⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 crt.c

📁 COCO類似C的編譯器
💻 C
📖 第 1 页 / 共 3 页
字号:
#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 + -