📄 parsell1.cpp
字号:
/****************************************************/
/* 文件 parseLL1.cpp */
/* 说明 类pascal编译器的语法分析器实现 */
/* 主题 编译器结构:原理和实例 */
/* 说明 采用LL1分析方法 */
/****************************************************/
/*********** 该文件所包含的头文件 ****************/
#include "globals.h" /* 该头文件定义了全局类与变量 */
#include "util.h" /* 该头文件定义了功能函数 */
#include "string.h"
#include "scanner.h" /* 该头文件定义了词法扫描器界面 */
#include "parseLL1.h" /* 该头文件定义了语法分析器界面 */
/*当前单词*/
TokenType currentToken;
/*当前单词行号,用于给出错误提示信息*/
extern int lineno;
/*LL1分析表*/
int LL1Table[TABLESIZE][TABLESIZE];
/*纪录当前语法树节点*/
TreeNode *currentP=NULL;
/*为保存类型需要的临时变量*/
DecKind *temp=NULL;
/*保存当前指针,以便修改后,将其恢复*/
TreeNode *saveP = NULL;
/*纪录表达式中,未匹配的左括号数目*/
int expflag = 0;
/*判断简单表达式处理结束,整个表达式是否处理结束标识*/
/*当是条件表达式时,取假值,简单表达式时,取真值*/
/*用于函数preocess84*/
int getExpResult = TRUE;
/*仅用于数组变量,故初始化为假,遇到数组变量时,将其
改变为真,以便在函数process84中,即算术表达式结束时,
从语法树栈中弹出相应指针,将数组下标表达式的结构链入
节点中*/
int getExpResult2 = FALSE;
/*符号栈顶指针*/
StackNode *StackTop;
/*栈空标志*/
int STACKEMPTY;
/*语法树栈顶指针*/
StackNodePA *StackTopPA;
/*栈空标志*/
int paSTACKEMPTY;
/*操作符栈的栈顶指针*/
StackNodeP *OpStackTop=NULL;
/*操作符栈空标志*/
int OpSTACKEMPTY = TRUE;
/*操作数栈的栈顶指针*/
StackNodeP *NumStackTop=NULL;
/*操作数栈空标志*/
int NumSTACKEMPTY = TRUE;
/************<语法分析功能函数> **************/
/********************************************************/
/* 函数名 CreatLL1Table */
/* 功 能 创建LL1分析表 */
/* 说 明 初始数组(表)中的每一项都为0;根据LL1文法 */
/* 给数组赋值(填表);填好后,若值为0, */
/* 表示无产生式可选,其他,为选中的产生式 */
/********************************************************/
void CreatLL1Table()
{ int i,j;
/*初始化LL1表元素*/
for (i=0;i<TABLESIZE;i++)
for (j=0;j<TABLESIZE;j++)
LL1Table[i][j]=0;
LL1Table [Program][PROGRAM] = 1;
LL1Table [ProgramHead][PROGRAM] = 2;
LL1Table [ProgramName][ID] = 3;
LL1Table [DeclarePart][TYPE]= 4;
LL1Table [DeclarePart][VAR]= 4;
LL1Table [DeclarePart][PROCEDURE]= 4;
LL1Table [DeclarePart][BEGIN]= 4;
LL1Table [TypeDec][VAR]= 5;
LL1Table [TypeDec][PROCEDURE]= 5;
LL1Table [TypeDec][BEGIN]= 5;
LL1Table [TypeDec][TYPE]= 6;
LL1Table [TypeDeclaration][TYPE]= 7;
LL1Table [TypeDecList][ID]= 8;
LL1Table [TypeDecMore][VAR]= 9;
LL1Table [TypeDecMore][PROCEDURE]= 9;
LL1Table [TypeDecMore][BEGIN]= 9;
LL1Table [TypeDecMore][ID]= 10;
LL1Table [TypeId][ID]= 11;
LL1Table [TypeName][INTEGER]= 12;
LL1Table [TypeName][CHAR]= 12;
LL1Table [TypeName][ARRAY]= 13;
LL1Table [TypeName][RECORD]= 13;
LL1Table [TypeName][ID]= 14;
LL1Table [BaseType][INTEGER]= 15;
LL1Table [BaseType][CHAR]= 16;
LL1Table [StructureType][ARRAY]= 17;
LL1Table [StructureType][RECORD]= 18;
LL1Table [ArrayType][ARRAY]= 19;
LL1Table [Low][INTC]= 20;
LL1Table [Top][INTC]= 21;
LL1Table [RecType][RECORD]= 22;
LL1Table [FieldDecList][INTEGER]= 23;
LL1Table [FieldDecList][CHAR]= 23;
LL1Table [FieldDecList][ARRAY]= 24;
LL1Table [FieldDecMore][END]= 25;
LL1Table [FieldDecMore][INTEGER]= 26;
LL1Table [FieldDecMore][CHAR]= 26;
LL1Table [FieldDecMore][ARRAY]= 26;
LL1Table [IdList][ID]= 27;
LL1Table [IdMore][SEMI]= 28;
LL1Table [IdMore][COMMA]= 29;
LL1Table [VarDec][PROCEDURE]= 30;
LL1Table [VarDec][BEGIN]= 30;
LL1Table [VarDec][VAR]= 31;
LL1Table [VarDeclaration][VAR]= 32;
LL1Table [VarDecList][INTEGER]= 33;
LL1Table [VarDecList][CHAR]= 33;
LL1Table [VarDecList][ARRAY]= 33;
LL1Table [VarDecList][RECORD]= 33;
LL1Table [VarDecList][ID]= 33;
LL1Table [VarDecMore][PROCEDURE]= 34;
LL1Table [VarDecMore][BEGIN]= 34;
LL1Table [VarDecMore][INTEGER]= 35;
LL1Table [VarDecMore][CHAR]= 35;
LL1Table [VarDecMore][ARRAY]= 35;
LL1Table [VarDecMore][RECORD]= 35;
LL1Table [VarDecMore][ID]= 35;
LL1Table [VarIdList][ID]= 36;
LL1Table [VarIdMore][SEMI]= 37;
LL1Table [VarIdMore][COMMA]= 38;
LL1Table [ProcDec][BEGIN]= 39;
LL1Table [ProcDec][PROCEDURE]= 40;
LL1Table [ProcDeclaration][PROCEDURE]= 41;
LL1Table [ProcDecMore][BEGIN]= 42;
LL1Table [ProcDecMore][PROCEDURE]= 43;
LL1Table [ProcName][ID]= 44;
LL1Table [ParamList][RPAREN]= 45;
LL1Table [ParamList][INTEGER]= 46;
LL1Table [ParamList][CHAR]= 46;
LL1Table [ParamList][ARRAY]= 46;
LL1Table [ParamList][RECORD]= 46;
LL1Table [ParamList][ID]= 46;
LL1Table [ParamList][VAR]= 46;
LL1Table [ParamDecList][INTEGER]= 47;
LL1Table [ParamDecList][CHAR]= 47;
LL1Table [ParamDecList][ARRAY]= 47;
LL1Table [ParamDecList][RECORD]= 47;
LL1Table [ParamDecList][ID]= 47;
LL1Table [ParamDecList][VAR]= 47;
LL1Table [ParamMore][RPAREN]= 48;
LL1Table [ParamMore][SEMI]= 49;
LL1Table [Param][INTEGER]= 50;
LL1Table [Param][CHAR]= 50;
LL1Table [Param][ARRAY]= 50;
LL1Table [Param][RECORD]= 50;
LL1Table [Param][ID]= 50;
LL1Table [Param][VAR]= 51;
LL1Table [FormList][ID]= 52;
LL1Table [FidMore][SEMI]= 53;
LL1Table [FidMore][RPAREN]= 53;
LL1Table [FidMore][COMMA]= 54;
LL1Table [ProcDecPart][TYPE]= 55;
LL1Table [ProcDecPart][VAR]= 55;
LL1Table [ProcDecPart][PROCEDURE]= 55;
LL1Table [ProcDecPart][BEGIN]= 55;
LL1Table [ProcBody][BEGIN]= 56;
LL1Table [ProgramBody][BEGIN]= 57;
LL1Table [StmList][ID]= 58;
LL1Table [StmList][IF]= 58;
LL1Table [StmList][WHILE]= 58;
LL1Table [StmList][RETURN]= 58;
LL1Table [StmList][READ]= 58;
LL1Table [StmList][WRITE]= 58;
LL1Table [StmMore][END]= 59;
LL1Table [StmMore][ENDWH]= 59;
LL1Table [StmMore][ELSE]= 59;
LL1Table [StmMore][FI]= 59;
LL1Table [StmMore][SEMI]= 60;
LL1Table [Stm][IF]= 61;
LL1Table [Stm][WHILE]= 62;
LL1Table [Stm][READ]= 63;
LL1Table [Stm][WRITE]= 64;
LL1Table [Stm][RETURN]= 65;
LL1Table [Stm][ID]= 66;
LL1Table [AssCall][ASSIGN]= 67;
LL1Table [AssCall][LMIDPAREN]= 67;
LL1Table [AssCall][DOT]= 67;
LL1Table [AssCall][LPAREN]= 68;
LL1Table [AssignmentRest][ASSIGN]= 69;
LL1Table [AssignmentRest][LMIDPAREN]= 69;
LL1Table [AssignmentRest][DOT]= 69;
LL1Table [ConditionalStm][IF]= 70;
LL1Table [LoopStm][WHILE]= 71;
LL1Table [InputStm][READ]= 72;
LL1Table [InVar][ID]= 73;
LL1Table [OutputStm][WRITE]= 74;
LL1Table [ReturnStm][RETURN]= 75;
LL1Table [CallStmRest][LPAREN]= 76;
LL1Table [ActParamList][RPAREN]= 77;
LL1Table [ActParamList][ID]= 78;
LL1Table [ActParamList][INTC]= 78;
LL1Table [ActParamList][LPAREN]= 78;
LL1Table [ActParamMore][RPAREN]= 79;
LL1Table [ActParamMore][COMMA]= 80;
LL1Table [RelExp][LPAREN]= 81;
LL1Table [RelExp][INTC]= 81;
LL1Table [RelExp][ID]= 81;
LL1Table [OtherRelE][LT]= 82;
LL1Table [OtherRelE][EQ]= 82;
LL1Table [Exp][LPAREN]= 83;
LL1Table [Exp][INTC]= 83;
LL1Table [Exp][ID]= 83;
LL1Table [OtherTerm][LT]= 84;
LL1Table [OtherTerm][EQ]= 84;
LL1Table [OtherTerm][THEN]= 84;
LL1Table [OtherTerm][DO]= 84;
LL1Table [OtherTerm][RPAREN]= 84;
LL1Table [OtherTerm][END]= 84;
LL1Table [OtherTerm][SEMI]= 84;
LL1Table [OtherTerm][COMMA]= 84;
LL1Table [OtherTerm][ENDWH]= 84;
LL1Table [OtherTerm][ELSE]= 84;
LL1Table [OtherTerm][FI]= 84;
LL1Table [OtherTerm][RMIDPAREN]= 84;
LL1Table [OtherTerm][PLUS]= 85;
LL1Table [OtherTerm][MINUS]= 85;
LL1Table [Term][LPAREN]= 86;
LL1Table [Term][INTC]= 86;
LL1Table [Term][ID]= 86;
LL1Table [OtherFactor][PLUS]= 87;
LL1Table [OtherFactor][MINUS]= 87;
LL1Table [OtherFactor][LT]= 87;
LL1Table [OtherFactor][EQ]= 87;
LL1Table [OtherFactor][THEN]= 87;
LL1Table [OtherFactor][ELSE]= 87;
LL1Table [OtherFactor][FI]= 87;
LL1Table [OtherFactor][DO]= 87;
LL1Table [OtherFactor][ENDWH]= 87;
LL1Table [OtherFactor][RPAREN]= 87;
LL1Table [OtherFactor][END]= 87;
LL1Table [OtherFactor][SEMI]= 87;
LL1Table [OtherFactor][COMMA]= 87;
LL1Table [OtherFactor][RMIDPAREN]= 87;
LL1Table [OtherFactor][TIMES]= 88;
LL1Table [OtherFactor][OVER]= 88;
LL1Table [Factor][LPAREN]= 89;
LL1Table [Factor][INTC]= 90;
LL1Table [Factor][ID]= 91;
LL1Table [Variable][ID]= 92;
LL1Table [VariMore][ASSIGN]= 93;
LL1Table [VariMore][TIMES]= 93;
LL1Table [VariMore][OVER]= 93;
LL1Table [VariMore][PLUS]= 93;
LL1Table [VariMore][MINUS]= 93;
LL1Table [VariMore][LT]= 93;
LL1Table [VariMore][EQ]= 93;
LL1Table [VariMore][THEN]= 93;
LL1Table [VariMore][ELSE]= 93;
LL1Table [VariMore][FI]= 93;
LL1Table [VariMore][DO]= 93;
LL1Table [VariMore][ENDWH]= 93;
LL1Table [VariMore][RPAREN]= 93;
LL1Table [VariMore][END]= 93;
LL1Table [VariMore][SEMI]= 93;
LL1Table [VariMore][COMMA]= 93;
LL1Table [VariMore][RMIDPAREN]= 93;
LL1Table [VariMore][LMIDPAREN]= 94;
LL1Table [VariMore][DOT]= 95;
LL1Table [FieldVar][ID]= 96;
LL1Table [FieldVarMore][ASSIGN]= 97;
LL1Table [FieldVarMore][TIMES]= 97;
LL1Table [FieldVarMore][OVER]= 97;
LL1Table [FieldVarMore][PLUS]= 97;
LL1Table [FieldVarMore][MINUS]= 97;
LL1Table [FieldVarMore][LT]= 97;
LL1Table [FieldVarMore][EQ]= 97;
LL1Table [FieldVarMore][THEN]= 97;
LL1Table [FieldVarMore][ELSE]= 97;
LL1Table [FieldVarMore][FI]= 97;
LL1Table [FieldVarMore][DO]= 97;
LL1Table [FieldVarMore][ENDWH]= 97;
LL1Table [FieldVarMore][RPAREN]= 97;
LL1Table [FieldVarMore][END]= 97;
LL1Table [FieldVarMore][SEMI]= 97;
LL1Table [FieldVarMore][COMMA]= 97;
LL1Table [FieldVarMore][LMIDPAREN]= 98;
LL1Table [CmpOp][LT]= 99;
LL1Table [CmpOp][EQ]= 100;
LL1Table [AddOp][PLUS]= 101;
LL1Table [AddOp][MINUS]= 102;
LL1Table [MultOp][TIMES]= 103;
LL1Table [MultOp][OVER]= 104;
}
/********************************************************************/
/* 函数名 gettoken */
/* 功 能 从Token序列中取出一个Token */
/* 说 明 从文件中存的Token序列中依次取一个单词,作为当前单词. */
/********************************************************************/
int fpnum=0;
void gettoken(TokenType *p)
{
FILE *fp2;
/*按只读方式打开文件*/
fp2=fopen("c:\\Tokenlist","rb");
if (fp==NULL)
{ printf("cannot create file Tokenlist!\n");
exit(0);
}
fseek(fp2,fpnum*sizeof(TokenType),0);
fread(p,sizeof(TokenType),1,fp2);
fpnum++;
fclose(fp2);
}
/********************************************************************/
/* 函数名 syntaxError */
/* 功 能 语法错误处理函数 */
/* 说 明 将函数参数message指定的错误信息格式化写入列表文件listing */
/* 设置错误追踪标志Error为TRUE */
/********************************************************************/
static void syntaxError(char * message)
{ fprintf(listing,"\n>>> ");
/* 将出错行号lineno和语法错误信息message格式化写入文件listing */
fprintf(listing,"Syntax error at line %d: %s",lineno,message);
/* 设置错误追踪标志Error为TRUE,防止错误进一步传递 */
Error = TRUE;
}
void process1()
{
Push(2, DOT);
Push(1, ProgramBody);
Push(1, DeclarePart);
Push(1, ProgramHead);
}
/********************************************************************/
/* 函数名 process2() */
/* 功 能 处理程序头,并生成程序头节点Phead. */
/* 说 明 产生式为:PROGRAM ProgramName */
/********************************************************************/
void process2()
{
Push(1,ProgramName);
Push(2,PROGRAM);
TreeNode **t=PopPA();
currentP=newPheadNode();
(*t)=currentP;
/*程序头节点没有兄弟节点,下面的声明用用根节点的child[1]指向*/
}
void process3()
{
Push(2,ID);
strcpy( currentP->name[0] ,currentToken.Sem);
currentP->idnum++;
}
void process4()
{
Push(1,ProcDec);
Push(1,VarDec);
Push(1,TypeDec);
}
void process5()
{
}
void process6()
{
Push(1,TypeDeclaration);
}
void process7()
{
Push(1,TypeDecList);
Push(2,TYPE);
TreeNode **t=PopPA();
currentP = newTypeNode(); /*生成Type作为标志的结点,它的子结点都是
类型声明*/
(*t) = currentP; /*头结点的兄弟结点指针指向此结点*/
PushPA(&((*currentP).sibling)); /* 压入指向变量声明节点的指针*/
PushPA(&((*currentP).child[0])); /*压入指向第一个类型声明节点的指针*/
}
void process8()
{
Push(1,TypeDecMore);
Push(2,SEMI);
Push(1,TypeName);
Push(2,EQ);
Push(1,TypeId);
TreeNode **t=PopPA();
currentP = newDecNode(); /*生成一个表示类型声明的结点,
不添任何信息*/
(*t) = currentP; /*若是第一个,则是Type类型的子结点指向当前结点,
否则,是上一个类型声明的兄弟结点*/
PushPA(&((*currentP).sibling));
}
void process9()
{
PopPA();
}
void process10()
{
Push(1,TypeDecList);
}
void process11()
{
Push(2,ID);
strcpy( (*currentP).name[0] ,currentToken.Sem);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -