📄 crt.c
字号:
#include <stdlib.h>
#include <stdarg.h>
#include <ctype.h>
#include <string.h>
#include "crt.h"
#include "cra.h"
#include "crf.h"
#include "collect.h"
#include "set.h"
#include "crs.h"
#define NODES_SIZE 100 /* Graph Node Table */
#define NODES_EXTEND 20
Collection nodes_tab;
#define TERM_SIZE 100 /* Terminal Table */
#define TERM_EXTEND 20
Collection term_tab;
#define NTERM_SIZE 100 /* Nonterminal Table */
#define NTERM_EXTEND 20
Collection nterm_tab;
#define CLASS_SIZE 20 /* Set Table */
#define CLASS_EXTEND 10
Collection class_tab;
#define SYMSET_SIZE 20 /* Symbol Sets Table */
#define SYMSET_EXTEND 10
Collection symset_tab;
#define PRAGMA_SIZE 5 /* Pragmas Tables */
#define PRAGMA_EXTEND 2
Collection pragma_tab;
#define NAME_SIZE 1 /* Names Tables */
#define NAME_EXTEND 1
Collection name_tab;
int dirty_DFA=0;
struct SemText global_defs; /* TRUE => Globals Definitions */
int first_weak_set = -1; /* First weak set index in symsettab */
int ignore_case = FALSE; /* TRUE => Ignore case */
FILE *lstfile;
int no_sym = 0;
Set ANY_SET; /* Set of all characters */
Set ALL_TERMS; /* Set of all Terminals */
static Set FollowVisited; /* Visited graph Nodes in Comp_Follow */
static Set FirstVisited; /* Visited graph Nodes in Comp_First */
static Set Set1;
static Set Set2;
static int CurrentNt;
int C_option = FALSE; /* TRUE => Generate Compiler */
int F_option = FALSE; /* TRUE => First & Follow */
int G_option = FALSE; /* TRUE => Graph listing */
int L_option = FALSE; /* TRUE => Generate listing */
int P_option = FALSE; /* TRUE => Generate Parser Only */
int Q_option = FALSE; /* TRUE => Q editor mode */
int S_option = FALSE; /* TRUE => Symbol Table Listing */
int T_option = FALSE; /* TRUE => Grammar Test Only */
int D_option = FALSE; /* TRUE => Debug #line */
int Z_option = FALSE; /* TRUE => Generate .hpp and .cpp files */
int A_option = FALSE; /* TRUE => Automata */
int O_option = FALSE; /* TRUE => Generate OR only Terminal Conditions */
int GenCplusplus = FALSE;
char Frames_Path[100] = "";
char c_ext[100] = "c";
char h_ext[100] = "h";
static void PrintTerm(int t);
static void PrintNTerm(int t);
extern int Errors;
typedef void (*Graph_Func) (int gp);
typedef void (*Graph_FuncInt) (int gp, int p);
typedef void (*Graph_FuncSet) (int gp, Set *s);
void upcase(char *s)
{
while (*s) {
if (*s >= 'a' && *s <= 'z') *s -= 32;
s++;
}
}
/*****************************************************************
*** Graph Construction Functions ***
******************************************************************/
/* Create a graph Node and initialize it */
static int MakeGraphNode(int type)
{
int gp;
PGraphNode gn;
gp = Collection_New(&nodes_tab);
gn = GetGraphP(gp);
gn->type = type;
gn->next = NIL;
gn->pointer1 = NIL;
gn->pointer2 = NIL;
gn->pointer3 = NIL;
gn->pointer4 = NIL;
return gp;
}
/* create a symbol node, Terminal and Nonterminal */
int MakeGraph(int type, int sp)
{
int gp;
PGraphNode gn;
gp = MakeGraphNode(type);
gn = GetGraphP(gp);
CR_ASSERT(gn != NULL);
gn->SLine = S_Line;
gn->SYMLINK = sp; /* set pointer to Table */
return gp;
}
/* */
void SetGraphLine(int current, int line)
{
PGraphNode gn;
gn = GetGraphP(current);
CR_ASSERT(gn != NULL);
gn->SLine = line;
}
/* create a semantic code node T_SEM , T_ATTR */
int MakeSemGraph(int type, long filepos, int len, int line, int col)
{
int gp;
PGraphNode gn;
gp = MakeGraphNode(type);
gn = GetGraphP(gp);
CR_ASSERT(gn != NULL);
gn->SEMPOS = filepos; /*kws*/
gn->SEMLEN = len;
gn->SEMLINE = line;
gn->SEMCOL = col;
return gp;
}
/* create an operator node with INNER => "link" */
int MakeGraphOp(int type, int link)
{
int gp;
PGraphNode gn;
gp = MakeGraphNode(type);
gn = GetGraphP(gp);
CR_ASSERT(gn != NULL);
gn->INNER = link;
return gp;
}
/* link two nodes */
int LinkGraph(int current, int next)
{
PGraphNode gn;
do {
gn = GetGraphP(current);
CR_ASSERT(gn != NULL);
current = gn->next;
} while (current!=NIL);
gn->next = next;
return next;
}
/* link two alt nodes */
int LinkAltGraph(int current, int nextalt)
{
PGraphNode gn;
gn = GetGraphP(current);
CR_ASSERT(gn != NULL);
gn->ALT = nextalt;
return nextalt;
}
/* prints a graph to the list file */
void ShowGraph(int gp)
{
PGraphNode gn;
while (gp > NIL) {
gn = GetGraphP(gp);
CR_ASSERT(gn != NULL);
fprintf(lstfile, "%d^", gp);
switch(gn->type) {
case T_T :
case T_WT:
{
PTermNode tn = GetTermP(gn->SYMLINK);
fprintf(lstfile, "%s", tn->name);
break;
}
case T_NT :
{
PNTermNode ntn = GetNTermP(gn->SYMLINK);
fprintf(lstfile, "%s", ntn->name);
break;
}
case T_OPT:
fprintf(lstfile, "[");
ShowGraph(gn->INNER);
fprintf(lstfile, "]");
break;
case T_REP:
fprintf(lstfile, "{");
ShowGraph(gn->INNER);
fprintf(lstfile, "}");
break;
case T_ALT:
{
PGraphNode gn1;
fprintf(lstfile, "(");
ShowGraph(gn->INNER);
gn1 = gn;
while (gn1->ALT) {
fprintf(lstfile, "|");
gn1 = GetGraphP(gn1->ALT);
CR_ASSERT(gn1 != NULL);
ShowGraph(gn1->INNER);
}
fprintf(lstfile, ")");
break;
}
case T_SEM:
fprintf(lstfile, "SEM");
break;
case T_ATTR:
fprintf(lstfile, "ATTR");
break;
case T_SYNC:
fprintf(lstfile, "SYNC");
break;
case T_ANY:
fprintf(lstfile, "ANY");
break;
}
gp = gn->next;
fprintf(lstfile, " ");
}
fprintf(lstfile, "%d^", gp);
}
/*****************************************************************
*** Pragmas management Functions ***
*****************************************************************/
/* compare a Pragma Name with "symbol" */
static int CompPragmaName(PPragmaNode tn, PName name)
{
return !strcmp(tn->name, name);
}
int FindPragma(PName name)
{
int tp;
tp = Collection_FirstThat(&pragma_tab,
(Collection_Comp) CompPragmaName, name);
return tp;
}
/* install a pragma */
int NewPragma(PName name)
{
int pp;
PPragmaNode pn;
pp = Collection_New(&pragma_tab);
pn = GetPragmaP(pp);
CR_ASSERT(pn != NULL);
strcpy(pn->name, name);
pn->has_attr = FALSE;
return pp;
}
void SetPragmaText(int sp, int gp)
{
PPragmaNode pn;
PGraphNode gn;
pn = GetPragmaP(sp);
CR_ASSERT(pn != NULL);
gn = GetGraphP(gp);
CR_ASSERT(gn != NULL);
pn->has_attr = TRUE;
pn->sem_text.pos = gn->SEMPOS;
pn->sem_text.len = gn->SEMLEN;
pn->sem_text.line = gn->SEMLINE;
pn->sem_text.col = gn->SEMCOL;
}
/* add Pragmas to Tokens before generating the Scanner
No_Sym & MAXT are marks to the last Token and Before first pragma */
void SetupPragmas(void)
{
PPragmaNode pn;
PTermNode tn;
int c, i, tp;
c = Collection_Count(&pragma_tab);
for (i = 0; i < c; i++) {
pn = GetPragmaP(i);
CR_ASSERT(pn != NULL);
tp = Collection_New(&term_tab);
tn = GetTermP(tp);
CR_ASSERT(tn != NULL);
tn->type = T_PRAGMATOKEN;
strcpy(tn->name, pn->name);
SetTermName(tn);
}
}
/*****************************************************************
*** Names management Functions ***
*****************************************************************/
/* compare a Name "Name" with "symbol" */
static int CompNameName(PNameNode tn, PName name)
{
return !strcmp(tn->name, name);
}
/* get table index of terminal "symbol" */
int FindName(PName name)
{
int tp;
tp = Collection_FirstThat(&name_tab,
(Collection_Comp) CompNameName, name);
return tp;
}
/* set the symbolic name of a terminal */
void NewName(PName name, PName user_name)
{
int np;
PNameNode nn;
np = Collection_New(&name_tab);
nn = GetNameP(np);
CR_ASSERT(nn != NULL);
strcpy(nn->name, name);
strcpy(nn->user_name, user_name);
}
/*****************************************************************
*** Terminal management Functions ***
*****************************************************************/
/* compare a terminal name with "symbol" */
static int CompTermName(PTermNode tn, PName name)
{
return !strcmp(tn->name, name);
}
/* get table index of terminal "symbol" */
int FindTerm(PName name)
{
int tp;
tp = Collection_FirstThat(&term_tab,
(Collection_Comp) CompTermName, name);
return tp;
}
void SetTermName(PTermNode tn)
{
char str[MAX_ID_LEN];
char temp[MAX_ID_LEN];
char name[MAX_ID_LEN + 100];
char *t;
strcpy(temp, tn->name);
name[0] = '\0';
t = temp;
if (*t == '"' || *t == '\'') {
t++;
t[strlen(t) - 1] = '\0';
}
if (strcmp(temp, "EOF") == 0) strcpy(name, "EOF_");
else if (strcmp(temp, "not") == 0) strcpy(name, "No_");
else while (*t) {
SymCharName(*t, str);
strcat(name, str);
t++;
}
/* ensure that the name is not longer that MAX_ID_LEN */
name[MAX_ID_LEN - 4] = '\0';
strcat(name, "Sym");
strcpy(tn->gen_name, name);
}
/* install a new terminal */
int NewTerm(PName name)
{
int tp;
PTermNode tn;
char TempName[MAX_STR_LEN];
strcpy(TempName, name);
TempName[MAX_ID_LEN - 1] = '\0';
tp = FindTerm(TempName);
if (tp != UNDEF) tn = (PTermNode) GetTermP(tp);
else {
tp = Collection_New(&term_tab);
tn = GetTermP(tp);
CR_ASSERT(tn != NULL);
strcpy(tn->name, TempName);
strcpy(tn->gen_name, "");
tn->type = T_CLASSTOKEN;
}
return tp;
}
/* return the symbolic name of a terminal */
void GetTermName(int tp, PName name)
{
PTermNode tn;
PNameNode nn;
int np;
tn = GetTermP(tp);
CR_ASSERT(tn != NULL);
if (tn->gen_name[0] == '\0') { /* no genname */
np = FindName(tn->name);
if (np == UNDEF) SetTermName(tn);
else {
nn = GetNameP(np);
strcpy(tn->gen_name, nn->user_name);
}
}
strcpy(name, tn->gen_name);
}
/* print each terminal data */
static void Func_ShowTerm(PTermNode tn, int tp)
{
CR_ASSERT(tn != NULL);
fprintf(lstfile, "%3d|%s\t=\t", tp, tn->name);
switch (tn->type) {
case T_CLASSTOKEN:
fprintf(lstfile, "Class Token");
break;
case T_CLASSLITTOKEN:
fprintf(lstfile, "Class Literal Token");
break;
case T_LITTOKEN:
fprintf(lstfile, "Literal Token");
break;
case T_PRAGMATOKEN:
fprintf(lstfile, "Pragma Token");
break;
}
fprintf(lstfile, "\n");
}
/* print terminal table to lstfile */
void ShowTermTab(void)
{
fprintf(lstfile, "\nTERMINALS\n");
Collection_ForEachPos(&term_tab, (Collection_FuncPos) Func_ShowTerm);
}
/*****************************************************************
*** Class management Functions ***
*****************************************************************/
/* find set by name */
static int CompClassName(PClassNode cn, PName name)
{
return !strcmp(cn->name, name);
}
int FindClass(PName name)
{
int cp;
cp = Collection_FirstThat(&class_tab,
(Collection_Comp) CompClassName, name);
return cp;
}
/* find set by contents */
static int CompClassData(PClassNode cn, Set *data)
{
CR_ASSERT(cn != NULL);
return Set_Equal(&(cn->data), data);
}
int FindClassWithSet(PSet data)
{
int cp;
cp = Collection_FirstThat(&class_tab,
(Collection_Comp) CompClassData, data);
return cp;
}
/* install a set to the set table */
int NewClass(PName name, PSet set)
{
int cp;
PClassNode cn;
cp = Collection_New(&class_tab);
cn = GetClassP(cp);
CR_ASSERT(cn != NULL);
strcpy(cn->name, name);
Set_Init(&cn->data);
Set_Union(&cn->data, set);
return cp;
}
int GetClassWithName(PName name, PSet set)
{
int cp;
PClassNode cn;
Set_Clean(set);
if ((cp = FindClass(name)) == UNDEF) return UNDEF;
cn = GetClassP(cp);
CR_ASSERT(cn != NULL);
Set_Union(set, &cn->data);
return cp;
}
/* print each set info */
static void Func_ShowClass(PClassNode cn, int cp)
{
CR_ASSERT(cn != NULL);
if (!cp) return;
fprintf(lstfile, "%3d|%s\t=\t", cp, cn->name);
Set_ForEach(&cn->data, (Set_Func) PrintAscii);
fprintf(lstfile, "\n");
}
/* print set table */
void ShowClassTab(void)
{
fprintf(lstfile, "\nClass\n");
Collection_ForEachPos(&class_tab,
(Collection_FuncPos) Func_ShowClass);
}
/*****************************************************************
*** Symbol Sets management Functions ***
*****************************************************************/
/* install a symbol set */
int NewSymSet(PSet set, byte typ)
{
PSymSetNode sn;
int sp;
sp = Collection_New(&symset_tab);
sn = GetSymSetP(sp);
CR_ASSERT(sn != NULL);
sn->type = typ;
Set_Init(&sn->set);
Set_Union(&sn->set, set);
if (typ == T_WT && first_weak_set == -1) first_weak_set = sp;
return sp;
}
/* install an ANY Terminals set */
int NewANY(void)
{
return NewSymSet(&ALL_TERMS, T_ANY);
}
/* get symset data by index */
void GetSymSet(int sp, PSet set)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -