1. 程式人生 > >算術表示式的語法分析及語義分析程式設計 —— LR分析法、輸出三元式(續)

算術表示式的語法分析及語義分析程式設計 —— LR分析法、輸出三元式(續)

#include<iostream>
#include<string>
#include<vector>
#include<cmath>
#define MAX 40
using namespace std;

typedef struct code{
    string data;
    int num;
}Code;
Code code[MAX];

struct Gene{//產生式
    string left;
    char* right;
};
vector<Gene> gene;

typedef struct action{
    char
para; int val; }Action; Action action[][MAX]={ {{'O',0},{'O',0},{'O',0},{'O',0},{'S',3},{'O',0}, {'O',0},{'O',0},{'O',0}}, {{'O',0},{'O',0},{'O',0},{'O',0},{'O',0},{'O',0},{'O',0},{'O',0},{'A', 0}}, {{'O',0},{'O',0},{'O',0},{'O',0},{'O',0},{'O',0},{'O',0},{'S', 4},{'O',0}}, {{'O',0},{'O',0},{'O',0},{'O',0},{'O'
,0},{'O',0},{'O',0},{'R', 10},{'O',0}}, {{'O',0},{'O',0},{'O',0},{'O',0},{'S',8},{'S',9},{'O',0},{'O',0},{'O',0}}, {{'S',10},{'S',11},{'O',0},{'O',0},{'O',0},{'O',0},{'O',0},{'O',0},{'R',1}}, {{'R', 4},{'R', 4},{'S', 12},{'S', 13},{'O',0},{'O',0},{'R',4},{'O',0},{'R', 4}}, {{'R', 7},{'R', 7},{'R', 7},{'R'
, 7},{'O',0},{'O',0},{'R',7},{'O',0},{'R', 7}}, {{'R', 8},{'R', 8},{'R', 8},{'R', 8},{'O',0},{'O',0},{'R',8},{'O',0},{'R', 8}}, {{'O',0},{'O',0},{'O',0},{'O',0},{'S', 8},{'S', 9},{'O', 0},{'O',0},{'O',0}}, {{'O',0},{'O',0},{'O',0},{'O',0},{'S', 8},{'S', 9},{'O', 0},{'O',0},{'O',0}}, {{'O',0},{'O',0},{'O',0},{'O',0},{'S', 8},{'S', 9},{'O', 0},{'O',0},{'O',0}}, {{'O',0},{'O',0},{'O',0},{'O',0},{'S', 8},{'S', 9},{'O', 0},{'O',0},{'O',0}}, {{'O',0},{'O',0},{'O',0},{'O',0},{'S', 8},{'S', 9},{'O', 0},{'O',0},{'O',0}}, {{'S',10},{'S',11},{'O',0},{'O',0},{'O',0},{'O',0},{'S',19},{'O',0},{'O',0}}, {{'R',2},{'R',2},{'S',12},{'S',13},{'O',0},{'O',0},{'R',2},{'O', 0},{'R',2}}, {{'R',3},{'R',3},{'S',12},{'S',13},{'O',0},{'O',0},{'R',3},{'O', 0},{'R',3}}, {{'R',5},{'R',5},{'R',5},{'R',5},{'O',0},{'O',0},{'R',5},{'O', 0},{'R',5}}, {{'R',6},{'R',6},{'R',6},{'R',6},{'O',0},{'O',0},{'R',6},{'O', 0},{'R',6}}, {{'R',9},{'R',9},{'R',9},{'R',9},{'O',0},{'O',0},{'R',9},{'O', 0},{'R',9}}, }; //轉移表goto int Goto[MAX][MAX]; int num;//詞法分析得到的單詞個數 string str;//輸入串 char *key[10]={"main","void","int","char","printf","scanf","else","if","return"}; char Word[20],ch; string Vn="AETFV";//非終結符 int Seq;//三元式序號 string Equ[MAX][3];//儲存三元式 int IsAlpha(char c) { if(((c<='z')&&(c>='a'))||((c<='Z')&&(c>='A'))) return 1; else return 0; } int IsNumber(char c) { if(c>='0'&&c<='9') return 1; else return 0; } int IsKey(char *word) { int m,i; for(i=0;i<9;i++) { if((m=strcmp(word,key[i]))==0) { if(i==0) return 2; return 1; } } return 0; } char* scanner(char *fp,int ii) { char Word[20]={'\0'}; char ch; int i,c,sign=9; ch=*fp; if(IsAlpha(ch)) { Word[0]=ch; fp++; ch=*fp; i=1; while(IsNumber(ch)||IsAlpha(ch)) { Word[i]=ch; i++; fp++; ch=*fp; } Word[i]='\0'; c=IsKey(Word); if(c==0) { sign=4; printf("%s\t普通識別符號\t%d\n",Word,sign); } else if(c==2) printf("%s\t主函式 \t%d\n",Word,sign); else printf("%s\t關鍵字 \t%d\n",Word,sign); } else if(IsNumber(ch)) { Word[0]=ch; fp++; ch=*fp; i=1; while(IsNumber(ch)) { Word[i]=ch; i++; fp++; ch=*fp; } Word[i]='\0'; sign=4; printf("%s\t無符號實數\t%d\n",Word,sign); } else { Word[0]=ch; switch(ch) { case '[': case '(': case '{': fp++; sign=5; printf("%s\t界符 \t%d\n",Word,sign); break; case ',': case '"': case ';': fp++; printf("%s\t界符 \t%d\n",Word,sign); break; case ']': case ')': case '}': fp++; sign=6; printf("%s\t界符 \t%d\n",Word,sign); break; case '+': fp++; ch=*fp; if(ch=='=') { Word[1]=ch; fp++; printf("%s\t運算子 \t%d\n",Word,sign); } else if(ch=='+') { Word[1]=ch; fp++; printf("%s\t運算子 \t%d\n",Word,sign); } else { sign=0; printf("%s\t運算子 \t%d\n",Word,sign); } break; case '-': fp++; ch=*fp; if(ch=='=') { Word[1]=ch; fp++; printf("%s\t運算子 \t%d\n",Word,sign); } else if(ch=='-') { Word[1]=ch; fp++; printf("%s\t運算子 \t%d\n",Word,sign); } else { sign=1; printf("%s\t運算子 \t%d\n",Word,sign); } break; case '*': fp++; ch=*fp; if(ch=='=') { Word[1]=ch; fp++; printf("%s\t運算子 \t%d\n",Word,sign); } else { sign=2; printf("%s\t運算子 \t%d\n",Word,sign); } break; case '/': fp++; ch=*fp; if(ch=='=') { Word[1]=ch; fp++; printf("%s\t運算子 \t%d\n",Word,sign); } else { sign=3; printf("%s\t運算子 \t%d\n",Word,sign); } break; case '!': case '=': fp++; ch=*fp; if(ch=='=') { Word[1]=ch; fp++; printf("%s\t運算子 \t%d\n",Word,sign); } else { sign=7; printf("%s\t運算子 \t%d\n",Word,sign); } break; case '<': fp++; ch=*fp; if(ch=='=') { Word[1]=ch; fp++; printf("%s\t運算子 \t%d\n",Word,sign); } else if(ch=='<') { Word[1]=ch; fp++; printf("%s\t運算子 \t%d\n",Word,sign); } else { printf("%s\t運算子 \t%d\n",Word,sign); } break; case '>': fp++; ch=*fp; if(ch=='=') { Word[1]=ch; fp++; printf("%s\t運算子 \t%d\n",Word,sign); } else if(ch=='>') { Word[1]=ch; fp++; printf("%s\t運算子 \t%d\n",Word,sign); } else { printf("%s\t運算子 \t%d\n",Word,sign); } break; case '%': fp++; ch=*fp; if(ch=='=') { Word[1]=ch; fp++; printf("%s\t運算子 \t%d\n",Word,sign); } if(IsAlpha(ch)) { Word[1]=ch; fp++; printf("%s\t型別識別符號\t%d\n",Word,sign); } else { printf("%s\t取餘運算子\t%d\n",Word,sign); } break; case '\\': fp++; ch=*fp; Word[1]=ch; fp++; printf("%s\t製表符 \t%d\n",Word,sign); break; default: printf("無法識別字符\n"); break; } } code[ii].data=Word; code[ii].num=sign; return fp; } int Cifafenxi() { int i=-1;//種別碼 printf("請輸入表示式(以‘#’號結束):\n"); cin>>str; cout<<"詞法分析:\n"; char *fp=&str[0]; do{ i++; if(*fp=='#') break; else if(*fp==' ') {} else { fp=scanner(fp,i); } }while(*fp!='#'); return i; } void GetWenfa() { Gene gen; gen.left='S'; gen.right="A"; gene.push_back (gen); gen.left ='A'; gen.right ="V=E"; gene.push_back (gen); gen.left ='E'; gen.right ="E+T"; gene.push_back (gen); gen.right ="E-T"; gene.push_back (gen); gen.right ="T"; gene.push_back (gen); gen.left ='T'; gen.right ="T*F"; gene.push_back (gen); gen.right ="T/F"; gene.push_back (gen); gen.right ="F"; gene.push_back (gen); gen.left ='F'; gen.right ="i"; gene.push_back (gen); gen.right ="(E)"; gene.push_back (gen); gen.left ='V'; gen.right ="i"; gene.push_back (gen); } void Init() { Goto[13][1]=9; Goto[13][3]=18; Goto[12][1]=9; Goto[12][3]=17; Goto[11][1]=9; Goto[11][2]=16;Goto[11][3]=7; Goto[10][1]=9; Goto[10][2]=15; Goto[10][3]=7; Goto[9][1]=14; Goto[9][2]=6; Goto[9][3]=7; Goto[4][1]=5; Goto[4][2]=6; Goto[4][3]=7; Goto[0][0]=1; Goto[0][4]=2;; } void error() { cout<<"ERROR!"<<endl; cout<<"\n動作不存在!"<<endl; exit(-1); } void Output(vector<string> str) { int len=str.size(); for(int i=0;i<len;i++) cout<<str[i]; cout<<" \t"; } void Yufafenxi(int num) { Init(); GetWenfa(); vector<int> state;//狀態棧 vector<string> ana;//分析棧 vector<string> an;//輸入棧 state.push_back (0); ana.push_back ("#"); int i,j; int k=0; do{ for(int a=0;a<state.size();a++)//輸出狀態棧 cout<<state[a]; cout<<"\t\t"; Output(ana);//輸出分析棧 for(a=k;a<=num;a++)//輸出剩餘輸入棧 cout<<code[a].data; cout<<"\t"; i=state[state.size()-1]; j=code[k].num ; if(j==9) error(); cout<<"\t"<<action[i][j].para<<action[i][j].val<<"\t"; //輸出動作 if(action[i][j].para=='O') error(); else if(action[i][j].para=='S')//移進 { cout<<"移進"<<"\n"; state.push_back (action[i][j].val); ana.push_back (code[k].data); an.push_back (code[k].data); k++; } else if(action[i][j].para=='R')//規約 { cout<<"規約"<<"\t"; int len; int tem=action[i][j].val; len=strlen(gene[tem].right); while(len!=0)//將分析棧中的待約項規約 { state.pop_back (); ana.pop_back (); len--; } cout<<gene[action[i][j].val].left<<"->"<<gene[action[i][j].val].right<<endl;//輸出規約所用的產生式 if(action[i][j].val==1||action[i][j].val==2||action[i][j].val==3||action[i][j].val==5||action[i][j].val==6||action[i][j].val==9)//輸出三元式 { int t=an.size()-1; if(action[i][j].val!=9) { Seq++; Equ[Seq][0]=an[t-1]; Equ[Seq][1]=an[t-2]; Equ[Seq][2]=an[t]; } an.pop_back (); an.pop_back (); an.pop_back (); char c=Seq+'1'-1; string str="("; str=str+c; str=str+")"; an.push_back (str); } ana.push_back (gene[action[i][j].val].left); int a=state[state.size()-1]; string b=ana[ana.size()-1]; int dex=0; while(Vn[dex]!=b[0]) dex++; if(Goto[a][dex]==0) error(); else state.push_back (Goto[a][dex]); } else if(action[i][j].para=='A') { cout<<"\n分析成功!\n"; break; } }while(1); int n=1; cout<<"\n三元式:\n"; while(n<=Seq) { cout<<"\n"<<n<<"\t"; cout<<"("<<Equ[n][0]<<",\t"<<Equ[n][1]<<",\t"<<Equ[n][2]<<")"<<endl; n++; } } int main(void) { num=Cifafenxi(); cout<<"詞法分析結束"<<"\n"; system("pause"); code[num+1].data="#"; code[num+1].num =8; num++; int i; cout<<"語法分析:\n"; cout<<"狀態棧 "<<"\t"<<"分析棧"<<"\t\t"<<"剩餘輸入棧"<<"\t"<<" 動作 "<<"\t產生式"<<"\n"; Yufafenxi(num); cout<<"語法分析結束\n"; return 0; }