?? 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 + -