?? parsell1.cpp
字號:
/****************************************************/
/* 文件 parseLL1.cpp */
/* 說明 類pascal編譯器的語法分析器實現(xiàn) */
/* 主題 編譯器結(jié)構(gòu):原理和實例 */
/* 說明 采用LL1分析方法 */
/****************************************************/
/************ 該文件所包含的頭文件 ****************/
#include "globals.h" /* 該頭文件定義了全局類與變量 */
#include "util.h" /* 該頭文件定義了功能函數(shù) */
#include "string.h"
#include "scanner.h" /* 該頭文件定義了詞法掃描器界面 */
#include "parseLL1.h" /* 該頭文件定義了語法分析器界面 */
/*當(dāng)前單詞*/
TokenType currentToken;
/*當(dāng)前單詞行號,用于給出錯誤提示信息*/
extern int lineno;
/*LL1分析表*/
int LL1Table[TABLESIZE][TABLESIZE];
/*紀(jì)錄當(dāng)前語法樹節(jié)點*/
TreeNode *currentP=NULL;
/*為保存類型需要的臨時變量*/
DecKind *temp=NULL;
/*保存當(dāng)前指針,以便修改后,將其恢復(fù)*/
TreeNode *saveP = NULL;
/*紀(jì)錄表達(dá)式中,未匹配的左括號數(shù)目*/
int expflag = 0;
/*判斷簡單表達(dá)式處理結(jié)束,整個表達(dá)式是否處理結(jié)束標(biāo)識*/
/*當(dāng)是條件表達(dá)式時,取假值,簡單表達(dá)式時,取真值*/
/*用于函數(shù)preocess84*/
int getExpResult = TRUE;
/*僅用于數(shù)組變量,故初始化為假,遇到數(shù)組變量時,將其
改變?yōu)檎妫员阍诤瘮?shù)process84中,即算術(shù)表達(dá)式結(jié)束時,
從語法樹棧中彈出相應(yīng)指針,將數(shù)組下標(biāo)表達(dá)式的結(jié)構(gòu)鏈入
節(jié)點中*/
int getExpResult2 = FALSE;
/*符號棧頂指針*/
StackNode *StackTop;
/*棧空標(biāo)志*/
int STACKEMPTY;
/*語法樹棧頂指針*/
StackNodePA *StackTopPA;
/*棧空標(biāo)志*/
int paSTACKEMPTY;
/*操作符棧的棧頂指針*/
StackNodeP *OpStackTop=NULL;
/*操作符棧空標(biāo)志*/
int OpSTACKEMPTY = TRUE;
/*操作數(shù)棧的棧頂指針*/
StackNodeP *NumStackTop=NULL;
/*操作數(shù)棧空標(biāo)志*/
int NumSTACKEMPTY = TRUE;
/************<語法分析功能函數(shù)> **************/
/********************************************************/
/* 函數(shù)名 CreatLL1Table */
/* 功 能 創(chuàng)建LL1分析表 */
/* 說 明 初始數(shù)組(表)中的每一項都為0;根據(jù)LL1文法 */
/* 給數(shù)組賦值(填表);填好后,若值為0, */
/* 表示無產(chǎn)生式可選,其他,為選中的產(chǎn)生式 */
/********************************************************/
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;
}
/********************************************************************/
/* 函數(shù)名 gettoken */
/* 功 能 從Token序列中取出一個Token */
/* 說 明 從文件中存的Token序列中依次取一個單詞,作為當(dāng)前單詞. */
/********************************************************************/
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);
}
/********************************************************************/
/* 函數(shù)名 syntaxError */
/* 功 能 語法錯誤處理函數(shù) */
/* 說 明 將函數(shù)參數(shù)message指定的錯誤信息格式化寫入列表文件listing */
/* 設(shè)置錯誤追蹤標(biāo)志Error為TRUE */
/********************************************************************/
static void syntaxError(char * message)
{ fprintf(listing,"\n>>> ");
/* 將出錯行號lineno和語法錯誤信息message格式化寫入文件listing */
fprintf(listing,"Syntax error at line %d: %s",lineno,message);
/* 設(shè)置錯誤追蹤標(biāo)志Error為TRUE,防止錯誤進一步傳遞 */
Error = TRUE;
}
void process1()
{
Push(2, DOT);
Push(1, ProgramBody);
Push(1, DeclarePart);
Push(1, ProgramHead);
}
/********************************************************************/
/* 函數(shù)名 process2() */
/* 功 能 處理程序頭,并生成程序頭節(jié)點Phead. */
/* 說 明 產(chǎn)生式為:PROGRAM ProgramName */
/********************************************************************/
void process2()
{
Push(1,ProgramName);
Push(2,PROGRAM);
TreeNode **t=PopPA();
currentP=newPheadNode();
(*t)=currentP;
/*程序頭節(jié)點沒有兄弟節(jié)點,下面的聲明用用根節(jié)點的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作為標(biāo)志的結(jié)點,它的子結(jié)點都是
類型聲明*/
(*t) = currentP; /*頭結(jié)點的兄弟結(jié)點指針指向此結(jié)點*/
PushPA(&((*currentP).sibling)); /* 壓入指向變量聲明節(jié)點的指針*/
PushPA(&((*currentP).child[0])); /*壓入指向第一個類型聲明節(jié)點的指針*/
}
void process8()
{
Push(1,TypeDecMore);
Push(2,SEMI);
Push(1,TypeName);
Push(2,EQ);
Push(1,TypeId);
TreeNode **t=PopPA();
currentP = newDecNode(); /*生成一個表示類型聲明的結(jié)點,
不添任何信息*/
(*t) = currentP; /*若是第一個,則是Type類型的子結(jié)點指向當(dāng)前結(jié)點,
否則,是上一個類型聲明的兄弟結(jié)點*/
PushPA(&((*currentP).sibling));
}
void process9()
{
PopPA();
}
void process10()
{
Push(1,TypeDecList);
}
void process11()
{
Push(2,ID);
strcpy( (*currentP).name[0] ,currentToken.Sem);
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -