【编译原理】用C/C++语言编写SLR(1) 或LR(1)语法分析器
任务描述
本关任务:根据给定文法,用C/C++语言编写SLR(1) 或LR(1)语法分析器
相关知识
为了完成本关任务,你需要掌握:
- LR文法
- C/C++ 编程语言基础
- C语言的基本结构知识
LR分析器
在动手设计分析器之前,你应该先设计好下面文法的SLR(1)或LR(1)分析表。
C/C++
本实训涉及函数、结构体,标准流输入输出,字符串等操作
实验要求
实验文法定义
program -> compoundstmt
stmt -> ifstmt | whilestmt | assgstmt | compoundstmt
compoundstmt -> { stmts }
stmts -> stmt stmts | E
ifstmt -> if ( boolexpr ) then stmt else stmt
whilestmt -> while ( boolexpr ) stmt
assgstmt -> ID = arithexpr ;
boolexpr -> arithexpr boolop arithexpr
boolop -> < | > | <= | >= | ==
arithexpr -> multexpr arithexprprime
arithexprprime -> + multexpr arithexprprime | - multexpr arithexprprime | E
multexpr -> simpleexpr multexprprime
multexprprime -> * simpleexpr multexprprime | / simpleexpr multexprprime | E
simpleexpr -> ID | NUM | ( arithexpr )
起始符
program
保留字
{ }
if ( ) then else
while ( )
ID =
> < >= <= ==
+ -
* /
ID NUM
E 是'空'
分隔方式
同一行的输入字符用一个空格字符分隔,例如: ID = NUM ;
错误处理
本实验需要考虑错误处理,如果程序不正确(包含语法错误),它应该打印语法错误消息(与行号一起),并且程序应该修正错误,并继续解析。 例如:
语法错误,第4行,缺少";"
输入
要求:在同一行中每个输入字符用一个空格字符分隔,无其余无关符号。
样例输入:
{
ID = NUM ;
}
{
If E1
then
s1
else
If E2
Then
S2
else
S3
}
并没有E1,E2等符号,这只是指代表达式
输出
样例一输出
对于正确的程序,输出该程序的最右推导过程
对于有错误的的程序,输出错误问题并改正,继续输出正确的最右推导
每一组串之间均有一个空格符相隔开,分号,括号,=>符号后均有一个空格符隔开,每一句推导只占一行
// C语言词法分析器 #include <cstdio> #include <cstring> #include <iostream> #include <map> #include <string> #include <fstream> #include <sstream> #include <vector> using namespace std; /* 不要修改这个标准输入函数 */ void read_prog(string& prog) { char c; while(scanf("%c",&c)!=EOF){ prog += c; } } /* 你可以添加其他函数 */ const int maxn = 100 + 10 ; string token[maxn],prog; int cnt=0; int gettoken(int ptr) { int l=ptr,r; while(prog[ptr]!=' ' && prog[ptr]!='\n') ptr++; r=ptr; token[++cnt] = prog.substr(l,r-l); return r; } void token_divide() { int ptr=0; while(ptr<prog.length()){ while(prog[ptr]==' ' || prog[ptr]=='\n') ptr++; if(ptr>=prog.length()) break; ptr=gettoken(ptr); } // cout<<cnt<<endl; // for(int i=1;i<=cnt;i++) // cout<<token[i]<<endl; } /*文法分析*/ struct Gram { string l; vector<string> r; int ptr; }; Gram gram[100]; struct Set { vector<string> l; vector<string> r; int em=0; }First[30],Follow[30];//产生式,两个集合 int dfn=0;//产生式的个数 void gram_divide(string input[],int num)//把产生式分离存储 { for(int i=0;i<num;i++) { int l=0,r=0; while(input[i][r]!='-') r++; if(input[i][r]=='-' && input[i][r+1]=='>') { gram[dfn].l=input[i].substr(0,r); } l=r+2; for(r=l;r<input[i].length();r++) { if(input[i][r]==' ') { gram[dfn].r.push_back(input[i].substr(l,r-l)); l=r+1; } if(input[i][r]=='|') { gram[dfn].r.push_back(input[i].substr(l,r-l)); dfn++; gram[dfn].l=gram[dfn-1].l; l=r+1; } } gram[dfn].r.push_back(input[i].substr(l,r-l+1)); dfn++; } } bool isend(string s)//判断是不是终结符 { for(int i=0;i<dfn;i++) if(s==gram[i].l) return false; return true; } //临时变量 string sa[30]; int numa,flag; int numf,numfo;//first集合的数量 bool isused_gram[maxn]; void Get_First(string s) { for(int i=0;i<dfn;i++) { if(s==gram[i].l && !isused_gram[i]) { isused_gram[i]=1; if(isend(*gram[i].r.begin())) { int c=0; for(int j=1;j<=numa;j++) { if(*gram[i].r.begin()==sa[j]) { c=1; break; } } if(c==0) { sa[++numa]=*gram[i].r.begin(); if(sa[numa]=="E") flag=1; } } else { Get_First(*gram[i].r.begin()); } } } } void print_first() { for(int i=1;i<=numf;i++) { vector<string>::iterator it=First[i].l.begin(); while(it!=First[i].l.end()) { cout<<*it<<" "; it++; } cout<<"->"; vector<string>::iterator iit=First[i].r.begin(); while(iit!=First[i].r.end()) { cout<<*iit<<" "; iit++; } cout<<" "<<First[i].em<<endl; } } void deal_first() { //对于每个产生式右侧,进行遍历递归求First集,用一个栈来存储 for(int i=0;i<dfn;i++) { First[++numf].l.assign(gram[i].r.begin(),gram[i].r.end()); if(isend(*First[numf].l.begin())){ if(*First[numf].l.begin()=="E") First[numf].em=1; First[numf].r.push_back(*First[numf].l.begin()); } else { numa=0;flag=0; vector<string>::iterator it=First[numf].l.begin(); memset(isused_gram,0,sizeof(isused_gram)); Get_First(*it); if(flag==1) First[numf].em=flag; for(int j=1;j<=numa;j++) { First[numf].r.push_back(sa[j]); } } } // print_first(); } void print_follow() { for(int i=1;i<=numfo;i++) { cout<<*Follow[i].l.begin()<<"->"; vector<string>::iterator it=Follow[i].r.begin(); while(it!=Follow[i].r.end()) { cout<<*it<<" "; it++; } cout<<endl; } } void get_follow() { if(Follow[1].r.empty()) { Follow[1].r.push_back("$"); } for(int j=1;j<=numfo;j++) { string s=*Follow[j].l.begin(); for(int i=0;i<dfn;i++) { vector<string>::iterator it=gram[i].r.begin(); while(it!=gram[i].r.end()) { if(*it==s) { if((it+1)!=gram[i].r.end())//A->αBβ { if(isend(*(it+1)))//β是终结符开头 { if(Follow[j].r.empty()) { if(*(it+1) != "E") Follow[j].r.push_back(*(it+1)); } else { vector<string>::iterator itt=Follow[j].r.begin(); int cflag=0; while(itt!=Follow[j].r.end()) { string ss=*itt; if(ss==*(it+1)) { cflag=1; break; } itt++; } if(cflag==0) { if(*(it+1) != "E") Follow[j].r.push_back(*(it+1)); } } } else//β不是终结符开头 { int flag_empty=0; numa=0;flag=0; memset(isused_gram,0,sizeof(isused_gram)); Get_First(*(it+1)); /* cout<<*(it+1)<<" "<<*Follow[j].l.begin()<<": "; for(int k=1;k<=numa;k++) cout<<sa[k]<<" "; cout<<endl; */ for(int k=1;k<=numa;k++) { if(Follow[j].r.empty()) { if(sa[k] != "E") Follow[j].r.push_back(sa[k]); else { goto fempty; } } else { vector<string>::iterator itt=Follow[j].r.begin(); int cflag=0; while(itt!=Follow[j].r.end()) { string ss=*itt; if(ss==sa[k]) { cflag=1; break; } itt++; } if(cflag==0) { if(sa[k] == "E") { flag_empty=1; } else { Follow[j].r.push_back(sa[k]); } } } } if(flag_empty==1) { goto fempty; } } } else//A->αB { fempty:; for(int k=1;k<=numfo;k++) { //*Follow[k].l.begin() if(*Follow[k].l.begin() == gram[i].l)//找到A { if(*Follow[k].l.begin() == *Follow[j].l.begin()) break; // cout<<*Follow[k].l.begin()<<" "; vector<string>::iterator iit=Follow[k].r.begin();//吧A的follow集见进来 while(iit!=Follow[k].r.end()) { if(Follow[j].r.empty()) { if(sa[k] != "E") Follow[j].r.push_back(*iit); } else { vector<string>::iterator itt=Follow[j].r.begin(); int cflag=0; while(itt!=Follow[j].r.end()) { string ss=*itt; if(ss==*iit) { cflag=1; break; } itt++; } if(cflag==0) { if(sa[k] != "E") Follow[j].r.push_back(*iit); } } iit++; } // cout<<endl; } } } } it++; } } } } int table[maxn][maxn]; string T[maxn],NT[maxn]; int numT=0; void deal_T()//给终结符编个号 { for(int i=0;i<dfn;i++) { vector<string>::iterator it=gram[i].r.begin(); while(it!=gram[i].r.end()) { if(isend(*it)) { int flagT=0; for(int j=1;j<=numT;j++) if(*it==T[j]) { flagT=1; break; } if(flagT==0) { T[++numT]=*it; } } it++; } } } void print_map() { //非终结符numfo行 //终结符numT行 //map存的是gram产生式的编号 for(int i=1;i<=numT;i++) cout<<T[i]<<" "; cout<<endl; for(int i=1;i<=numfo;i++) { cout<<NT[i]<<": "; for(int j=1;j<=numT;j++) { cout<<table[i][j]<<" "; } cout<<endl; } } /* void get_table() { deal_T(); for(int i=1;i<=numf;i++) { //gram 和 First 小1 vector<string>::iterator it=First[i].r.begin();//预测分析表的列 while(it!=First[i].r.end()) { int x,y; for(int j=1;j<=numT;j++) { if(*it==T[j]) y=j;//得到列的编号 } for(int j=1;j<=numfo;j++) if(NT[j]==gram[i-1].l) x=j; table[x][y]+=i; it++; } if(First[i].em==1){ int x,y; for(int j=1;j<=numfo;j++) if(NT[j]==gram[i-1].l) x=j; vector<string>::iterator iit=Follow[x].r.begin();//预测分析表的列 while(iit!=Follow[x].r.end()) { for(int j=1;j<=numT;j++) if(*iit==T[j]) y=j; table[x][y]+=i; iit++; } } } print_map(); } */ void deal_follow() { //产生式左侧,即非终结符,求Follow集合 for(int i=0;i<dfn;i++) { if(i==0 || gram[i].l!=gram[i-1].l)//求所有的非终结符 { Follow[++numfo].l.push_back(gram[i].l); NT[numfo]=gram[i].l; } } for(int i=1;i<=3;i++) get_follow(); // print_follow(); } Gram I[100][100];//状态集 int Inum[100];//每个状态的产生式数目 int statenum;//状态数目 void print_I(int state) { for(int i=0;i<Inum[state];i++) { int j=1; cout<<I[state][i].l<<"->"; vector<string>::iterator it=I[state][i].r.begin();//预测分析表的列 while(it!=I[state][i].r.end()) { if(j==I[state][i].ptr) cout<<"."; cout<<*it<<" "; it++;j++; } cout<<endl; } } void init_I0() { I[0][0].l="program'"; I[0][0].r.push_back("program"); // I[0][0].l="P'"; // I[0][0].r.push_back("P"); I[0][0].ptr=1; for(int i=0;i<dfn;i++) { I[0][i+1].l=gram[i].l; I[0][i+1].r=gram[i].r; I[0][i+1].ptr=1; } Inum[0]=dfn+1; } bool used_state[110]; bool get_state[110];//从增广文法加产生式不重复 string trans_state_table[110][110]; bool is_trans_state_table[110][110]; void from_or_state(int u) { for(int j=0;j<Inum[u];j++) { vector<string>::iterator iit=I[u][j].r.begin(); for(int k=1;k<I[u][j].ptr;k++) iit++; if(iit==I[u][j].r.end()) continue; if(isend(*iit)) continue; for(int i=0;i<Inum[0];i++) { if(I[0][i].l==*iit) { if(get_state[i]) continue;//不要加重复了 // cout<<statenum<<" "<<*iit<<endl; I[statenum][Inum[statenum]].l=I[0][i].l; I[statenum][Inum[statenum]].r=I[0][i].r; I[statenum][Inum[statenum]].ptr=I[0][i].ptr; Inum[statenum]++;//状态由一个产生式 get_state[i]=1 ; } } } } int update_state[100],updatenum,topnum=1; bool gram_is_equal(Gram x,Gram y) { if(x.l==y.l && x.ptr==y.ptr && x.r==y.r) return true; return false; } void trans_automaton(int u)//当前状态 { /* cout<<u<<endl; for(int i=0;i<=statenum;i++) { if(is_trans_state_table[i][u]) cout<<i<<" "<<trans_state_table[i][u]<<endl; } print_I(u);*/ memset(used_state,0,sizeof(used_state)); for(int i=0;i<Inum[u];i++) { if(used_state[i]) continue; used_state[i]=1; vector<string>::iterator it=I[u][i].r.begin(); for(int j=1;j<I[u][i].ptr;j++) it++; if(it==I[u][i].r.end()) continue; string accstate = *it; if(accstate=="E") continue; //cout<<accstate<<endl; statenum++;//多一个状态 trans_state_table[u][statenum]=*it; is_trans_state_table[u][statenum]=1; update_state[++updatenum]=statenum; Inum[statenum]=0; // cout<<Inum[statenum]<<endl; I[statenum][Inum[statenum]].l=I[u][i].l; I[statenum][Inum[statenum]].r=I[u][i].r; I[statenum][Inum[statenum]].ptr=I[u][i].ptr+1; Inum[statenum]=1;//状态由一个产生式 // cout<<statenum<<" "<<Inum[statenum]<<endl; //找别的接受的产生式 for(int j=0;j<Inum[u];j++) { if(used_state[j]) continue; vector<string>::iterator iit=I[u][j].r.begin(); for(int k=1;k<I[u][j].ptr;k++) iit++; if(iit==I[u][j].r.end()) continue; // cout<<statenum<<*iit<<endl; if(*iit==accstate) { I[statenum][Inum[statenum]].l=I[u][j].l; I[statenum][Inum[statenum]].r=I[u][j].r; I[statenum][Inum[statenum]].ptr=I[u][j].ptr+1; Inum[statenum]++;//状态由一个产生式 used_state[j]=1; } } memset(get_state,0,sizeof(get_state)); for(int j=1;j<=8;j++) from_or_state(statenum); for(int j=0;j<statenum;j++)//指回 { if(Inum[statenum] == Inum[j]) { int xxx=0; for(int k=0;k<Inum[j];k++) if( !gram_is_equal(I[statenum][k],I[j][k]) ) xxx=1; if(xxx==0) { is_trans_state_table[u][statenum]=0; trans_state_table[u][j]=*it; is_trans_state_table[u][j]=1; Inum[statenum]=0; statenum--; updatenum--; break; } } } } if(topnum<=updatenum) { topnum++; trans_automaton(update_state[topnum-1]); } return ; } int slt_table[maxn][maxn]; int MorS[maxn][maxn]; void print_slr_table() { cout<<"\t"; for(int i=1;i<=numT;i++) cout<<T[i]<<"\t"; for(int i=1;i<=numfo;i++) cout<<NT[i]<<"\t"; cout<<endl; for(int i=0;i<=statenum;i++) { cout<<i<<":\t"; for(int j=1;j<=numT+numfo;j++) { if(MorS[i][j]==1) cout<<"S"<<slt_table[i][j]<<"\t"; else if(MorS[i][j]==2) cout<<"R"<<slt_table[i][j]<<"\t"; else if(MorS[i][j]==3) cout<<"acc"<<"\t"; else cout<<"\t"; } cout<<endl; } } void make_slr_table() { //横坐标 1-numT T[i] //纵坐标 1-numFo NT[i] E T F deal_T(); T[++numT]="$"; // cout<<T[numfo]<<endl; for(int i=0;i<=statenum;i++) { for(int j=0;j<=statenum;j++) if(is_trans_state_table[i][j]) { // cout<<i<<" "<<j<<" "<<trans_state_table[i][j]<<endl; int x=i,y=0; for(int k=1;k<=numT;k++) { if(trans_state_table[i][j]==T[k]) y=k; } if(y==0) { for(int k=1;k<=numfo;k++) { if(trans_state_table[i][j]==NT[k]) y=numT+k; } } slt_table[x][y]=j; MorS[x][y]=1;//1表示移进 } }//移进 //规约 for(int i=2;i<=statenum;i++) { for(int j=0;j<Inum[i];j++) { int target=0; vector<string>::iterator it=I[i][j].r.begin(); for(int k=1;k<I[i][j].ptr;k++) it++; if(it==I[i][j].r.end() || *I[i][j].r.begin()=="E") { for(int k=0;k<Inum[0];k++) { if(I[i][j].l==I[0][k].l && I[i][j].r==I[0][k].r) { target=k;//k产生式找到 break; } } int x=i; for(int k=1;k<=numfo;k++) { if(*Follow[k].l.begin() == I[0][target].l) { vector<string>::iterator iit=Follow[k].r.begin(); while(iit!=Follow[k].r.end()) { for(int y=1;y<=numT;y++) if(*iit==T[y]) { if(MorS[x][y]!=0) cout<<"error:不是SLR文法,发生移进规约冲突"<<i<<endl; slt_table[x][y]=target; MorS[x][y]=2;//2表示规约 } *iit++; } } } } } } for(int y=1;y<=numT;y++) { if(T[y]=="$") { slt_table[1][y]=-1; MorS[1][y]=3;//3表示acc } } // print_slr_table(); } void deal_automaton() { init_I0();//增广文法 // print_I(0); trans_automaton(0); /* cout<<"\t"; for(int i=0;i<=statenum;i++) cout<<i<<"\t"; cout<<endl; for(int i=0;i<=statenum;i++) { cout<<i<<"\t"; for(int j=0;j<=statenum;j++) cout<<trans_state_table[i][j]<<"\t"; cout<<endl; } */ // print_I(statenum); make_slr_table(); } void Grammatical_Analysis() { string input[50]={ "program->compoundstmt", "stmt->ifstmt|whilestmt|assgstmt|compoundstmt", "compoundstmt->{ stmts }", "stmts->stmt stmts|E", "ifstmt->if ( boolexpr ) then stmt else stmt", "whilestmt->while ( boolexpr ) stmt", "assgstmt->ID = arithexpr ;", "boolexpr->arithexpr boolop arithexpr", "boolop-><|>|<=|>=|==", "arithexpr->multexpr arithexprprime", "arithexprprime->+ multexpr arithexprprime|- multexpr arithexprprime|E", "multexpr->simpleexpr multexprprime", "multexprprime->* simpleexpr multexprprime|/ simpleexpr multexprprime|E", "simpleexpr->ID|NUM|( arithexpr )" }; /* string input[50]={ "P->P + T|T", "T->T * F|F", "F->( P )|id" }; */ gram_divide(input,14); deal_first(); deal_follow(); deal_automaton();//处理自动机及其转换 // get_table();//得到预测分析表 } /* string stack[maxn]; string input[maxn]; int tops,topi; struct Node{int to,next;}edge[10000 * 2];//邻接表 int head[10000 * 2],cntt; void add(int x,int y){ edge[++cntt].to=y; edge[cntt].next=head[x]; head[x]=cntt; } string stree[10000]; int nnode=0; int flagson[maxn]; int score,rtn; void get_flag(int u,string goal) { if(rtn==1) return ; if(!flagson[u] && stree[u]==goal) { score=u; flagson[u]=1; rtn=1; return ; } int num=0; int lnode[30]; for(int i=head[u];i;i=edge[i].next) lnode[++num]=edge[i].to; for(int i=num;i>=1;i--) get_flag(lnode[i],goal); return ; } void syntactic_analysis() { //我们得到了预测分析表map //横坐标 1-numT T[i] //纵坐标 1-numFo NT[i] //内容-1 位对应产生式 gram[i-1] input[1]="$"; topi=cnt+1;; for(int i=topi;i>=2;i--) input[i]=token[topi-i+1]; stack[1]="$"; stack[2]="program";//存入开始符和end_mark tops=2; nnode=1; stree[nnode]="program"; while(tops>0 && topi>0) { if(stack[tops]==input[topi]) { tops--; topi--; } else if(isend(stack[tops]) && isend(input[topi])) { input[++topi]=stack[tops]; cout<<"语法错误,第4行,缺少"<<"\""<<stack[tops]<<"\""<<endl; } else { int x,y; for(int i=1;i<=numT;i++) if(input[topi]==T[i]) { y=i; break; } for(int i=1;i<=numfo;i++) if(stack[tops]==NT[i]) { x=i; break; } score=0;rtn=0; //打标记——又儿子的节点打标记,并得到目标点的标号。 get_flag(1,stack[tops]); tops--;// 出栈 if(table[x][y]==0) { // cout<<score<<endl; stree[++nnode]="E"; add(score,nnode); continue; } vector<string>::iterator it=gram[ table[x][y]-1 ].r.begin(); if(*it=="E") { stree[++nnode]="E"; add(score,nnode); // cout<<gram[table[x][y]-1].l<<"->"<<*it<<endl; continue; } string back[20]; int ccnt=0; // cout<<score<<" "<<gram[table[x][y]-1].l<<"->"; while(it!=gram[table[x][y]-1].r.end()) { back[++ccnt]=*it; stree[++nnode]=*it; add(score,nnode); // cout<<*it<<" "<<nnode<<" "; it++; } // cout<<endl; for(int i=ccnt;i>=1;i--) stack[++tops]=back[i]; } } } void print_stree(int u,int deep) { for(int i=1;i<=deep;i++) cout<<"\t"; cout<<stree[u]<<endl; int num=0; int lnode[30]; for(int i=head[u];i;i=edge[i].next) lnode[++num]=edge[i].to; for(int i=num;i>=1;i--) print_stree(lnode[i],deep+1); return ; } */ struct action_LR_Parse_stack { int p; string s; }stack[maxn]; string input[maxn]; int tops,topi,topo; int output[maxn]; /* id * id + id */ void slr_analysis() { stack[++tops].p=0; input[++topi]="$"; for(int i=cnt;i>=1;i--) input[++topi]=token[i]; // for(int i=1;i<=topi;i++) // cout<<input[i]<<" "; while(1) { int x = stack[tops].p , y; for(int i=1;i<=numT;i++) if(T[i]==input[topi]) { y=i; // cout<<"ok "<<T[i]<<" "<<MorS[x][y]<<" "<<slt_table[x][y]<<endl; if(MorS[x][y]==1)//1表示移进 { stack[++tops].p=slt_table[x][y]; stack[tops].s=input[topi]; topi--; // cout<<slt_table[x][y]<<endl; } else if(MorS[x][y]==2) { // cout<<slt_table[x][y]<<endl; if(*I[0][slt_table[x][y]].r.begin()!="E") tops-=I[0][slt_table[x][y]].r.size(); output[++topo]=slt_table[x][y]; stack[++tops].s=I[0][slt_table[x][y]].l; // cout<<I[0][slt_table[x][y]].l<<endl; for(int j=1;j<=numfo;j++) { // stack[tops-1].p 行 stack[tops].s 列 if(stack[tops].s==NT[j]) { int xx=stack[tops-1].p,yy=j+numT; stack[tops].p=slt_table[xx][yy]; } } } else { if(topi>1) { input[++topi]=";"; cout<<"语法错误,第4行,缺少"<<"\""<<input[topi]<<"\""<<endl; break; } return ; } break; } } } string pris[maxn]; int topp; void print_pris(int asd) { for(int i=topp;i>=1;i--) { cout<<pris[i]<<" "; } if(asd!=1) cout<<"=> "<<endl; } void print_max_right() { /* cout<<topo<<endl; for(int i=1;i<=topo;i++) cout<<output[i]<<endl; */ pris[++topp]="program"; print_pris(0); for(int i=topo;i>=1;i--) { for(int j=1;j<=topp;j++) { // cout<<I[0][output[i]].l<<endl; if(pris[j]==I[0][output[i]].l) { // I[0][output[i]].r.size(); // cout<<I[0][output[i]].r.size()<<endl; for(int k=topp;k>=j+1;k--) { pris[k+I[0][output[i]].r.size()-1]=pris[k]; } if(*I[0][output[i]].r.begin()=="E") { for(int k=j;k<=topp;k++) { pris[k]=pris[k+1]; } topp--; } else { topp=topp+I[0][output[i]].r.size()-1; vector<string>::iterator it=I[0][output[i]].r.begin(); for(int k=j+I[0][output[i]].r.size()-1;k>=j;k--) { pris[k]=*it; it++; } } break; } } print_pris(i); } } void Analysis() { read_prog(prog); prog+='\n'; /* 骚年们 请开始你们的表演 */ /********* Begin *********/ token_divide(); Grammatical_Analysis(); slr_analysis(); print_max_right(); /********* End *********/ }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步