整個詞法分析器有一張預測分析表,一個先進後出的分析棧和一個總控程序組成。主控程序控制整個分析的過程,分析過程當中從用戶輸入的程序源碼中利用詞法分析器從程序源碼緩衝區中取出字符(知足語法規則的單詞),而後根據分析棧中的內容,經過查找預測分析表,根據經過的返回結果執行不一樣的操做,出現錯誤則直接返回報錯,不然知道將整個源碼程序分析完爲止。算法
(1).文法轉換:函數
<表達式> ::=<項>{+<項>|-<項>}this
<項> ::= <因子>{*<因子>|/<因子>}spa
<因子> ::=ID|num|(<表達式>)設計
改成:指針
S->ABcode
A->CDci
B->+AB|-AB |ε字符串
C->ID|num|(S)terminal
D->*CD| /CD |ε
構造預測分析表:
|
ID |
num |
( |
) |
+ |
- |
* |
/ |
# |
S |
S->AB |
S->AB |
S->AB |
|
|
|
|
|
|
A |
A->CD |
A->CD |
A->CD |
|
|
|
|
|
|
B |
|
|
|
B->ε |
B->+AB |
B->-AB |
|
|
B->ε |
C |
C->ID |
C->num |
C->(S) |
|
|
|
|
|
|
D |
|
|
|
D->ε |
D->ε |
D->ε |
D->*CD |
D->/CD |
D->ε |
(2)分析棧爲S,從源碼緩衝區讀出的字符存放變量a
下面是僞碼:
push(S,’#‘); //‘#’爲結束符 push(S,’S’); //‘S‘爲文法開始符號 X=pop(S) //X存放從分析棧pop出的字符 while(true) { if(X∈Vt) { if(X=a) { a= scanner(codeBuffer); //將下一個字符讀入a } else { error(); } } else { if(X=’#’) { if(X=a) { break; //結束 } else { error(); } } else { if(search(M[X,a])) { push(YnYn-1...Y2Y1);//若是找到規則X->Y1Y2…Yn,右側逆序入棧,空不入 } else { error(); } } } }
下面是主控程序的流程框圖:
int AnalysisStack[ANALYSIS_STACK_LEN]; //分析堆棧 int stackTop; //堆棧頂部指針 charbufferToken[TOKEN_LENGTH]; //從緩衝區中取出的字符串 int stackToken;// 從分析堆棧取出的字符 bool startGrammarAnalysis(constchar codeBuffer[]); //開始語法分析 Morphology morphology; //詞法分析器,實現詞法分析功能 bool isTerminalCh(int Xcode,intteminalChTable[]);//判斷是否爲終結字符 bool serachPreMatrix(int Xcode,int Avalue,int &stackTop); //查表函數 void pushStack(intAnalysisStack[],int &stackTop,int object);
輸入:以#號結束所給文法的源程序字符串
輸出:success或者error
例如:輸入:x+1
輸出:success(語法正確)
輸入:x=1
輸出:error(語法錯誤)
樣例1:a++1.27e+18#
樣例2:--20+-124. e+137.246e+#
樣例3:/* this test program*/
x
+
1-36*x#
7. 程序源碼
/* *功能:語法分析器 *做者:KDF5000 *時間:2013.10 */ #include "grtammarAnalysis.h" #include <stdio.h> #include <string.h> #include "Complier.h" int teminalChTable[] = {IDENTIFIER,DIGIT,PLUS,SUB,STAR,SLASH,KUOHAO_L,KUOHAO_R}; grammarAnalysis::grammarAnalysis(void) { } grammarAnalysis::~grammarAnalysis(void) { } bool grammarAnalysis::startGrammarAnalysis(const char codeBuffer[]) { int returnCode; //每次識別字符串的code int startPosition = 0; //每次讀出字符的起始位置 morphology.setPreIsOp(true);//初始化操做符信號 double num = 0; //記錄scanner掃描到數字的數值 //////////////////////////////////////////////////////// do{ returnCode = morphology.scaner(codeBuffer,startPosition,bufferToken); if(returnCode == DIGIT) { Complier::strToNumber(bufferToken,num); printf("(%d,%g)\n",returnCode,num); } else if(returnCode == ERROR) { printf("('%s')不能有該文法生成!\n",bufferToken); } else if(returnCode==NOTE) { // } else { printf("(%d,'%s')\n",returnCode,bufferToken); } }while(returnCode!=END_JINGHAO); //////////////////////////////////////// startPosition=0; returnCode=0; stackTop = 0; //指向棧頂 morphology.setPreIsOp(true); AnalysisStack[stackTop++] = END_JINGHAO; // AnalysisStack[stackTop] = S_NTERMINAL;//S做爲文法的其實字符 returnCode = morphology.scaner(codeBuffer,startPosition,bufferToken); while(returnCode==NOTE) { returnCode = morphology.scaner(codeBuffer,startPosition,bufferToken); } //語法分析 while(true) { //將棧頂字符取出 stackToken = AnalysisStack[stackTop--]; //若是stackToken是非終結符(x屬於Vt) if(isTerminalCh(stackToken,teminalChTable)) { //X=a if(stackToken != returnCode) { return false; } else { do { returnCode = morphology.scaner(codeBuffer,startPosition,bufferToken); }while(returnCode==NOTE); } } else { //X = '$' if(stackToken == END_JINGHAO) { if(stackToken == returnCode ) { return true; } else { return false; } } // X!=‘$' else { if(!serachPreMatrix(stackToken,returnCode,stackTop)) { return false; } } } } } //判斷是否爲終結符 bool grammarAnalysis::isTerminalCh(int Xcode,int terminalT[]) { for(int i=0;i<sizeof(teminalChTable)/sizeof(teminalChTable[0]);i++) { if(Xcode==teminalChTable[i]) { return true; } } return false; } /* | ID | num | ( | ) | + | - | * | / | # S |S->AB |S->AB |S->AB | | | | | | A |A->CD |A->CD |A->CD | | | | | | B | | | |B->ε |B->+AB |B->-AB | | | B->ε C |C->ID |C->num |C->(S) | | | | | | D | | | |D->ε |D->ε |D->ε |D->*CD |D->/CD| D->ε _____________________________________________________________________________*/ //查找預測矩陣 bool grammarAnalysis::serachPreMatrix(int Xcode ,int Avalue,int &stackTop) { switch(Xcode) { case S_NTERMINAL: switch(Avalue) { case IDENTIFIER: case DIGIT: case KUOHAO_L: pushStack(AnalysisStack,stackTop,B_NTERMINAL); pushStack(AnalysisStack,stackTop,A_NTERMINAL); return true; default: return false; } break; case A_NTERMINAL: switch(Avalue) { case IDENTIFIER: case DIGIT: case KUOHAO_L: pushStack(AnalysisStack,stackTop,D_NTERMINAL); pushStack(AnalysisStack,stackTop,C_NTERMINAL); return true; default: return false; } break; case B_NTERMINAL: switch(Avalue) { case PLUS: pushStack(AnalysisStack,stackTop,B_NTERMINAL); pushStack(AnalysisStack,stackTop,A_NTERMINAL); pushStack(AnalysisStack,stackTop,PLUS); return true; case SUB: pushStack(AnalysisStack,stackTop,B_NTERMINAL); pushStack(AnalysisStack,stackTop,A_NTERMINAL); pushStack(AnalysisStack,stackTop,SUB); return true; case KUOHAO_R: case END_JINGHAO: return true; default: return false; } break; case C_NTERMINAL: switch(Avalue) { case IDENTIFIER: pushStack(AnalysisStack,stackTop,IDENTIFIER); return true; case DIGIT: pushStack(AnalysisStack,stackTop,DIGIT); return true; case KUOHAO_L: pushStack(AnalysisStack,stackTop,KUOHAO_R); pushStack(AnalysisStack,stackTop,S_NTERMINAL); pushStack(AnalysisStack,stackTop,KUOHAO_L); return true; default: return false; } break; case D_NTERMINAL: switch(Avalue) { case PLUS: case SUB: case KUOHAO_R: case END_JINGHAO: return true; case STAR: pushStack(AnalysisStack,stackTop,D_NTERMINAL); pushStack(AnalysisStack,stackTop,C_NTERMINAL); pushStack(AnalysisStack,stackTop,STAR); return true; case SLASH: pushStack(AnalysisStack,stackTop,D_NTERMINAL); pushStack(AnalysisStack,stackTop,C_NTERMINAL); pushStack(AnalysisStack,stackTop,SLASH); return true; default: return false; } break; default: return false; } } // void grammarAnalysis::pushStack(int AnalysisStack[],int &stackTop,int object) { //缺乏判斷堆棧是否已滿 AnalysisStack[++stackTop]= object; }