C++ LR(1)加减乘除

E->E+T

E->E-T

E->T

T->T*F

T->T/F

T->id                                一共30个状态,且代码写得个人感觉很罗嗦!

#include<iostream>
#include<string.h>
#include<stdio.h>
#include<stack>
using namespace std;
char s[100];                          //词法流
int length=0;                         //词法流长度
stack<char> S;                        //栈
char t1;                             //指向词法流的指针
int p1,p2;
int bb[30][3];                       //goto表
char ch;                           //指针
int temp1,temp2;
int flag=0;
int nn=0;  
int TEMP=0;
struct C{                               //存储action表内每个单元信息
 char c1;                             //移近、规约,错误标志
 int c2;                              //数字
 char *st;                           //返回一些有用的信息
};
C cc[30][8];                           //action表
int zhong(char t)                    //将终结符数字化
{
 if(t=='i') return 0;
 if(t=='+') return 1;
 if(t=='-') return 2;
 if(t=='*') return 3;
 if(t=='/') return 4;
 if(t=='(') return 5;
 if(t==')') return 6;
 if(t=='$') return 7;
}
struct Chan{
 int num;           //产生式右侧个数
 char *you;
 char zuo;
};
Chan MM[8];
void ChuShiHua()
{
 for(p1=0;p1<30;p1++)
 {
  for(p2=0;p2<8;p2++)
  {
   cc[p1][p2].st="error";
  }
 }
 for(p1=0;p1<30;p1++)
  for(p2=0;p2<3;p2++)
   bb[p1][p2]=0;
 cc[0][0].c1=cc[0][5].c1=cc[1][1].c1=cc[1][2].c1=cc[2][3].c1=cc[2][4].c1='s';
 cc[4][0].c1=cc[4][5].c1=cc[6][0].c1=cc[6][5].c1=cc[7][0].c1=cc[7][5].c1='s';
 cc[8][0].c1=cc[8][5].c1=cc[9][0].c1=cc[9][5].c1=cc[10][1].c1=cc[10][2].c1=cc[10][6].c1='s';
 cc[11][3].c1=cc[11][4].c1=cc[13][0].c1=cc[13][5].c1=cc[15][3].c1=cc[15][4].c1=cc[16][3].c1=cc[16][4].c1='s';
 cc[20][0].c1=cc[20][5].c1=cc[21][0].c1=cc[21][5].c1=cc[22][0].c1=cc[22][5].c1=cc[23][0].c1=cc[23][5].c1='s';
 cc[24][1].c1=cc[24][2].c1=cc[24][6].c1=cc[25][3].c1=cc[25][4].c1=cc[26][3].c1=cc[26][4].c1='s';
 //以上是移进标志!
 cc[0][0].c2=cc[6][0].c2=cc[7][0].c2=cc[8][0].c2=cc[9][0].c2=5;                    //移近5号状态
 cc[0][5].c2=cc[6][5].c2=cc[7][5].c2=cc[8][5].c2=cc[9][5].c2=4;                    //移近4号状态
 cc[1][1].c2=6;                                                                    //移近6号状态
 cc[1][2].c2=7;                                                                    //移近7号状态
 cc[2][3].c2=cc[15][3].c2=cc[16][3].c2=8;                                          //移近8号状态
 cc[2][4].c2=cc[15][4].c2=cc[16][4].c2=9;                                          //移近9号状态
 cc[4][0].c2=cc[13][0].c2=cc[20][0].c2=cc[21][0].c2=cc[22][0].c2=cc[23][0].c2=14;  //移近14号状态
 cc[4][5].c2=cc[13][5].c2=cc[20][5].c2=cc[21][5].c2=cc[22][5].c2=cc[23][5].c2=13;  //移近13号状态
 cc[10][1].c2=cc[24][1].c2=20;                                                     //移近20号状态
 cc[10][2].c2=cc[24][2].c2=21;                                                     //移近21号状态
 cc[10][6].c2=19;                                                                  //移近19号状态
 cc[11][3].c2=cc[25][3].c2=cc[26][3].c2=22;                                        //移近22号状态
 cc[11][4].c2=cc[25][4].c2=cc[26][4].c2=23;                                        //移近23号状态
 cc[24][6].c2=29;                                                                  //移近29号状态
 cc[2][1].c1=cc[2][2].c1=cc[2][7].c1='r';
 cc[2][1].c2=cc[2][2].c2=cc[2][7].c2=3;
 cc[3][1].c1=cc[3][2].c1=cc[3][3].c1=cc[3][4].c1=cc[3][7].c1='r';
 cc[3][1].c2=cc[3][2].c2=cc[3][3].c2=cc[3][4].c2=cc[3][7].c2=6;
 cc[5][1].c1=cc[5][2].c1=cc[5][3].c1=cc[5][4].c1=cc[5][7].c1='r';
 cc[5][1].c2=cc[5][2].c2=cc[5][3].c2=cc[5][4].c2=cc[5][7].c2=8;
 cc[11][1].c1=cc[11][2].c1=cc[11][6].c1='r';
 cc[11][1].c2=cc[11][2].c2=cc[11][6].c2=3;
 cc[12][1].c1=cc[12][2].c1=cc[12][3].c1=cc[12][4].c1=cc[12][6].c1='r';
 cc[12][1].c2=cc[12][2].c2=cc[12][3].c2=cc[12][4].c2=cc[12][6].c2=6;
 cc[14][1].c1=cc[14][2].c1=cc[14][3].c1=cc[14][4].c1=cc[14][6].c1='r';
 cc[14][1].c2=cc[14][2].c2=cc[14][3].c2=cc[14][4].c2=cc[14][6].c2=8;
 cc[15][1].c1=cc[15][2].c1=cc[15][7].c1='r';
 cc[15][1].c2=cc[15][2].c2=cc[15][7].c2=1;
 cc[16][1].c1=cc[16][2].c1=cc[16][7].c1='r';
 cc[16][1].c2=cc[16][2].c2=cc[16][7].c2=2;
 cc[17][1].c1=cc[17][2].c1=cc[17][3].c1=cc[17][4].c1=cc[17][7].c1='r';
 cc[17][1].c2=cc[17][2].c2=cc[17][3].c2=cc[17][4].c2=cc[17][7].c2=4;
 cc[18][1].c1=cc[18][2].c1=cc[18][3].c1=cc[18][4].c1=cc[18][7].c1='r';
 cc[18][1].c2=cc[18][2].c2=cc[18][3].c2=cc[18][4].c2=cc[18][7].c2=5;
 cc[19][1].c1=cc[19][2].c1=cc[19][3].c1=cc[19][4].c1=cc[19][7].c1='r';
 cc[19][1].c2=cc[19][2].c2=cc[19][3].c2=cc[19][4].c2=cc[19][7].c2=7;
 cc[25][1].c1=cc[25][2].c1=cc[25][6].c1='r';
 cc[25][1].c2=cc[25][2].c2=cc[25][6].c2=1;
 cc[26][1].c1=cc[26][2].c1=cc[26][6].c1='r';
 cc[26][1].c2=cc[26][2].c2=cc[26][6].c2=2;
 cc[27][1].c1=cc[27][2].c1=cc[27][3].c1=cc[27][4].c1=cc[27][6].c1='r';
 cc[27][1].c2=cc[27][2].c2=cc[27][3].c2=cc[27][4].c2=cc[27][6].c2=4;
 cc[28][1].c1=cc[28][2].c1=cc[28][3].c1=cc[28][4].c1=cc[28][6].c1='r';
 cc[28][1].c2=cc[28][2].c2=cc[28][3].c2=cc[28][4].c2=cc[28][6].c2=5;
 cc[29][1].c1=cc[29][2].c1=cc[29][3].c1=cc[29][4].c1=cc[29][6].c1='r';
 cc[29][1].c2=cc[29][2].c2=cc[29][3].c2=cc[29][4].c2=cc[29][6].c2=7;
 cc[1][7].c1='o';
 //以上规约完成
 bb[0][0]=1;bb[0][1]=2;bb[0][2]=3;bb[4][0]=10;bb[4][1]=11;bb[4][2]=12;
 bb[6][1]=15;bb[6][2]=3;bb[7][1]=16;bb[7][2]=3;bb[8][2]=17;bb[9][2]=18;
 bb[13][0]=24;bb[13][1]=11;bb[13][2]=12;bb[20][1]=25;bb[20][2]=12;
 bb[21][1]=26;bb[21][2]=12;bb[22][2]=27;bb[23][2]=28;
 //以上goto
 MM[0].num=3;MM[1].num=3;MM[2].num=1;MM[3].num=3;MM[4].num=3;MM[5].num=1;MM[6].num=3;MM[7].num=1;
 MM[0].you="E->E+T";MM[0].zuo='E';
 MM[1].you="E->E-T";MM[1].zuo='E';
 MM[2].you="E->T";MM[2].zuo='E';
 MM[3].you="T->T*F";MM[3].zuo='T';
 MM[4].you="T->T/F";MM[4].zuo='T';
 MM[5].you="T->F";MM[5].zuo='T';
 MM[6].you="F->(E)";MM[6].zuo='F';
 MM[7].you="F->id";MM[7].zuo='F';
 for(p1=0;p1<30;p1++)
 {
  for(p2=0;p2<8;p2++)
  {
   if(cc[p1][p2].c1=='r')
    cc[p1][p2].st="归约";
   if(cc[p1][p2].c1=='s')
    cc[p1][p2].st="移近";
  }
 }
}
void CuoWu()
{
 cc[0][1].c1=cc[0][2].c1=cc[0][3].c1=cc[0][4].c1=cc[0][7].c1=cc[6][1].c1=cc[6][2].c1=cc[6][3].c1=cc[6][4].c1=cc[7][1].c1=cc[7][2].c1=cc[7][3].c1=cc[7][4].c1='a';
 cc[8][1].c1=cc[8][2].c1=cc[8][3].c1=cc[8][4].c1=cc[9][1].c1=cc[9][2].c1=cc[9][3].c1=cc[9][4].c1=cc[6][7].c1=cc[7][7].c1=cc[8][7].c1=cc[9][7].c1=cc[6][6].c1=cc[7][6].c1=cc[8][6].c1=cc[9][6].c1='a';
 cc[4][1].c1=cc[4][2].c1=cc[4][3].c1=cc[4][4].c1=cc[13][1].c1=cc[13][2].c1=cc[13][3].c1=cc[13][4].c1=cc[20][7].c1=cc[21][7].c1=cc[22][7].c1=cc[23][7].c1=cc[20][6].c1=cc[21][6].c1=cc[22][6].c1=cc[23][6].c1='a';
 cc[20][1].c1=cc[20][2].c1=cc[20][3].c1=cc[20][4].c1=cc[21][1].c1=cc[21][2].c1=cc[21][3].c1=cc[21][4].c1=cc[22][1].c1=cc[22][2].c1=cc[22][3].c1=cc[22][4].c1=cc[23][1].c1=cc[23][2].c1=cc[23][3].c1=cc[23][4].c1='a';
 cc[0][6].c1=cc[5][6].c1=cc[19][6].c1='b';
 cc[4][6].c1=cc[13][6].c1='c';
 cc[19][5].c1=cc[3][5].c1=cc[29][5].c1='d';
 cc[5][5].c1=cc[5][0].c1=cc[14][0].c1=cc[14][5].c1='e';
 cc[14][7].c1=cc[4][7].c1=cc[24][7].c1=cc[12][7].c1=cc[29][7].c1='f';
}
void a()
{
 printf("error\t缺少操作数\n");
 if(S.top()==20+48)                    
  S.push(12+48);
 else if(S.top()==21+48)                      
  S.push(12+48);
 else if(S.top()==22+48)                      
  S.push(27+48);
 else if(S.top()==23+48)                      
  S.push(28+48);
 else
  S.push(5+48);
}
void b()
{
 printf("error\t多余右括号\n");
 nn=nn+1;
 ch=s[nn];
}
void c()
{
 printf("error\t括号里没有东西\n");
 if(S.top()==4+48)
  S.push(10+48);
 else
  S.push(24+48);
}
void d()                                  //右括号后面直接左括号
{
 printf("error\t缺少运算符\n");
 S.pop();S.pop();S.pop();
 if(S.top()==4+48)
 {S.push(10+28);S.push(20+48);}
 else if(S.top()==13+48||S.top()==20+48)
 {S.push(24+48);S.push(20+48);}
 else
 {S.push(3+48);S.push(6+48);}
}
void e()
{
 printf("error\t缺少运算符\n");             
 S.pop();
 if(S.top()==4+48)
 {S.push(10+48);S.push(20+48);}
 else if(S.top()==13+48)
 {S.push(24+48);S.push(20+48);}
 else
 {S.push(1+48);S.push(6+48);}
}
void f()
{
 if(S.top()!=29+48)
 {printf("error\t缺少右括号\n");TEMP++;}
 while(S.top()!=13+48&&S.top()!=4+48)
 {
  S.pop();
 }
 if(S.top()==13+48)
 {S.pop();S.push(12+48);}
 else
 {S.pop();S.push(3+48);}
}
int FeiZhong(char t)                                                            //非终结符数字化
{
 if(t=='E') return 0;
 if(t=='T') return 1;
 if(t=='F') return 2;
}
void display()
{
 cout<<"action"<<endl;
 for(p1=0;p1<30;p1++)
 { 
  for(p2=0;p2<8;p2++)
  {
   if(cc[p1][p2].c1=='s'||cc[p1][p2].c1=='r')
    cout<<cc[p1][p2].c1<<cc[p1][p2].c2;
   else
    cout<<cc[p1][p2].st;
   printf("\t");
  }
  cout<<endl;
 }
 cout<<"goto"<<endl;
 for(p1=0;p1<30;p1++)
 {
  for(p2=0;p2<3;p2++)
   printf("%d\t",bb[p1][p2]);
  cout<<endl;
 }
 cout<<"chanshengshi"<<endl;
 for(p1=0;p1<8;p1++)
  printf("%d\t%s\t%c\n",MM[p1].num,MM[p1].you,MM[p1].zuo);
}
void fenxi(int m,char t)
{
 if(cc[m][zhong(t)].c1=='s')
 {
  printf("%d\t%s\t%s",S.top()-48,s+nn,cc[m][zhong(t)].st);
  if(t=='i')
   printf("id\n");
  else
   printf("%c\n",t);
  S.push(cc[m][zhong(t)].c2+48);
  if(t=='i')
   nn=nn+2;
  else
   nn=nn+1;
  ch=s[nn];
 }
 else if(cc[m][zhong(t)].c1=='r')
 {
  printf("%d\t%s\t%s\t%s\n",S.top()-48,s+nn,cc[m][zhong(t)].st,MM[cc[m][zhong(t)].c2-1].you);
  for(p1=0;p1<MM[cc[m][zhong(t)].c2-1].num;p1++)
   S.pop();
  temp2=FeiZhong(MM[cc[m][zhong(t)].c2-1].zuo);
  temp1=bb[S.top()-48][temp2];
  S.push(temp1+48);
 }
 else if(cc[m][zhong(t)].c1=='o')
 {
  flag=1;
 }
 else
 {
  if(cc[m][zhong(t)].c1=='a')
   a();
  if(cc[m][zhong(t)].c1=='b')
   b();
  if(cc[m][zhong(t)].c1=='c')
   c();
  if(cc[m][zhong(t)].c1=='d')
   d();
  if(cc[m][zhong(t)].c1=='e')
   e();
  if(cc[m][zhong(t)].c1=='f')
   f();
 }
}
void FENXI()
{
 ch=s[nn];
 cout<<"语法分析!"<<endl;
 printf("栈顶:\n");
 while(1)
 {
  fenxi(S.top()-48,ch);
  if(flag==1)
  {
   printf("%d\t%s\t接受\tE'->E\n",S.top()-48,s+nn);
   cout<<"语法正确!"<<endl;
   break;
  }
 }
}
int main()
{
 cout<<"请输入词法流!(以#结束)"<<endl;
 gets(s);
 length=strlen(s);
 s[length]=s[length-1];
 s[length-1]='$';
 S.push('0');
 ChuShiHua();
 CuoWu();
 //display();
 FENXI();
 system("pause");
 return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值