精华内容
下载资源
问答
  • 算符语法分析器,是用C语言编写的,试试看,很不错的
  • 编译原理实验 词法分析器 语法分析器 完美代码 完美实验
  • 语法分析(C语言编写)

    2009-05-12 14:34:46
    C语言编写语法分析器,计算机专业的作业,需要的下载吧;
  • 算符优先语法分析器C语言编写

    热门讨论 2009-05-17 23:08:29
    这是一个由C语言编写语法分析器,采用算符优先算法,source文件中读取算符优先分法后构造FIRSTVT和LASTVT集,并构造优先关系表,最有打印详细规约过程。
  • c语言设计的词法分析器 做编译原理实验的福音
  • 语法分析器C语言实现

    千次阅读 2013-02-25 18:34:10
    #include"stdlib.h" #include"stdio.h" #include"string.h" #include typedef struct {  char R;  char r;  int flag; }array; array F[30]; typedef struct {  char E;  char e; }charLode;...type
    #include"stdlib.h"
    #include"stdio.h"
    #include"string.h"
    #include <windows.h>
    typedef struct
    {
          char R;
          char r;
          int flag;
    }array;
    array F[30];
    typedef struct
    {
          char E;
          char e;
    }charLode;
    typedef struct
    {
          charLode *base;
          int top;
    }charstack;
    char str[80][80],arr[80][80],brr[80][80];
    int m,kk,p,ppp,FF=1;
    char r[20];
    int crr[30][30],FLAG=0;
    char ccrr1[1][30],ccrr2[30][1];
    void Initstack(charstack *s)
    {
      s->base=(charLode *)malloc(30*sizeof(charLode));
          s->top=-1;
    }
    void push(charstack *s,charLode w)
    {
        s->top++;
        s->base[s->top].E=w.E;
        s->base[s->top].e=w.e;
    }
    void pop(charstack *s,charLode *w)
    {
        w->E=s->base[s->top].E;
        w->e=s->base[s->top].e;
        s->top--;
    }
    int IsEmpty(charstack s)
    {
          if(s.top==-1)
                  return 1;
          else
            return 0;
    }
    int IsLetter(char ch)
    {
          if(ch>='A'&&ch<='Z')
                return 1;
          else
        return 0;
    }

    int judge1(int n)
    {
          int j=3,flag=1,i;
          for(i=0;i<=n;i++)
        while(str[i][j]!='\0')
        {
                          char a=str[i][j];
                          char b=str[i][j+1];
                          if(IsLetter(a)&&IsLetter(b))
          {
            flag=0;
            break;
          }
                          else
            j++;
        }
        return flag;
    }

    void judge2(int n)
    {
      int i;
          for(i=0;i<=n;i++)
          if(str[i][3]=='~'||judge1(n)==0||FLAG==1)
          {
        printf("grammar G is not operator priority grammar!\n");
        FF=0;
        break;
      }
          if(i>n)
        printf("grammar G is operator priority grammar!\n");
    }

    int search1(char r[],int kk,char a)
    {
      int i;
          for(i=0;i<kk;i++)
                  if(r[i]==a)
                          break;
          if(i==kk)
        return 0;
          else
        return 1;
    }

    void createF(int n)
    {
          int k=0,i=1;
          char c;
          int j;
          char t[10];
          t[0]=str[0][0];
          while(i<=n)
      {
                  if(t[k]!=str[i][0])
        {
          k++;
          t[k]=str[i][0];
          i++;
        }
                  else
          i++;
      }
          kk=0;
          for(i=0;i<=n;i++)
      {
        j=3;
                  while(str[i][j]!='\0')
        {
                          c=str[i][j];
                          if(IsLetter(c)==0)
          {
                                  if(!search1(r,kk,c))
                                  r[kk]=c;
            kk++;
          }
                          j++;
        }
          }
          m=0;
          for(i=0;i<k;i++)
                  for(j=0;j<kk-1;j++)
        {
                          F[m].R=t[i];
                          F[m].r=r[j];
                          F[m].flag=0;
                          m++;
        }
    }

    void search(charLode w)
    {
      int i;
          for(i=0;i<m;i++)
                  if(F[i].R==w.E&&F[i].r==w.e)
        {
          F[i].flag=1;
          break;
        }
    }
    void FirstVT(int n)
    {
          charstack sta;
          charLode ww;
          charLode w;
          int i=0,k;
          char a,b;
          Initstack(&sta);
          while(i<=n)
      {
                  k=3;
                  w.E=str[i][0];
                  a=str[i][k];
                b=str[i][k+1];
                  if(!IsLetter(a))
        {
                          w.e=a;
                          push(&sta,w);
                          search(w);
                          i++;
        }
                  else if(IsLetter(a)&&b!='\0'&&!IsLetter(b))
        {
                          w.e=b;
                          push(&sta,w);
                          search(w);
                          i++;
        }
                  else
          i++;
      }
          while(!IsEmpty(sta))
      {
                  pop(&sta,&ww);
                  for(i=0;i<=n;i++)
        {
                          w.E=str[i][0];
                          if(str[i][3]==ww.E&&str[i][4]=='\0')
          {
                                  w.e=ww.e;
                                  push(&sta,w);
                                  search(w);
                                  break;
          }
          else if(str[i][3]==ww.E&&w.E!=ww.E)
          {
            w.e=ww.e;
                                  push(&sta,w);
                                  search(w);
                                  break;
          }
         
        }
      }
          p=0;
        k=1;i=1;
          while(i<m)
      {
                  if(F[i-1].flag==1)
        {
                          arr[p][0]=F[i-1].R;
                          arr[p][k]=F[i-1].r;
        }
                  while(F[i].flag==0&&i<m)
                          i++;
                  if(F[i].flag==1)
        {
                          if(F[i].R==arr[p][0])
                                  k++;
                          else
          {
            arr[p][k+1]='\0';
            p++;
            k=1;
          }
                          i++;
        }
       
    }
    void LastVT(int n)
    {
          charstack sta;
          charLode w;
          charLode ee;
          char a,b;
          int k,i;
          for(i=0;i<m;i++)
                  F[i].flag=0;
          i=0;
          Initstack(&sta);
          while(i<=n)
      {
                  int k=strlen(str[i]);
                  w.E=str[i][0];
                  a=str[i][k-1];
                  b=str[i][k-2];
                  if(!IsLetter(a))
        {
                          w.e=a;
                          push(&sta,w);
                          search(w);
                          i++;
        }
                  else if(IsLetter(a)&&!IsLetter(b))
        {
                          w.e=b;
                          push(&sta,w);
                          search(w);
                          i++;
        }
                  else
          i++;
      }
          while(!IsEmpty(sta))
      {
                  pop(&sta,&ee);
                  for(i=0;i<=n;i++)
        {
                          w.E=str[i][0];
                          if(str[i][3]==ee.E&&str[i][4]=='\0')
          {
                                  w.e=ee.e;
                                  push(&sta,w);
                                  search(w);
          }
        }
      }
        k=1;
      i=1;
          ppp=0;
          while(i<m)
      {
                  if(F[i-1].flag==1)
        {
                          brr[ppp][0]=F[i-1].R;
                          brr[ppp][k]=F[i-1].r;
        }
                  while(F[i].flag==0&&i<m)
                          i++;
                  if(F[i].flag==1)
        {
                          if(F[i].R==arr[ppp][0])
                                  k++;
                          else
          {
            brr[ppp][k+1]='\0';
            ppp++;
            k=1;
          }
                          i++;
        }
       
    }
    void createYXB(int n)
    {
          int i,j;
          int I,mm,pp,J;
          for(j=1;j<=kk;j++)
                  ccrr1[0][j]=r[j-1];
          for(i=1;i<=kk;i++)
                  ccrr2[i][0]=r[i-1];
          for(i=1;i<=kk;i++)
                  for(j=1;j<=kk;j++)
                          crr[i][j]=0;
          I=0,J=3;
          while(I<=n)
          {
                  if(str[I][J+1]=='\0')
        {
          I++;
          J=3;
        }
                  else
        {
                          while(str[I][J+1]!='\0')
          {
                                  char aa=str[I][J];
                                  char bb=str[I][J+1];
                                  if(!IsLetter(aa)&&!IsLetter(bb))
           
                                          for(i=1;i<=kk;i++)
              {
                                                  if(ccrr2[i][0]==aa)
                                                          break;
                                          }
                                          for(j=1;j<=kk;j++)
              {
                                                  if(ccrr1[0][j]==bb)
                                                          break; 
                                          }
                                          if(crr[i][j]==0)
                                                  crr[i][j]=1;
                                          else
              {
                FLAG=1;
                I=n+1;
              }
                                          J++;
            }
                                  if(!IsLetter(aa)&&IsLetter(bb)&&str[I][J+2]!='\0'&&!IsLetter(str[I][J+2]))
           
                                          for(i=1;i<=kk;i++)
              {
                                                  if(ccrr2[i][0]==aa)
                                                          break;
                                          }
                                          for(j=1;j<=kk;j++)
              {
                                                  if(ccrr1[0][j]==str[I][J+2])
                                                          break;
                                          }
                                          if(crr[i][j]==0)
                                                  crr[i][j]=1;
                                          else
              {
                FLAG=1;
                I=n+1;
              }
            }
                                  if(!IsLetter(aa)&&IsLetter(bb))
           
                                          for(i=1;i<=kk;i++)
              {
                                                  if(aa==ccrr2[i][0])
                                                          break;
                                          }
                                          for(j=0;j<=p;j++)
              {
                                                  if(bb==arr[j][0])
                                                          break;
                                          }
                                          for(mm=1;arr[j][mm]!='\0';mm++)
              {
                                                  for(pp=1;pp<=kk;pp++)
                {
                                                          if(ccrr1[0][pp]==arr[j][mm])
                                                                  break;
                }
                                                  if(crr[i][pp]==0)
                                                          crr[i][pp]=2;
                                                  else
                {
                  FLAG=1;
                  I=n+1;
                }
              }
                                          J++;
            }
                                  if(IsLetter(aa)&&!IsLetter(bb))
            {
                                          for(i=1;i<=kk;i++)
              {
                                                  if(ccrr1[0][i]==bb)
                                                          break;
              }
                                          for(j=0;j<=ppp;j++)
              {
                                                  if(aa==brr[j][0])
                                                          break;
              }
                                          for(mm=1;brr[j][mm]!='\0';mm++)
             
                                                  for(pp=1;pp<=kk;pp++)
                {
                                                          if(ccrr2[pp][0]==brr[j][mm])
                                                                  break;
                }
                                                  if(crr[pp][i]==0)
                                                          crr[pp][i]=3;
                                                  else
                {
                  FLAG=1;
                  I=n+1;
                }
               
              }
              J++;
            }
                          }
                  }
          }
    }

    int judge3(char s,char a)
    {
          int i=1,j=1;
          while(ccrr2[i][0]!=s)
                  i++;
          while(ccrr1[0][j]!=a)
                  j++;
          if(crr[i][j]==3)
        return 3;
          else if(crr[i][j]==2)
                  return 2;
          else if(crr[i][j]==1)
                  return 1;
          else return 0;
    }
    void print(char s[],char STR[][20],int q,int u,int ii,int k)
    {
      int i;
      printf("%d\t\t",u);
          for(i=0;i<=k;i++)
                 
        printf("%c",s[i]);
               
      printf("\t\t");
          for(i=q;i<=ii;i++)
               
        printf("%c",STR[0][i]);
       
      printf("\t\t");
    }
    void process(char STR[][20],int ii)
    {
          int k=0,q=0,u=0,b,i,j;
          char s[40],a;
          printf("step\t\tcharstack\tinputstring\tAction\n");
          s[k]='#';
          print(s,STR,q,u,ii,k);
      printf("ready\n");
          k++;
      u++;
          s[k]=STR[0][q];
          q++;
          print(s,STR,q,u,ii,k);
      printf("shift\n");
          while(q<=ii)
      {
                  a=STR[0][q];
                  if(!IsLetter(s[k]))
          j=k;
                  else
          j=k-1;
                  b=judge3(s[j],a);
                  if(b==3)
        {
                          while(IsLetter(s[j-1]))
                                  j--;
                          for(i=j;i<=k;i++)
                                  s[i]='\0';
                          k=j;s[k]='G';u++;
                          print(s,STR,q,u,ii,k);
          printf("reduce\n");
        }
                  else if(b==2||b==1)
        {
                          k++;
                          s[k]=a;
                          u++;
                          q++;
                          print(s,STR,q,u,ii,k);
                          if(s[0]=='#'&&s[1]=='N'&&s[2]=='#')
                                  printf("shift\n");
                          else
            printf("accept\n");
        }
                  else
        {
          printf("error\n");
          break;
        }
      }
          if(s[0]=='#'&&s[1]=='N'&&s[2]=='#')
        printf("Reduction is successful\n");
          else
        printf("Reduction fails\n");
    }
    void main()
    {
          int n,i,j,o;
          int ii;
          printf("please input the number of grammer G defined:");
          scanf("%d",&n);
          printf("please input the grammer G ");
          printf("\n");
          for(i=0;i<n;i++)
      {
              scanf("%s",str[i]);
              j=strlen(str[i]);
              str[i][j]='\0';
      }
          str[i][0]='Q';
          str[i][1]='-';
          str[i][2]='>';
          str[i][3]='#';
          str[i][4]=str[0][0];
          str[i][5]='#';
          str[i][6]='\0';
      printf("Creation style that you define as follows:\n");
          for(i=0;i<=n;i++)
        printf("%s\n",str[i]);
          if(judge1(n)==0)
        printf("Grammar G is not operator grammar !\n");
          if(judge1(n)==1)
      {
        printf("grammar G is the operator of grammar !\n");
                  createF(n);
                  FirstVT(n);
                  LastVT(n);
                  createYXB(n);
      }
          judge2(n);
          if(FLAG==0)
          {
                  for(i=0;i<=p;i++)
                  {
          printf("FirstVT(%c)={",arr[i][0]);
                          for(o=1;arr[i][o+1]!='\0';o++)
            printf("%c,",arr[i][o]);
          printf("%c}\n",arr[i][o]);
                  }
      }
        printf("FirstVT(Q)={#}\n");
                  for(i=0;i<=ppp;i++)
        {
          printf("LastVT(%c)={",arr[i][0]);
                          for(o=1;brr[i][o+1]!='\0';o++)
            printf("%c,",brr[i][o]);
          printf("%c}\n",brr[i][o]);
        }
        printf("LastVT(Q)={#}\n");
        printf("Priority table is as follows:\n");
                  for(i=1;i<kk;i++)
        {
          printf("    ");
          printf("%c",ccrr1[0][i]);
        }
        printf("\n");
                  for(i=1;i<kk;i++)
        {
          printf("%c  ",ccrr2[i][0]);
                          for(j=1;j<kk;j++)
          {
                                  if(crr[i][j]==0)
              printf(" ");
                                  else if(crr[i][j]==1)
              printf("=");
                                  else if(crr[i][j]==2)
              printf("<");
                                  else if(crr[i][j]==3)
                                          printf(">");
            printf("    ");
          }
          printf("\n");
        }
       
     
        if(FF==1)
        {
                  char STR[1][20];
        printf("Please input the string to the Statute:\n");
        scanf("%s",STR[0]);
        //getchar();
                  //gets(STR[0]);
                  ii=strlen(STR[0]);
                  STR[0][ii]='#';
        printf("the Analysis  are as follow:\n");
                  process(STR,ii);
        }
    }
     
     
     
    展开全文
  • 这是编译原理我自己做的语法分析,读取字符流文件分析出各种语法成分,也可以把他改成词法分析器。易读
  • 通过C语言编写一个语法分析器采用递归下降分析法编写语法分析程序及LL(1)语法分析法编写语法分析程序。附上实验报告。
  • c语言编写的词法分析器,从文件读入多行表达式,输出正确与否。
  • 这是一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。利用C语言编制递归下降分析程序,并对简单语言进行语法分析
  • 基于 pascal 语言的语法识别 小程序 C语言编写
  • C语言LL语法分析器

    2010-07-13 15:54:46
    利用C语言编写的LL语法分析器,用于判断语法是否正确。
  • 该词法分析器是编译原理课程设计时的项目,使用c语言编写,文件夹中的大部分文件都是当时使用的参考文件,文件夹‘词法分析器’为完成的可以直接运行的词法分析器,解压后可以直接运行。
  • 实验三 语法分析的C语言实现一、实验目的加深对语法分析器工作过程的理解;能够采用一种编程语言实现简单的语法分析程序; 能够使用自己编写的分析程序对简单的程序段进行语法分析。二、实验要求1、在实验一(用c语言...

    实验三 语法分析的C语言实现

    一、实验目的

    加深对语法分析器工作过程的理解;能够采用一种编程语言实现简单的语法分析程序; 能够使用自己编写的分析程序对简单的程序段进行语法分析。

    二、实验要求

    1、在实验一(用c语言实现词法分析的程序)的基础上,实现编写语法分析程序,语法 分析程序的实现可以采用任何一种编程工具。

    2、对语法规则有明确的定义;

    3、编写的分析程序能够对实验一的结果进行止确的语法分析;

    4、对于遇到的语法错误,能够做出简单的错误处理,给出简单的错误提示,保证顺利 完成语法分析过程;

    三、实验分工

    个人完成

    四、程序说明 有文法 G[E]: E->TG

    T->FS

    G->+TG| e S->*FS|=E| e F-> (E)|i

    1.1判断LL(1)文法

    当我们需选用a顶向下分析技术时,首先必须判别所给文法是否是ll(i)文 法,分析所给文法可知文法中不含左公因子,也不存在左递归,因而再对给定文 法计算First集、Follow集以及Select集,对于求出的每个产生式的Select 集,看对于同一个左部非终结符是否存在交集,如果它们的交为空则表示所给文 法是1X(1)文法,否则不是L(l)文法。若所给文法是LL(1)文法,再根据求得的 Select集合构造预测分析表,对于一个输入吊,根据已知的预测分析表分析它 是否是文法的句子。各非终结符的First集以及Follow集如下表所示:

    表1T

    VN

    First 集

    Follow 集

    E

    {(,i}

    {#,)}

    T

    {(,!}

    {+, #,)}

    G

    {+, £}

    {#,)}

    F

    {(,i}

    {*, +,二,#}

    S

    {*, =, £ }

    {+, #,)}

    齐产生式的Select集: Select (E->TG) = {(, i}

    Select (T->FS) = {(, i}Select (G->+TG) = {+}

    Select (T->FS) = {(, i}

    Select (G->+TG) = {+}

    Select(S->*FS)二{*}

    Select (F->(E)) = {()

    Select (S-> £ ) = {+,#,)} Select (S->=E) = {=}

    Select (F->i) = {i}

    曲各产生式的Select集可以看出,每个非终结符的Select集交集为空,则可以 确定该文法是1±(1)文法。

    1.2构造预测分析表

    表1-2

    \VT

    VN\

    ?

    1

    +

    *

    (

    )

    #

    =

    E

    ->TG

    ->TG

    ->TG

    T

    ->FS

    ->FS

    ->FS

    G

    ->+TG

    -> e

    -> e

    F

    -> £

    -〉*FS

    -> £

    -> £

    S

    ->i

    -> (E)

    ->=E

    程序流程图

    主要函数介绍:

    1、void print ();输出分析栈

    2、void printl ();输出剩余串

    3、intmainO;程序主函数,在其中调用门定义函数,完成文法产生式的赋值, 预测分析表的构建,以及对输入串的分析等主要功能。

    程序主要代码:

    1、初始化程序即分析栈、剩余串、非终结符与终结符的初始化

    char A[20] ;/*分析栈*/

    char B[20] ;/*剩余串*/

    char vl[20] = {'i',终结符 */

    char v2[20] = {'E','G','T','S','F'};/*非终结符 */

    int j二0,b二0,top二0,l;/*L 为输入串长度 */

    2、结构体的定义及结构体变量定义

    tvpedef struct type/*产生式类型定义*/

    {

    char origin;/*大写字符 */

    char array [5] ;A产生式右边字符*/

    int length;A字符个数 */

    }type;

    type c, e, t, g, gl, s, si, f, fl, s2;/*结构体变量 */

    type C[10][10];/*预测分析表 */

    3、输出分析栈函数定义

    void print ()

    {

    int a;

    for (a=0;a<=top+l;a++)

    printf (〃%c〃,A[a]);

    printf("\t\t");

    }

    4、输出剩余串函数定义

    void printl ()

    {

    int j;

    for (j=0;j

    printf (,z “);

    for(j=b;j<=l;j++)

    printf (〃%c〃,B[j]);

    printf (“\t\t\t");

    }

    5、在main函数中定义结构体,把文法产生式赋值给结构体

    /*把文法产生式赋值结构体*/

    e. origin」E‘ ;

    strepy(c. array, 〃TG〃);

    e.length=2;

    t. origin=,T'

    展开全文
  • 编译原理专题实验c语言语法分析器源代码,用c++做的。
  • ),用算符优先分析方法分析表达式是否合法,程序能给出语法分析过程和表达式的结果。由于C语言的运算符较多,导致算符运算关系表比较大,所以每种表达式选择了一种符号作为代表。压缩包中给了多个用例。
  • 实验三_用C语言编写TINY语言的词法分析器,供大家学习编译参考!
  • 词法分析器 编译原理实验 c语言
  • 实现了c语言的算术表达式的语法分析,用的是递归下降分析法。程序简单易懂
  • C语言编的词法分析器,含有语法分析,和程序生成部分,且有实验截图!
  • C++写的一个简单的语法分析器(分析C语言

    万次阅读 多人点赞 2012-11-23 13:23:06
    本程序实现一个分析C语言的词法分析+语法分析。 注意: 1.文法简略,没有实现的部分,可以在此文法的基础上进行扩充,本程序的采用自顶向下的LL(1)文法。 2.可以自动实现求First 集和 Follow 集。 3.处终结符外...

    本程序实现一个分析C语言的词法分析+语法分析。

    注意:

    1.文法简略,没有实现的部分,可以在此文法的基础上进行扩充,本程序的采用自顶向下的LL(1)文法。

    2.可以自动实现求First 集和 Follow 集。

    3.处终结符外(有些硬编码的成分),终结符的文法可以自定义,也就是说读者可以自定义文法。

    4.为方便理解,C语言的文法描述写成中文。

    5.程序将词法分析和语法分析结合起来,词法分析的结果作为语法分析的输入。

    6.最终结果在控制台显示的有:词法分析、First集、Follow集、Select集,在preciateResult.txt 中写入了语法分析结果,在preciateTable.txt 中写入了预测分析表。

    7.文法的词素之间必须有空格分开。

    项目结构如下:


    文法如下:

    wenfa.txt:

    <函数定义> -> <修饰词闭包> <类型> <变量> ( <参数声明> ) { <函数块> }
    <修饰词闭包> -> <修饰词> <修饰词闭包> | $
    <修饰词> -> describe
    <类型> -> type <取地址>
    <取地址> -> <星号闭包>
    <星号闭包> -> <星号> <星号闭包> | $
    <星号> -> *
    <变量> -> <标志符> <数组下标>
    <标志符> -> id
    <数组下标> -> [ <因式> ] | $
    <因式> -> ( <表达式> ) | <变量> | <数字>
    <数字> -> digit
    <表达式> -> <因子> <项>
    <因子> -> <因式> <因式递归>
    <因式递归> -> * <因式> <因式递归> | / <因式> <因式递归> | $
    <项> -> + <因子> <项> | - <因子> <项> | $
    <参数声明> -> <声明> <声明闭包> | $
    <声明> -> <修饰词闭包> <类型> <变量> <赋初值>
    <赋初值> -> = <右值> | $
    <右值> -> <表达式> | { <多个数据> }
    <多个数据> -> <数字> <数字闭包>
    <数字闭包> -> , <数字> <数字闭包> | $
    <声明闭包> -> , <声明> <声明闭包> | $
    <函数块> -> <声明语句闭包> <函数块闭包>
    <声明语句闭包> -> <声明语句> <声明语句闭包> | $
    <声明语句> -> <声明> ;
    <函数块闭包> -> <赋值函数> <函数块闭包> | <for循环> <函数块闭包> | <条件语句> <函数块闭包> | <函数返回> <函数块闭包> | $
    <赋值函数> -> <变量> <赋值或函数调用>
    <赋值或函数调用> -> = <右值> ; | ( <参数列表> ) ;
    <参数列表> -> <参数> <参数闭包>
    <参数闭包> -> , <参数> <参数闭包> | $
    <参数> -> <标志符> | <数字> | <字符串>
    <字符串> -> string
    <for循环> -> for ( <赋值函数> <逻辑表达式> ; <后缀表达式> ) { <函数块> }
    <逻辑表达式> -> <表达式> <逻辑运算符> <表达式>
    <逻辑运算符> -> < | > | == | !=
    <后缀表达式> -> <变量> <后缀运算符>
    <后缀运算符> -> ++ | --
    <条件语句> -> if ( <逻辑表达式> ) { <函数块> } <否则语句>
    <否则语句> -> else { <函数块> } | $
    <函数返回> -> return <因式> ;
    


    词法分析头文件:

    LexAnalysis.h

    //LexAnalysis.h
    #ifndef _LEXANALYSIS_H
    #define _LEXANALYSIS_H
    
    //关键字
    #define AUTO 1
    #define BREAK 2
    #define CASE 3
    #define CHAR 4
    #define CONST 5
    #define CONTINUE 6
    #define DEFAULT 7
    #define DO 8
    #define DOUBLE 9
    #define ELSE 10
    #define ENUM 11
    #define EXTERN 12
    #define FLOAT 13
    #define FOR 14
    #define GOTO 15
    #define IF 16
    #define INT 17
    #define LONG 18
    #define REGISTER 19
    #define RETURN 20
    #define SHORT 21
    #define SIGNED 22
    #define SIZEOF 23
    #define STATIC 24
    #define STRUCT 25
    #define SWITCH 26
    #define TYPEDEF 27
    #define UNION 28
    #define UNSIGNED 29
    #define VOID 30
    #define VOLATILE 31
    #define WHILE 32
    #define KEY_DESC "关键字"
    
    //标志符
    #define IDENTIFER 40
    #define IDENTIFER_DESC "标志符"
    
    //常量
    #define INT_VAL 51 //整形常量
    #define CHAR_VAL 52 //字符常量
    #define FLOAT_VAL 53 //浮点数常量
    #define STRING_VAL 54 //双精度浮点数常量
    #define MACRO_VAL 55 //宏常量
    #define CONSTANT_DESC "常量"
    
    //运算符
    #define NOT 61   // !
    #define BYTE_AND 62 //&
    #define COMPLEMENT 63 // ~
    #define BYTE_XOR  64 // ^
    #define MUL 65 // *
    #define DIV 66// /
    #define MOD 67 // %
    #define ADD 68 // +
    #define SUB 69 // -
    #define LES_THAN 70 // <
    #define GRT_THAN 71 // >
    #define ASG 72 // =
    #define ARROW 73 // ->
    #define SELF_ADD 74 // ++
    #define SELF_SUB 75 // --
    #define LEFT_MOVE 76 // <<
    #define RIGHT_MOVE 77 // >>
    #define LES_EQUAL 78 // <=
    #define GRT_EQUAL 79 // >=
    #define EQUAL 80 // ==
    #define NOT_EQUAL 81 // !=
    #define AND 82 // &&
    #define OR 83 // ||
    #define COMPLETE_ADD 84 // +=
    #define COMPLETE_SUB 85 // -=
    #define COMPLETE_MUL 86 // *=
    #define COMPLETE_DIV 87 // /=
    #define COMPLETE_BYTE_XOR 88 // ^=
    #define COMPLETE_BYTE_AND 89 // &=
    #define COMPLETE_COMPLEMENT 90 // ~=
    #define COMPLETE_MOD 91 //%=
    #define BYTE_OR 92 // |
    
    #define OPE_DESC "运算符"
    
    //限界符
    #define LEFT_BRA 100 // (
    #define RIGHT_BRA 101 // )
    #define LEFT_INDEX 102 // [
    #define RIGHT_INDEX 103 // ]
    #define L_BOUNDER 104 //  {
    #define R_BOUNDER 105 // }
    #define POINTER 106 // .
    #define JING 107 // #
    #define UNDER_LINE 108 // _
    #define COMMA 109 // ,
    #define SEMI 110 // ;
    #define SIN_QUE 111 // '
    #define DOU_QUE 112 // "
    
    #define CLE_OPE_DESC "限界符"
    
    #define NOTE1 120 // "/**/"注释
    #define NOTE2 121 // "//"注释
    #define NOTE_DESC "注释"
    
    
    #define HEADER 130 //头文件
    #define HEADER_DESC "头文件"
    
    //错误类型
    #define FLOAT_ERROR "float表示错误"
    #define FLOAT_ERROR_NUM 1
    #define DOUBLE_ERROR "double表示错误"
    #define DOUBLE_ERROR_NUM 2
    #define NOTE_ERROR "注释没有结束符"
    #define NOTE_ERROR_NUM 3
    #define STRING_ERROR "字符串常量没有结束符"
    #define STRING_ERROR_NUM 4
    #define CHARCONST_ERROR "字符常量没有结束符"
    #define CHARCONST_ERROR_NUM 5
    #define CHAR_ERROR "非法字符"
    #define CHAR_ERROR_NUM 6
    #define LEFT_BRA_ERROR "'('没有对应项"
    #define LEFT_BRA_ERROR_NUM 7
    #define RIGHT_BRA_ERROR "')'没有对应项"
    #define RIGHT_BRA_ERROR_NUM 8
    #define LEFT_INDEX_ERROR "'['没有对应项"
    #define LEFT_INDEX_ERROR_NUM 9
    #define RIGHT_INDEX_ERROR "']'没有对应项"
    #define RIGHT_INDEX_ERROR_NUM 10
    #define L_BOUNDER_ERROR "'{'没有对应项"
    #define L_BOUNDER_ERROR_NUM 11
    #define R_BOUNDER_ERROR "'}'没有对应项"
    #define R_BOUNDER_ERROR_NUM 12
    #define PRE_PROCESS_ERROR "预处理错误" //头文件或者宏定义错误
    #define PRE_PROCESS_ERROR_NUM  13
    
    #define _NULL "无"
    
    #define DESCRIBE 4000
    #define TYPE 4001
    #define STRING 4002
    #define DIGIT 4003
    
    struct NormalNode
    {
        char content[30];//内容
        char describe[30];//描述
        int type;//种别码
        int addr;//入口地址
        int line;//所在行数
        NormalNode * next;//下一个节点
    };
    
    void initKeyMapping();
    void initOperMapping();
    void initLimitMapping();
    
    void initNode();
    void createNewNode(char * content,char *descirbe,int type,int addr,int line);
    void createNewError(char * content,char *descirbe,int type,int line);
    int createNewIden(char * content,char *descirbe,int type,int addr,int line);
    void printNodeLink();
    void printErrorLink();
    void printIdentLink();
    int mystrlen(char * word);
    void preProcess(char * word,int line);
    void close();
    int seekKey(char * word);
    void scanner();
    void BraMappingError();
    
    
    #endif
    

    语法分析头文件:

    SynAnalysis.h

    //SynAnalysis.h
    #ifndef _SYNANALYSIS_H
    #define _SYNANALYSIS_H
    
    #define GRAMMAR_ARROW 2000 //->
    #define GRAMMAR_OR 2001 // |
    #define GRAMMAR_NULL 2002 //空值
    #define GRAMMAR_SPECIAL 2003 //特殊符号#
    #define GRAMMAR_BASE 2010 //动态生成的基值
    
    #define Stack_Size 5000
    
    typedef struct
    {
        int elem[Stack_Size];
        int top;
    } SeqStack;
    
    void initGrammer();
    int seekCodeNum(char * word);
    void ceshi();
    void First();
    void Follow();
    void Select();
    void MTable();
    void Analysis();
    #endif
    

    词法分析Cpp文件:(与先前写过的一片博客相类似,改了部分)

    LexAnalysis.cpp

    //LexAnalysis.cpp
    #include <iostream>
    #include <fstream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <vector>
    #include <iomanip>
    #include "LexAnalysis.h"
    
    using namespace std;
    
    int leftSmall = 0;//左小括号
    int rightSmall = 0;//右小括号
    int leftMiddle = 0;//左中括号
    int rightMiddle = 0;//右中括号
    int leftBig = 0;//左大括号
    int rightBig = 0;//右大括号
    int lineBra[6][1000] = {0};//括号和行数的对应关系,第一维代表左右6种括号
    int static_iden_number = 0;//模拟标志符的地址,自增
    //Token节点
    
    
    NormalNode * normalHead;//首结点
    
    //错误节点
    struct ErrorNode
    {
        char content[30];//错误内容
        char describe[30];//错误描述
        int type;
        int line;//所在行数
        ErrorNode * next;//下一个节点
    };
    
    ErrorNode * errorHead;//首节点
    
    //标志符节点
    struct IdentiferNode
    {
        char content[30];//内容
        char describe[30];//描述
        int type;//种别码
        int addr;//入口地址
        int line;//所在行数
        IdentiferNode * next;//下一个节点
    };
    IdentiferNode * idenHead;//首节点
    
    vector<pair<const char *,int> > keyMap;
    vector<pair<const char *,int> > operMap;
    vector<pair<const char *,int> > limitMap;
    
    
    
    //初始化C语言的关键字的集合
    void initKeyMapping()
    {
        keyMap.clear();
        keyMap.push_back(make_pair("auto",AUTO));
        keyMap.push_back(make_pair("break",BREAK));
        keyMap.push_back(make_pair("case",CASE));
        keyMap.push_back(make_pair("char",CHAR));
        keyMap.push_back(make_pair("const",CONST));
        keyMap.push_back(make_pair("continue",CONTINUE));
        keyMap.push_back(make_pair("default",DEFAULT));
        keyMap.push_back(make_pair("do",DO));
        keyMap.push_back(make_pair("double",DOUBLE));
        keyMap.push_back(make_pair("else",ELSE));
        keyMap.push_back(make_pair("enum",ENUM));
        keyMap.push_back(make_pair("extern",EXTERN));
        keyMap.push_back(make_pair("float",FLOAT));
        keyMap.push_back(make_pair("for",FOR));
        keyMap.push_back(make_pair("goto",GOTO));
        keyMap.push_back(make_pair("if",IF));
        keyMap.push_back(make_pair("int",INT));
        keyMap.push_back(make_pair("long",LONG));
        keyMap.push_back(make_pair("register",REGISTER));
        keyMap.push_back(make_pair("return",RETURN));
        keyMap.push_back(make_pair("short",SHORT));
        keyMap.push_back(make_pair("signed",SIGNED));
        keyMap.push_back(make_pair("sizeof",SIZEOF));
        keyMap.push_back(make_pair("static",STATIC));
        keyMap.push_back(make_pair("struct",STRUCT));
        keyMap.push_back(make_pair("switch",SWITCH));
        keyMap.push_back(make_pair("typedef",TYPEDEF));
        keyMap.push_back(make_pair("union",UNION));
        keyMap.push_back(make_pair("unsigned",UNSIGNED));
        keyMap.push_back(make_pair("void",VOID));
        keyMap.push_back(make_pair("volatile",VOLATILE));
        keyMap.push_back(make_pair("while",WHILE));
    
        keyMap.push_back(make_pair("describe",DESCRIBE));
        keyMap.push_back(make_pair("type",TYPE));
        keyMap.push_back(make_pair("string",STRING));
        keyMap.push_back(make_pair("digit",DIGIT));
    }
    void initOperMapping()
    {
        operMap.clear();
        operMap.push_back(make_pair("!",NOT));
        operMap.push_back(make_pair("&",BYTE_AND));
        operMap.push_back(make_pair("~",COMPLEMENT));
        operMap.push_back(make_pair("^",BYTE_XOR));
        operMap.push_back(make_pair("*",MUL));
        operMap.push_back(make_pair("/",DIV));
        operMap.push_back(make_pair("%",MOD));
        operMap.push_back(make_pair("+",ADD));
        operMap.push_back(make_pair("-",SUB));
        operMap.push_back(make_pair("<",LES_THAN));
        operMap.push_back(make_pair(">",GRT_THAN));
        operMap.push_back(make_pair("=",ASG));
        operMap.push_back(make_pair("->",ARROW));
        operMap.push_back(make_pair("++",SELF_ADD));
        operMap.push_back(make_pair("--",SELF_SUB));
        operMap.push_back(make_pair("<<",LEFT_MOVE));
        operMap.push_back(make_pair(">>",RIGHT_MOVE));
        operMap.push_back(make_pair("<=",LES_EQUAL));
        operMap.push_back(make_pair(">=",GRT_EQUAL));
        operMap.push_back(make_pair("==",EQUAL));
        operMap.push_back(make_pair("!=",NOT_EQUAL));
        operMap.push_back(make_pair("&&",AND));
        operMap.push_back(make_pair("||",OR));
        operMap.push_back(make_pair("+=",COMPLETE_ADD));
        operMap.push_back(make_pair("-=",COMPLETE_SUB));
        operMap.push_back(make_pair("*=",COMPLETE_MUL));
        operMap.push_back(make_pair("/=",COMPLETE_DIV));
        operMap.push_back(make_pair("^=",COMPLETE_BYTE_XOR));
        operMap.push_back(make_pair("&=",COMPLETE_BYTE_AND));
        operMap.push_back(make_pair("~=",COMPLETE_COMPLEMENT));
        operMap.push_back(make_pair("%=",COMPLETE_MOD));
        operMap.push_back(make_pair("|",BYTE_OR));
    }
    void initLimitMapping()
    {
        limitMap.clear();
        limitMap.push_back(make_pair("(",LEFT_BRA));
        limitMap.push_back(make_pair(")",RIGHT_BRA));
        limitMap.push_back(make_pair("[",LEFT_INDEX));
        limitMap.push_back(make_pair("]",RIGHT_INDEX));
        limitMap.push_back(make_pair("{",L_BOUNDER));
        limitMap.push_back(make_pair("}",R_BOUNDER));
        limitMap.push_back(make_pair(".",POINTER));
        limitMap.push_back(make_pair("#",JING));
        limitMap.push_back(make_pair("_",UNDER_LINE));
        limitMap.push_back(make_pair(",",COMMA));
        limitMap.push_back(make_pair(";",SEMI));
        limitMap.push_back(make_pair("'",SIN_QUE));
        limitMap.push_back(make_pair("\"",DOU_QUE));
    }
    void initNode()
    {
        normalHead = new NormalNode();
        strcpy(normalHead->content,"");
        strcpy(normalHead->describe,"");
        normalHead->type = -1;
        normalHead->addr = -1;
        normalHead->line = -1;
        normalHead->next = NULL;
    
        errorHead = new ErrorNode();
        strcpy(errorHead->content,"");
        strcpy(errorHead->describe,"");
        errorHead->line = -1;
        errorHead->next = NULL;
    
        idenHead = new IdentiferNode();
        strcpy(idenHead->content,"");
        strcpy(idenHead->describe,"");
        idenHead->type = -1;
        idenHead->addr = -1;
        idenHead->line = -1;
        idenHead->next = NULL;
    }
    
    void createNewNode(char * content,char *descirbe,int type,int addr,int line)
    {
        NormalNode * p = normalHead;
        NormalNode * temp = new NormalNode();
    
        while(p->next!=NULL)
        {
            p = p->next;
        }
    
        strcpy(temp->content,content);
        strcpy(temp->describe,descirbe);
        temp->type = type;
        temp->addr = addr;
        temp->line = line;
        temp->next = NULL;
    
        p->next = temp;
    }
    void createNewError(char * content,char *descirbe,int type,int line)
    {
        ErrorNode * p = errorHead;
        ErrorNode * temp = new ErrorNode();
    
        strcpy(temp->content,content);
        strcpy(temp->describe,descirbe);
        temp->type = type;
        temp->line = line;
        temp->next = NULL;
        while(p->next!=NULL)
        {
            p = p->next;
        }
        p->next = temp;
    }
    //返回值是新的标志符的入口地址
    int createNewIden(char * content,char *descirbe,int type,int addr,int line)
    {
        IdentiferNode * p = idenHead;
        IdentiferNode * temp = new IdentiferNode();
        int flag = 0;
        int addr_temp = -2;
        while(p->next!=NULL)
        {
            if(strcmp(content,p->next->content) == 0)
            {
                flag = 1;
                addr_temp = p->next->addr;
            }
            p = p->next;
        }
        if(flag == 0)
        {
            addr_temp = ++static_iden_number;//用自增来模拟入口地址
        }
        strcpy(temp->content,content);
        strcpy(temp->describe,descirbe);
        temp->type = type;
        temp->addr = addr_temp;
        temp->line = line;
        temp->next = NULL;
        p->next = temp;
        return addr_temp;
    }
    
    void printNodeLink()
    {
        NormalNode * p = normalHead;
        p = p->next;
        cout<<"************************************分析表******************************"<<endl<<endl;
        cout<<setw(30)<<"内容"<<setw(10)<<"描述"<<"\t"<<"种别码"<<"\t"<<"地址"<<"\t"<<"行号"<<endl;
        while(p!=NULL)
        {
            if(p->type == IDENTIFER)
            {
                cout<<setw(30)<<p->content<<setw(10)<<p->describe<<"\t"<<p->type<<"\t"<<p->addr<<"\t"<<p->line<<endl;
            }
            else
            {
                cout<<setw(30)<<p->content<<setw(10)<<p->describe<<"\t"<<p->type<<"\t"<<"\t"<<p->line<<endl;
            }
            p = p->next;
        }
        cout<<endl<<endl;
    }
    /*
    错误种类:
    1.float表示错误
    2.double表示错误
    3.注释没有结束符
    4.字符串常量没有结束符
    5.字符常量没有结束符
    6.非法字符
    7.'('没有对应项
    8.预处理错误
    */
    void printErrorLink()
    {
        ErrorNode * p = errorHead;
        p = p->next;
        cout<<"************************************错误表******************************"<<endl<<endl;
        cout<<setw(10)<<"内容"<<setw(30)<<"描述"<<"\t"<<"类型"<<"\t"<<"行号"<<endl;
        while(p!=NULL)
        {
            cout<<setw(10)<<p->content<<setw(30)<<p->describe<<"\t"<<p->type<<"\t"<<p->line<<endl;
            p = p->next;
        }
        cout<<endl<<endl;
    }
    //标志符表,有重复部分,暂不考虑
    void printIdentLink()
    {
        IdentiferNode * p = idenHead;
        p = p->next;
        cout<<"************************************标志符表******************************"<<endl<<endl;
        cout<<setw(30)<<"内容"<<setw(10)<<"描述"<<"\t"<<"种别码"<<"\t"<<"地址"<<"\t"<<"行号"<<endl;
        while(p!=NULL)
        {
            cout<<setw(30)<<p->content<<setw(10)<<p->describe<<"\t"<<p->type<<"\t"<<p->addr<<"\t"<<p->line<<endl;
            p = p->next;
        }
        cout<<endl<<endl;
    }
    int mystrlen(char * word)
    {
        if(*word == '\0')
        {
            return 0;
        }
        else
        {
            return 1+mystrlen(word+1);
        }
    }
    //预处理,处理头文件和宏定义
    void preProcess(char * word,int line)
    {
        const char * include_temp = "include";
        const char * define_temp = "define";
        char * p_include,*p_define;
        int flag = 0;
        p_include = strstr(word,include_temp);
        if(p_include!=NULL)
        {
            flag = 1;
            int i;
            for(i=7;;)
            {
                if(*(p_include+i) == ' ' || *(p_include+i) == '\t')
                {
                    i++;
                }
                else
                {
                    break;
                }
            }
            createNewNode(p_include+i,HEADER_DESC,HEADER,-1,line);
        }
        else
        {
            p_define = strstr(word,define_temp);
            if(p_define!=NULL)
            {
                flag = 1;
                int i;
                for(i=7;;)
                {
                    if(*(p_define+i) == ' ' || *(p_define+i) == '\t')
                    {
                        i++;
                    }
                    else
                    {
                        break;
                    }
                }
                createNewNode(p_define+i,CONSTANT_DESC,MACRO_VAL,-1,line);
            }
        }
        if(flag == 0)
        {
            createNewError(word,PRE_PROCESS_ERROR,PRE_PROCESS_ERROR_NUM,line);
        }
    }
    
    void close()
    {
        //delete idenHead;
        //delete errorHead;
        //delete normalHead;
    }
    
    int seekKey(char * word)
    {
        for(int i=0; i<keyMap.size(); i++)
        {
            if(strcmp(word,keyMap[i].first) == 0)
            {
                return i+1;
            }
        }
        return IDENTIFER;
    }
    
    void scanner()
    {
        char filename[30];
        char ch;
        char array[30];//单词长度上限是30
        char * word;
        int i;
        int line = 1;//行数
    
    
        FILE * infile;
        printf("请输入要进行语法分析的C语言程序:\n");
        scanf("%s",filename);
        infile = fopen(filename,"r");
        while(!infile)
        {
            printf("打开文件失败!\n");
            return;
        }
        ch = fgetc(infile);
        while(ch!=EOF)
        {
    
            i = 0;
            //以字母或者下划线开头,处理关键字或者标识符
            if((ch>='A' && ch<='Z') || (ch>='a' && ch<='z') || ch == '_')
            {
                while((ch>='A' && ch<='Z')||(ch>='a' && ch<='z')||(ch>='0' && ch<='9') || ch == '_')
                {
                    array[i++] = ch;
                    ch = fgetc(infile);
                }
                word = new char[i+1];
                memcpy(word,array,i);
                word[i] = '\0';
                int seekTemp = seekKey(word);
                if(seekTemp!=IDENTIFER)
                {
                    createNewNode(word,KEY_DESC,seekTemp,-1,line);
                }
                else
                {
                    int addr_tmp = createNewIden(word,IDENTIFER_DESC,seekTemp,-1,line);
                    createNewNode(word,IDENTIFER_DESC,seekTemp,addr_tmp,line);
                }
                fseek(infile,-1L,SEEK_CUR);//向后回退一位
            }
            //以数字开头,处理数字
            else if(ch >='0' && ch<='9')
            {
                int flag = 0;
                int flag2 = 0;
                //处理整数
                while(ch >='0' && ch<='9')
                {
                    array[i++] = ch;
                    ch = fgetc(infile);
                }
                //处理float
                if(ch == '.')
                {
                    flag2 = 1;
                    array[i++] = ch;
                    ch = fgetc(infile);
                    if(ch>='0' && ch<='9')
                    {
                        while(ch>='0' && ch<='9')
                        {
                            array[i++] = ch;
                            ch = fgetc(infile);
                        }
                    }
                    else
                    {
                        flag = 1;
                    }
    
                    //处理Double
                    if(ch == 'E' || ch == 'e')
                    {
                        array[i++] = ch;
                        ch = fgetc(infile);
                        if(ch == '+' || ch == '-')
                        {
                            array[i++] = ch;
                            ch = fgetc(infile);
                        }
                        if(ch >='0' && ch<='9')
                        {
                            array[i++] = ch;
                            ch = fgetc(infile);
                        }
                        else
                        {
                            flag = 2;
                        }
                    }
    
                }
                word = new char[i+1];
                memcpy(word,array,i);
                word[i] = '\0';
                if(flag == 1)
                {
                    createNewError(word,FLOAT_ERROR,FLOAT_ERROR_NUM,line);
                }
                else if(flag == 2)
                {
                    createNewError(word,DOUBLE_ERROR,DOUBLE_ERROR_NUM,line);
                }
                else
                {
                    if(flag2 == 0)
                    {
                        createNewNode(word,CONSTANT_DESC,INT_VAL,-1,line);
                    }
                    else
                    {
                        createNewNode(word,CONSTANT_DESC,FLOAT_VAL,-1,line);
                    }
                }
                fseek(infile,-1L,SEEK_CUR);//向后回退一位
            }
            //以"/"开头
            else if(ch == '/')
            {
                ch = fgetc(infile);
                //处理运算符"/="
                if(ch == '=')
                {
                    createNewNode("/=",OPE_DESC,COMPLETE_DIV,-1,line);
                }
                //处理"/**/"型注释
                else if(ch == '*')
                {
                    ch =  fgetc(infile);
                    while(1)
                    {
                        while(ch != '*')
                        {
                            if(ch == '\n')
                            {
                                line++;
                            }
                            ch = fgetc(infile);
                            if(ch == EOF)
                            {
                                createNewError(_NULL,NOTE_ERROR,NOTE_ERROR_NUM,line);
                                return;
                            }
                        }
                        ch = fgetc(infile);
                        if(ch == '/')
                        {
                            break;
                        }
                        if(ch == EOF)
                        {
                            createNewError(_NULL,NOTE_ERROR,NOTE_ERROR_NUM,line);
                            return;
                        }
                    }
                    createNewNode(_NULL,NOTE_DESC,NOTE1,-1,line);
                }
                //处理"//"型注释
                else if(ch == '/')
                {
                    while(ch!='\n')
                    {
                        ch = fgetc(infile);
                        if(ch == EOF)
                        {
                            createNewNode(_NULL,NOTE_DESC,NOTE2,-1,line);
                            return;
                        }
                    }
                    line++;
                    createNewNode(_NULL,NOTE_DESC,NOTE2,-1,line);
                    if(ch == EOF)
                    {
                        return;
                    }
                }
                //处理除号
                else
                {
                    createNewNode("/",OPE_DESC,DIV,-1,line);
                }
            }
            //处理常量字符串
            else if(ch == '"')
            {
                createNewNode("\"",CLE_OPE_DESC,DOU_QUE,-1,line);
                ch = fgetc(infile);
                i = 0;
                while(ch!='"')
                {
                    array[i++] = ch;
                    if(ch == '\n')
                    {
                        line++;
                    }
                    ch = fgetc(infile);
                    if(ch == EOF)
                    {
                        createNewError(_NULL,STRING_ERROR,STRING_ERROR_NUM,line);
                        return;
                    }
                }
                word = new char[i+1];
                memcpy(word,array,i);
                word[i] = '\0';
                createNewNode(word,CONSTANT_DESC,STRING_VAL,-1,line);
                createNewNode("\"",CLE_OPE_DESC,DOU_QUE,-1,line);
            }
            //处理常量字符
            else if(ch == '\'')
            {
                createNewNode("\'",CLE_OPE_DESC,SIN_QUE,-1,line);
                ch = fgetc(infile);
                i = 0;
                while(ch!='\'')
                {
                    array[i++] = ch;
                    if(ch == '\n')
                    {
                        line++;
                    }
                    ch = fgetc(infile);
                    if(ch == EOF)
                    {
                        createNewError(_NULL,CHARCONST_ERROR,CHARCONST_ERROR_NUM,line);
                        return;
                    }
                }
                word = new char[i+1];
                memcpy(word,array,i);
                word[i] = '\0';
                createNewNode(word,CONSTANT_DESC,CHAR_VAL,-1,line);
                createNewNode("\'",CLE_OPE_DESC,SIN_QUE,-1,line);
            }
            else if(ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n')
            {
                if(ch == '\n')
                {
                    line++;
                }
            }
            else
            {
                if(ch == EOF)
                {
                    return;
                }
                //处理头文件和宏常量(预处理)
                else if(ch == '#')
                {
                    while(ch!='\n' && ch!=EOF)
                    {
                        array[i++] = ch;
                        ch = fgetc(infile);
                    }
                    word = new char[i+1];
                    memcpy(word,array,i);
                    word[i] = '\0';
                    preProcess(word,line);
    
                    fseek(infile,-1L,SEEK_CUR);//向后回退一位
                }
                //处理-开头的运算符
                else if(ch == '-')
                {
                    array[i++] = ch;
                    ch = fgetc(infile);
                    if(ch >='0' && ch<='9')
                    {
                        int flag = 0;
                        int flag2 = 0;
                        //处理整数
                        while(ch>='0' && ch<='9')
                        {
                            array[i++] = ch;
                            ch = fgetc(infile);
                        }
                        //处理float
                        if(ch == '.')
                        {
                            flag2 = 1;
                            array[i++] = ch;
                            ch = fgetc(infile);
                            if(ch>='0' && ch<='9')
                            {
                                while(ch>='0' && ch<='9')
                                {
                                    array[i++] = ch;
                                    ch = fgetc(infile);
                                }
                            }
                            else
                            {
                                flag = 1;
                            }
                            //处理Double
                            if(ch == 'E' || ch == 'e')
                            {
                                array[i++] = ch;
                                ch = fgetc(infile);
                                if(ch == '+' || ch == '-')
                                {
                                    array[i++] = ch;
                                    ch = fgetc(infile);
                                }
                                if(ch >='0' && ch<='9')
                                {
                                    array[i++] = ch;
                                    ch = fgetc(infile);
                                }
                                else
                                {
                                    flag = 2;
                                }
                            }
                        }
                        word = new char[i+1];
                        memcpy(word,array,i);
                        word[i] = '\0';
                        if(flag == 1)
                        {
                            createNewError(word,FLOAT_ERROR,FLOAT_ERROR_NUM,line);
                        }
                        else if(flag == 2)
                        {
                            createNewError(word,DOUBLE_ERROR,DOUBLE_ERROR_NUM,line);
                        }
                        else
                        {
                            if(flag2 == 0)
                            {
                                createNewNode(word,CONSTANT_DESC,INT_VAL,-1,line);
                            }
                            else
                            {
                                createNewNode(word,CONSTANT_DESC,FLOAT_VAL,-1,line);
                            }
                        }
                        fseek(infile,-1L,SEEK_CUR);//向后回退一位
                    }
                    else if(ch == '>')
                    {
                        createNewNode("->",OPE_DESC,ARROW,-1,line);
                    }
                    else if(ch == '-')
                    {
                        createNewNode("--",OPE_DESC,SELF_SUB,-1,line);
                    }
                    else if(ch == '=')
                    {
                        createNewNode("--",OPE_DESC,SELF_SUB,-1,line);
                    }
                    else
                    {
                        createNewNode("-",OPE_DESC,SUB,-1,line);
                        fseek(infile,-1L,SEEK_CUR);
                    }
                }
                //处理+开头的运算符
                else if(ch == '+')
                {
                    ch = fgetc(infile);
                    if(ch == '+')
                    {
                        createNewNode("++",OPE_DESC,SELF_ADD,-1,line);
                    }
                    else if(ch == '=')
                    {
                        createNewNode("+=",OPE_DESC,COMPLETE_ADD,-1,line);
                    }
                    else
                    {
                        createNewNode("+",OPE_DESC,ADD,-1,line);
                        fseek(infile,-1L,SEEK_CUR);
                    }
                }
                //处理*开头的运算符
                else if(ch == '*')
                {
                    ch = fgetc(infile);
                    if(ch == '=')
                    {
                        createNewNode("*=",OPE_DESC,COMPLETE_MUL,-1,line);
                    }
                    else
                    {
                        createNewNode("*",OPE_DESC,MUL,-1,line);
                        fseek(infile,-1L,SEEK_CUR);
                    }
                }
                //处理按^开头的运算符
                else if(ch == '^')
                {
                    ch = fgetc(infile);
                    if(ch == '=')
                    {
                        createNewNode("^=",OPE_DESC,COMPLETE_BYTE_XOR,-1,line);
                    }
                    else
                    {
                        createNewNode("^",OPE_DESC,BYTE_XOR,-1,line);
                        fseek(infile,-1L,SEEK_CUR);
                    }
                }
                //处理%开头的运算符
                else if(ch == '%')
                {
                    ch = fgetc(infile);
                    if(ch == '=')
                    {
                        createNewNode("%=",OPE_DESC,COMPLETE_MOD,-1,line);
                    }
                    else
                    {
                        createNewNode("%",OPE_DESC,MOD,-1,line);
                        fseek(infile,-1L,SEEK_CUR);
                    }
                }
                //处理&开头的运算符
                else if(ch == '&')
                {
                    ch = fgetc(infile);
                    if(ch == '=')
                    {
                        createNewNode("&=",OPE_DESC,COMPLETE_BYTE_AND,-1,line);
                    }
                    else if(ch == '&')
                    {
                        createNewNode("&&",OPE_DESC,AND,-1,line);
                    }
                    else
                    {
                        createNewNode("&",OPE_DESC,BYTE_AND,-1,line);
                        fseek(infile,-1L,SEEK_CUR);
                    }
                }
                //处理~开头的运算符
                else if(ch == '~')
                {
                    ch = fgetc(infile);
                    if(ch == '=')
                    {
                        createNewNode("~=",OPE_DESC,COMPLETE_COMPLEMENT,-1,line);
                    }
                    else
                    {
                        createNewNode("~",OPE_DESC,COMPLEMENT,-1,line);
                        fseek(infile,-1L,SEEK_CUR);
                    }
                }
                //处理!开头的运算符
                else if(ch == '!')
                {
                    ch = fgetc(infile);
                    if(ch == '=')
                    {
                        createNewNode("!=",OPE_DESC,NOT_EQUAL,-1,line);
                    }
                    else
                    {
                        createNewNode("!",OPE_DESC,NOT,-1,line);
                        fseek(infile,-1L,SEEK_CUR);
                    }
                }
                //处理<开头的运算符
                else if(ch == '<')
                {
                    ch = fgetc(infile);
                    if(ch == '<')
                    {
                        createNewNode("<<",OPE_DESC,LEFT_MOVE,-1,line);
                    }
                    else if(ch == '=')
                    {
                        createNewNode("<=",OPE_DESC,LES_EQUAL,-1,line);
                    }
                    else
                    {
                        createNewNode("<",OPE_DESC,LES_THAN,-1,line);
                        fseek(infile,-1L,SEEK_CUR);
                    }
                }
                //处理>开头的运算符
                else if(ch == '>')
                {
                    ch = fgetc(infile);
                    if(ch == '>')
                    {
                        createNewNode(">>",OPE_DESC,RIGHT_MOVE,-1,line);
                    }
                    else if(ch == '=')
                    {
                        createNewNode(">=",OPE_DESC,GRT_EQUAL,-1,line);
                    }
                    else
                    {
                        createNewNode(">",OPE_DESC,GRT_THAN,-1,line);
                        fseek(infile,-1L,SEEK_CUR);
                    }
                }
                //处理|开头的运算符
                else if(ch == '|')
                {
                    ch = fgetc(infile);
                    if(ch == '|')
                    {
                        createNewNode("||",OPE_DESC,OR,-1,line);
                    }
                    else
                    {
                        createNewNode("|",OPE_DESC,BYTE_OR,-1,line);
                        fseek(infile,-1L,SEEK_CUR);
                    }
                }
                else if(ch == '=')
                {
                    ch = fgetc(infile);
                    if(ch == '=')
                    {
                        createNewNode("==",OPE_DESC,EQUAL,-1,line);
                    }
                    else
                    {
                        createNewNode("=",OPE_DESC,ASG,-1,line);
                        fseek(infile,-1L,SEEK_CUR);
                    }
                }
                else if(ch == '(')
                {
                    leftSmall++;
                    lineBra[0][leftSmall] = line;
                    createNewNode("(",CLE_OPE_DESC,LEFT_BRA,-1,line);
                }
                else if(ch == ')')
                {
                    rightSmall++;
                    lineBra[1][rightSmall] = line;
                    createNewNode(")",CLE_OPE_DESC,RIGHT_BRA,-1,line);
                }
                else if(ch == '[')
                {
                    leftMiddle++;
                    lineBra[2][leftMiddle] = line;
                    createNewNode("[",CLE_OPE_DESC,LEFT_INDEX,-1,line);
                }
                else if(ch == ']')
                {
                    rightMiddle++;
                    lineBra[3][rightMiddle] = line;
                    createNewNode("]",CLE_OPE_DESC,RIGHT_INDEX,-1,line);
                }
                else if(ch == '{')
                {
                    leftBig++;
                    lineBra[4][leftBig] = line;
                    createNewNode("{",CLE_OPE_DESC,L_BOUNDER,-1,line);
                }
                else if(ch == '}')
                {
                    rightBig++;
                    lineBra[5][rightBig] = line;
                    createNewNode("}",CLE_OPE_DESC,R_BOUNDER,-1,line);
                }
                else if(ch == '.')
                {
                    createNewNode(".",CLE_OPE_DESC,POINTER,-1,line);
                }
                else if(ch == ',')
                {
                    createNewNode(",",CLE_OPE_DESC,COMMA,-1,line);
                }
                else if(ch == ';')
                {
                    createNewNode(";",CLE_OPE_DESC,SEMI,-1,line);
                }
                else
                {
                    char temp[2];
                    temp[0] = ch;
                    temp[1] = '\0';
                    createNewError(temp,CHAR_ERROR,CHAR_ERROR_NUM,line);
                }
            }
            ch = fgetc(infile);
        }
    }
    void BraMappingError()
    {
        if(leftSmall != rightSmall)
        {
            int i = (leftSmall>rightSmall) ? (leftSmall-rightSmall) : (rightSmall - leftSmall);
            bool  flag = (leftSmall>rightSmall) ? true : false;
            if(flag)
            {
                while(i--)
                {
                    createNewError(_NULL,LEFT_BRA_ERROR,LEFT_BRA_ERROR_NUM,lineBra[0][i+1]);
                }
            }
            else
            {
                while(i--)
                {
                    createNewError(_NULL,RIGHT_BRA_ERROR,RIGHT_BRA_ERROR_NUM,lineBra[1][i+1]);
                }
            }
        }
        if(leftMiddle != rightMiddle)
        {
            int i = (leftMiddle>rightMiddle) ? (leftMiddle-rightMiddle) : (rightMiddle - leftMiddle);
            bool flag = (leftMiddle>rightMiddle) ? true : false;
            if(flag)
            {
                while(i--)
                {
                    createNewError(_NULL,LEFT_INDEX_ERROR,LEFT_INDEX_ERROR_NUM,lineBra[2][i+1]);
                }
            }
            else
            {
                while(i--)
                {
                    createNewError(_NULL,RIGHT_INDEX_ERROR,RIGHT_INDEX_ERROR_NUM,lineBra[3][i+1]);
                }
            }
        }
        if(leftBig != rightBig)
        {
            int i = (leftBig>rightBig) ? (leftBig-rightBig) : (rightBig - leftSmall);
            bool flag = (leftBig>rightBig) ? true : false;
            if(flag)
            {
                while(i--)
                {
                    createNewError(_NULL,L_BOUNDER_ERROR,L_BOUNDER_ERROR_NUM,lineBra[4][i+1]);
                }
            }
            else
            {
                while(i--)
                {
                    createNewError(_NULL,R_BOUNDER_ERROR,R_BOUNDER_ERROR_NUM,lineBra[5][i+1]);
                }
            }
        }
    }
    
    

    语法分析Cpp代码:

    //SynAnalysis.cpp
    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <conio.h>
    #include <fstream>
    #include <vector>
    #include <conio.h>
    #include "LexAnalysis.h"
    #include "SynAnalysis.h"
    
    using namespace std;
    
    #define Max_Proc 500
    #define Max_Length 500
    
    #define Max_NonTer 60
    #define Max_Ter 60
    #define Max_Length2 100
    
    int procNum = 0;
    //proc的维数都是从1开始的
    int proc[Max_Proc][Max_Length];//产生式的数组,里边存储了终结符或者非终结符对应的编号
    int first[Max_Proc][Max_Length];
    int follow[Max_Proc][Max_Length];
    int select[Max_Proc][Max_Length];
    int M[Max_NonTer][Max_Ter][Max_Length2];
    
    int connectFirst[Max_Length];//将某些First集结合起来的集合
    
    
    int firstVisit[Max_Proc];//记录某非终结符的First集是否已经求过
    int followVisit[Max_Proc];//记录某非终结符的Follow集是否已经求过
    
    int empty[Max_Proc];//可推出空的非终结符的编号
    int emptyRecu[Max_Proc];//在求可推出空的非终结符的编号集时使用的防治递归的集合
    int followRecu[Max_Proc];//在求Follow集时使用的防治递归的集合
    
    //extern的部分代表可能出现的终结符和其编号
    extern vector<pair<const char *,int> > keyMap;
    extern vector<pair<const char *,int> > operMap;
    extern vector<pair<const char *,int> > limitMap;
    
    extern NormalNode * normalHead;//首结点
    
    fstream resultfile;
    
    vector<pair<const char *,int> > nonTerMap;//非终结符映射表,不可重复的
    vector<pair<const char *,int> > terMap;//终结符映射表,不可重复的
    vector<pair<const char *,int> > specialMap;//文法中的特殊符号映射表,包括-> | $(空)
    
    
    void initSpecialMapping()
    {
        specialMap.clear();
        specialMap.push_back(make_pair("->",GRAMMAR_ARROW));
        specialMap.push_back(make_pair("|",GRAMMAR_OR));
        specialMap.push_back(make_pair("$",GRAMMAR_NULL));
        specialMap.push_back(make_pair("#",GRAMMAR_SPECIAL));
    
    }
    const char * searchMapping(int num)
    {
        //标志符
        if(num == IDENTIFER)
        {
            return "id";
        }
        //处理文法中的特殊符号
        for(int i = 0; i<specialMap.size(); i++)
        {
            if(specialMap[i].second == num)
            {
                return specialMap[i].first;
            }
        }
        //处理非终结符
        for(int i=0; i<nonTerMap.size(); i++)
        {
            if(nonTerMap[i].second == num)
            {
                return nonTerMap[i].first;
            }
        }
        //处理终结符
        for(int i=0; i<terMap.size(); i++)
        {
            if(terMap[i].second == num)
            {
                return terMap[i].first;
            }
        }
    
    }
    
    //动态生成非终结符,在基点的基础上,确保不和终结符冲突
    int dynamicNonTer(char *word)
    {
        int i = 0;
        int dynamicNum;
        for(i=0; i<nonTerMap.size(); i++)
        {
            if(strcmp(word,nonTerMap[i].first) == 0)
            {
                return nonTerMap[i].second;
            }
        }
        if(i == nonTerMap.size())
        {
            if(i == 0)
            {
                dynamicNum = GRAMMAR_BASE;
                nonTerMap.push_back(make_pair(word,dynamicNum));
            }
            else
            {
                dynamicNum = nonTerMap[nonTerMap.size()-1].second + 1;
                nonTerMap.push_back(make_pair(word,dynamicNum));
            }
        }
        return dynamicNum;
    }
    //判断某个标号是不是非终结符的标号,1代表是,0代表否
    int inNonTer(int n)
    {
        for(int i=0; i<nonTerMap.size(); i++)
        {
            if(nonTerMap[i].second == n)
            {
                return 1;
            }
        }
        return 0;
    }
    //判断某个标号是不是终结符的标号,1代表是,0代表否
    int inTer(int n)
    {
        for(int i=0; i<terMap.size(); i++)
        {
            if(terMap[i].second == n)
            {
                return 1;
            }
        }
        return 0;
    }
    //判断某个标号在不在此时的empty集中,1代表是,0代表否
    int inEmpty(int n)
    {
        //当前Empty集的长度
        int emptyLength = 0;
        for(emptyLength = 0;; emptyLength++)
        {
            if(empty[emptyLength] == -1)
            {
                break;
            }
        }
        for(int i = 0; i<emptyLength; i++)
        {
            if(empty[i] == n)
            {
                return 1;
            }
        }
        return 0;
    
    }
    //判断某个标号在不在此时的emptyRecu集中,1代表是,0代表否
    int inEmptyRecu(int n)
    {
        //当前Empty集的长度
        int emptyLength = 0;
        for(emptyLength = 0;; emptyLength++)
        {
            if(emptyRecu[emptyLength] == -1)
            {
                break;
            }
        }
        for(int i = 0; i<emptyLength; i++)
        {
            if(emptyRecu[i] == n)
            {
                return 1;
            }
        }
        return 0;
    }
    //判断某个标号在不在此时的followRecu集中,1代表是,0代表否
    int inFollowRecu(int n)
    {
        int followLength = 0;
        for(followLength = 0;; followLength++)
        {
            if(followRecu[followLength] == -1)
            {
                break;
            }
        }
        for(int i = 0; i<followLength; i++)
        {
            if(followRecu[i] == n)
            {
                return 1;
            }
        }
        return 0;
    }
    
    //判断某个标号是不是在产生式的右边
    int inProcRight(int n,int * p)
    {
        //注意这里默认是从3开始
        for(int i=3;; i++)
        {
            if(p[i] == -1)
            {
                break;
            }
            if(p[i] == n)
            {
                return 1;
            }
        }
        return 0;
    }
    
    int seekCodeNum(char * word)
    {
        //处理文法中的特殊符号
        for(int i = 0; i<specialMap.size(); i++)
        {
            if(strcmp(word,specialMap[i].first) == 0)
            {
                return specialMap[i].second;
            }
        }
        //先搜索终结符映射表中有没有此终结符
        for(int i=0; i<terMap.size(); i++)
        {
            if(strcmp(word,terMap[i].first) == 0)
            {
                return terMap[i].second;
            }
        }
        for(int i = 0; i<keyMap.size(); i++)
        {
            if(strcmp(word,keyMap[i].first) == 0)
            {
                terMap.push_back(make_pair(word,keyMap[i].second));
                return keyMap[i].second;
            }
        }
    
        for(int i = 0; i<operMap.size(); i++)
        {
            if(strcmp(word,operMap[i].first) == 0)
            {
                terMap.push_back(make_pair(word,operMap[i].second));
                return operMap[i].second;
            }
        }
    
        for(int i = 0; i<limitMap.size(); i++)
        {
            if(strcmp(word,limitMap[i].first) == 0)
            {
                terMap.push_back(make_pair(word,limitMap[i].second));
                return limitMap[i].second;
            }
        }
    
        if(strcmp(word,"id")==0)
        {
            //处理标志符
            terMap.push_back(make_pair(word,IDENTIFER));
            return IDENTIFER;
        }
        else
        {
            //处理关键字、运算符、限界符表,即非终结符
            return dynamicNonTer(word);
        }
    }
    //分割" | "文法
    void splitProc(int p[][Max_Length],int &line,int orNum)
    {
        if(p[line][1] == -1 || orNum == 0)
        {
            return;
        }
        int head = p[line][1];
        int push = p[line][2];
        int length = 0;
        int right,left;
        int lineTrue = line + orNum;
        for(length = 3;;length++)
        {
            if(p[line][length] == -1)
            {
                break;
            }
        }
        length--;
        for(left = length,right = length;left>=2;)
        {
            if(p[line][left] == GRAMMAR_OR || left == 2)
            {
                p[line + orNum][1] = head;
                p[line + orNum][2] = push;
                for(int i=left+1;i<=right;i++)
                {
                    p[line+orNum][i-left+2] = p[line][i];
                }
                p[line+orNum][right-left+3] = -1;
                right = left = left-1;
                orNum--;
            }
            else
            {
                left--;
            }
        }
        line = lineTrue;
    }
    void initGrammer()
    {
        FILE * infile;
        char ch;
        char array[30];
        char * word;
        int i;
        int codeNum;
        int line = 1;
        int count = 0;
        int orNum = 0;
        infile = fopen("wenfa.txt","r");
        if(!infile)
        {
            printf("文法打开失败!\n");
            return;
        }
        initSpecialMapping();
        nonTerMap.clear();
        terMap.clear();
    
        memset(proc,-1,sizeof(proc));
        memset(first,-1,sizeof(first));
        memset(follow,-1,sizeof(follow));
        memset(select,-1,sizeof(select));
    
        memset(connectFirst,-1,sizeof(connectFirst));
    
        memset(firstVisit,0,sizeof(firstVisit));//非终结符的first集还未求过
        memset(followVisit,0,sizeof(followVisit));//非终结符的follow集还未求过
    
        memset(empty,-1,sizeof(empty));
        memset(emptyRecu,-1,sizeof(emptyRecu));
        memset(followRecu,-1,sizeof(followRecu));
    
        memset(M,-1,sizeof(M));
    
        ch = fgetc(infile);
        i = 0;
        while(ch!=EOF)
        {
            i = 0;
            while(ch == ' ' || ch == '\t')
            {
                ch = fgetc(infile);
            }
            while(ch!=' ' && ch!= '\n' && ch!=EOF)
            {
                array[i++] = ch;
                ch = fgetc(infile);
            }
            while(ch == ' ' || ch == '\t')
            {
                ch = fgetc(infile);
            }
            word = new char[i+1];
            memcpy(word,array,i);
            word[i] = '\0';
            codeNum = 0;
            codeNum = seekCodeNum(word);
            if(codeNum!=0)
            {
                count++;
                if(codeNum == GRAMMAR_OR)
                {
                    orNum++;
                }
                proc[line][count] = codeNum;
    
            }
            //原本需要回退一个字符,由于是冗余字符,不回退
            if(ch == '\n')
            {
                splitProc(proc,line,orNum);//将" | "文法进行拆分
                count = 0;
                orNum = 0;
                line++;
                ch = fgetc(infile);
            }
        }
        procNum = line - 1;
        printf("************************************C语言文法******************************\n\n");
        for(int i=1; i<line; i++)
        {
            for(int j=1; j<Max_Length; j++)
            {
                if(proc[i][j]!=-1)
                {
                    printf("%s ",searchMapping(proc[i][j]));
                }
                else
                {
                    break;
                }
            }
            printf("\n");
        }
        printf("\n************************************文法终结符******************************\n\n");
        for(int i=0; i<terMap.size(); i++)
        {
            printf("%s ",terMap[i].first);
        }
        printf("\n");
        printf("\n************************************文法非终结符******************************\n\n");
        for(int i=0; i<nonTerMap.size(); i++)
        {
            printf("%s ",nonTerMap[i].first);
        }
        printf("\n");
    }
    //将s集合合并至d集合中,type = 1代表包括空($),type = 2代表不包括空
    void merge(int *d,int *s,int type)
    {
        int flag = 0;
        for(int i = 0;; i++)
        {
            flag = 0;
            if(s[i] == -1)
            {
                break;
            }
            int j = 0;
            for(j = 0;; j++)
            {
                if(d[j] == -1)
                {
                    break;
                }
                if(d[j] == s[i])
                {
                    flag = 1;
                    break;
                }
            }
            if(flag == 1)
            {
                continue;
            }
            if(type == 1)
            {
                d[j] = s[i];
            }
            else
            {
                if(s[i] != GRAMMAR_NULL)
                {
                    d[j] = s[i];
                }
            }
            d[j + 1] = -1;
        }
    }
    
    void nullSet(int currentNum)
    {
        int temp[2];
        for(int j = 1; j<=procNum; j++)
        {
            //如果右边的第一个是该字符,并且长度只有1
            if(proc[j][3] == currentNum && proc[j][4] == -1)
            {
                temp[0] = proc[j][1];
                temp[1] = -1;
                merge(empty,temp,1);
                nullSet(proc[j][1]);
            }
        }
    }
    //判断该非终结符是否能推出空,但终结符也可能传入,但没关系
    int reduNull(int currentNon)
    {
        int temp[2];
        int result = 1;
        int mark = 0;
        temp[0] = currentNon;
        temp[1] = -1;
        merge(emptyRecu,temp,1);//先将此符号并入防递归集合中
        if(inEmpty(currentNon) == 1)
        {
            return 1;
        }
    
        for(int j = 1; j<=procNum; j++)
        {
            if(proc[j][1] == currentNon)
            {
                int rightLength = 0;
                //先求出右部的长度
                for(rightLength = 3;; rightLength++)
                {
                    if(proc[j][rightLength] == -1)
                    {
                        break;
                    }
                }
                rightLength--;
                //如果长度为1,并且已经求过
                if(rightLength - 2 == 1 && inEmpty(proc[j][rightLength]))
                {
                    return 1;
                }
                //如果长度为1,并且是终结符
                else if(rightLength -2 == 1 && inTer(proc[j][rightLength]))
                {
                    return 0;
                }
                //如果长度超过了2
                else
                {
                    for(int k=3; k<=rightLength; k++)
                    {
                        if(inEmptyRecu(proc[j][k]))
                        {
                            mark = 1;
                        }
                    }
                    if(mark == 1)
                    {
                        continue;
                    }
                    else
                    {
                        for(int k=3; k<=rightLength; k++)
                        {
                            result*= reduNull(proc[j][k]);
                            temp[0] = proc[j][k];
                            temp[1] = -1;
                            merge(emptyRecu,temp,1);//先将此符号并入防递归集合中
                        }
                    }
                }
                if(result == 0)
                {
                    continue;
                }
                else if(result == 1)
                {
                    return 1;
                }
            }
        }
        return 0;
    }
    
    //求first集,传入的参数是在非终结符集合中的序号
    void firstSet(int i)
    {
        int k = 0;
        int currentNon = nonTerMap[i].second;//当前的非终结符标号
        //依次遍历全部产生式
        for(int j = 1; j<=procNum; j++) //j代表第几个产生式
        {
            //找到该非终结符的产生式
            if(currentNon == proc[j][1])//注意从1开始
            {
                //当右边的第一个是终结符或者空的时候
                if(inTer(proc[j][3]) == 1 || proc[j][3] == GRAMMAR_NULL)
                {
                    //并入当前非终结符的first集中
                    int temp[2];
                    temp[0] = proc[j][3];
                    temp[1] = -1;//其实是模拟字符串操作的手段
                    merge(first[i],temp,1);
                }
                //当右边的第一个是非终结符的时候
                else if(inNonTer(proc[j][3]) == 1)
                {
                    //如果遇到左递归形式的,直接放过?
                    if(proc[j][3] == currentNon)
                    {
                        continue;
                    }
                    //记录下右边第一个非终结符的位置
                    for(k=0;; k++)
                    {
                        if(nonTerMap[k].second == proc[j][3])
                        {
                            break;
                        }
    
                    }
                    //当右边第一个非终结符还未访问过的时候
                    if(firstVisit[k] == 0)
                    {
                        firstSet(k);
                        firstVisit[k] = 1;
                    }
                    merge(first[i],first[k],2);//如果first[k]此时有空值的话,暂时不把空值并入first[i]中
                    int rightLength = 0;
                    //先求出右部的长度
    
                    for(rightLength = 3;; rightLength++)
                    {
                        if(proc[j][rightLength] == -1)
                        {
                            break;
                        }
                    }
                    //到目前为止,只求出了右边的第一个(还不包括空的部分),For循环处理之后的
                    for(k = 3; k<rightLength; k++)
                    {
                        emptyRecu[0] = -1;//相当于初始化这个防递归集合
    
                        //如果右部的当前字符能推出空并且还不是最后一个字符,就将之后的一个字符并入First集中
                        if(reduNull(proc[j][k]) == 1 && k<rightLength -1)
                        {
                            int u = 0;
                            for(u=0;; u++)
                            {
                                //注意是记录下一个符号的位置
                                if(nonTerMap[u].second == proc[j][k+1])
                                {
                                    break;
                                }
                            }
                            if(firstVisit[u] == 0)
                            {
                                firstSet(u);
                                firstVisit[u] = 1;
                            }
                            merge(first[i],first[u],2);
                        }
                        //到达最后一个字符,并且产生式右部都能推出空,将$并入First集中
                        else if(reduNull(proc[j][k]) == 1 && k == rightLength -1)
                        {
                            int temp[2];
                            temp[0] = GRAMMAR_NULL;
                            temp[1] = -1;//其实是模拟字符串操作的手段
                            merge(first[i],temp,1);
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }
        }
        firstVisit[i] = 1;
    }
    void First()
    {
        //先求出能直接推出空的非终结符集合
        nullSet(GRAMMAR_NULL);
        printf("\n");
        for(int i=0; i<nonTerMap.size(); i++)
        {
            firstSet(i);
        }
        printf("\n************************************First集******************************\n\n");
        for(int i=0; i<nonTerMap.size(); i++)
        {
            printf("First[%s] = ",nonTerMap[i].first);
            for(int j=0;; j++)
            {
                if(first[i][j] == -1)
                {
                    break;
                }
                printf("%s ",searchMapping(first[i][j]));
            }
            printf("\n");
        }
    }
    //将First结合起来的函数
    void connectFirstSet(int *p)
    {
        int i = 0;
        int flag = 0;
        int temp[2];
        //如果P的长度为1
        if(p[1] == -1)
        {
            if(p[0] == GRAMMAR_NULL)
            {
                connectFirst[0] = GRAMMAR_NULL;
                connectFirst[1] = -1;
            }
            else
            {
                for(i=0; i<nonTerMap.size(); i++)
                {
                    if(nonTerMap[i].second == p[0])
                    {
                        flag = 1;
                        merge(connectFirst,first[i],1);
                        break;
                    }
                }
                //也可能是终结符
                if(flag == 0)
                {
                    for(i=0; i<terMap.size(); i++)
                    {
                        if(terMap[i].second == p[0])
                        {
                            temp[0] = terMap[i].second;
                            temp[1] = -1;
                            merge(connectFirst,temp,2);//终结符的First集就是其本身
                            break;
                        }
                    }
                }
            }
        }
        //如果p的长度大于1
        else
        {
            for(i=0; i<nonTerMap.size(); i++)
            {
                if(nonTerMap[i].second == p[0])
                {
                    flag = 1;
                    merge(connectFirst,first[i],2);
                    break;
                }
            }
            //也可能是终结符
            if(flag == 0)
            {
                for(i=0; i<terMap.size(); i++)
                {
                    if(terMap[i].second == p[0])
                    {
                        temp[0] = terMap[i].second;
                        temp[1] = -1;
                        merge(connectFirst,temp,2);//终结符的First集就是其本身
                        break;
                    }
                }
            }
            flag = 0;
            int length = 0;
            for(length = 0;; length++)
            {
                if(p[length] == -1)
                {
                    break;
                }
            }
            for(int k=0; k<length; k++)
            {
                emptyRecu[0] = -1;//相当于初始化这个防递归集合
    
                //如果右部的当前字符能推出空并且还不是最后一个字符,就将之后的一个字符并入First集中
                if(reduNull(p[k]) == 1 && k<length -1)
                {
                    int u = 0;
                    for(u=0; u<nonTerMap.size(); u++)
                    {
                        //注意是记录下一个符号的位置
                        if(nonTerMap[u].second == p[k+1])
                        {
                            flag = 1;
                            merge(connectFirst,first[u],2);
                            break;
                        }
                    }
                    //也可能是终结符
                    if(flag == 0)
                    {
                        for(u=0; u<terMap.size(); u++)
                        {
                            //注意是记录下一个符号的位置
                            if(terMap[u].second == p[k+1])
                            {
                                temp[0] = terMap[i].second;
                                temp[1] = -1;
                                merge(connectFirst,temp,2);
                                break;
                            }
                        }
                    }
                    flag = 0;
                }
                //到达最后一个字符,并且产生式右部都能推出空,将$并入First集中
                else if(reduNull(p[k]) == 1 && k == length -1)
                {
                    temp[0] = GRAMMAR_NULL;
                    temp[1] = -1;//其实是模拟字符串操作的手段
                    merge(connectFirst,temp,1);
                }
                else
                {
                    break;
                }
            }
        }
    }
    void followSet(int i)
    {
        int currentNon = nonTerMap[i].second;//当前的非终结符标号
        int temp[2];
        int result = 1;
        temp[0] = currentNon;
        temp[1] = -1;
        merge(followRecu,temp,1);//将当前标号加入防递归集合中
    
        //如果当前符号就是开始符号,把特殊符号加入其Follow集中
        if(proc[1][1] == currentNon)
        {
            temp[0] = GRAMMAR_SPECIAL;//这个也是要处理的
            temp[1] = -1;
            merge(follow[i],temp,1);
        }
        for(int j = 1; j<=procNum; j++) //j代表第几个产生式
        {
            //如果该非终结符在某个产生式的右部存在
            if(inProcRight(currentNon,proc[j]) == 1)
            {
                int rightLength = 1;
                int k = 0;//k为该非终结符在产生式右部的序号
                int flag = 0;
                int leftNum = proc[j][1];//产生式的左边
                int h = 0;
                int kArray[Max_Length2];
                memset(kArray,-1,sizeof(kArray));
                for(h = 0; h < nonTerMap.size(); h++)
                {
                    if(nonTerMap[h].second == leftNum)
                    {
                        break;
                    }
                }
    
                for(rightLength = 1;; rightLength++)
                {
                    if(currentNon == proc[j][rightLength+2])
                    {
                        kArray[k++] = rightLength;
                    }
                    if(proc[j][rightLength+2] == -1)
                    {
                        break;
                    }
                }
                rightLength--;
                for(int y=0;; y++)
                {
                    if(kArray[y] == -1)
                    {
                        break;
                    }
                    //如果该非终结符在右部产生式的最后
                    if(kArray[y] == rightLength)
                    {
    
                        if(inFollowRecu(leftNum) == 1)
                        {
                            merge(follow[i],follow[h],1);
                            continue;
                        }
                        if(followVisit[h] == 0)
                        {
                            followSet(h);
                            followVisit[h] = 1;
                        }
                        merge(follow[i],follow[h],1);
                    }
                    //如果不在最后
                    else
                    {
                        int n = 0;
                        result = 1;//这是关键的,曾在这里失误过
                        for(n=kArray[y]+1; n<=rightLength; n++)
                        {
                            emptyRecu[0] = -1;
                            result *= reduNull(proc[j][n+2]);
                        }
                        if(result == 1)
                        {
                            if(inFollowRecu(leftNum) == 1)
                            {
                                merge(follow[i],follow[h],1);
                                continue;
                            }
                            if(followVisit[h] == 0)
                            {
                                followSet(h);
                                followVisit[h] = 1;
                            }
                            merge(follow[i],follow[h],1);
                        }
                        int temp2[Max_Length];
                        memset(temp2,-1,sizeof(temp2));
                        for(n=kArray[y]+1; n<=rightLength; n++)
                        {
                            temp2[n-kArray[y]-1] = proc[j][n+2];
                        }
                        temp2[rightLength-kArray[y]] = -1;
                        connectFirst[0] = -1;//应该重新初始化一下
                        connectFirstSet(temp2);
                        merge(follow[i],connectFirst,2);
                    }
                }
            }
        }
        followVisit[i] = 1;
    }
    
    //求所有非终结符的Follow集
    void Follow()
    {
        for(int i=0; i<nonTerMap.size(); i++)
        {
            followRecu[0] = -1;
            followSet(i);
        }
        printf("\n************************************Follow集******************************\n\n");
        for(int i=0; i<nonTerMap.size(); i++)
        {
            printf("Follow[%s] = ",nonTerMap[i].first);
            for(int j=0;; j++)
            {
                if(follow[i][j] == -1)
                {
                    break;
                }
                printf("%s ",searchMapping(follow[i][j]));
            }
            printf("\n");
        }
    }
    //求已经分解的产生式对应的Select集,注意Select集中不能含有空($),因而Type=2
    void Select()
    {
        for(int i = 1; i<=procNum; i++) //j代表第几个产生式
        {
            int leftNum = proc[i][1];//产生式的左边
            int h = 0;
            int result = 1;
            for(h = 0; h < nonTerMap.size(); h++)
            {
                if(nonTerMap[h].second == leftNum)
                {
                    break;
                }
            }
    
            int rightLength = 1;
            for(rightLength = 1;; rightLength++)
            {
                if(proc[i][rightLength+2] == -1)
                {
                    break;
                }
            }
            rightLength--;
            //如果右部推出式的长度为1并且是空,select[i-1] = follow[左边]
            if(rightLength == 1 && proc[i][rightLength + 2] == GRAMMAR_NULL)
            {
                merge(select[i-1],follow[h],2);
            }
            //如果右部不是空的时候,select[i-1] = first[右部全部]
            //如果右部能够推出空,select[i-1] = first[右部全部] ^ follow[左边]
            else
            {
                int temp2[Max_Length];
                int n = 0;
                memset(temp2,-1,sizeof(temp2));
                for(n=1; n<=rightLength; n++)
                {
                    temp2[n-1] = proc[i][n+2];
                }
                temp2[rightLength] = -1;
                connectFirst[0] = -1;//应该重新初始化一下
                connectFirstSet(temp2);
                merge(select[i-1],connectFirst,2);
                for(n=1; n<=rightLength; n++)
                {
                    emptyRecu[0] = -1;
                    result *= reduNull(proc[i][n+2]);
                }
                //如果右部能推出空,将follow[左边]并入select[i-1]中
                if(result == 1)
                {
                    merge(select[i-1],follow[h],2);
                }
            }
        }
        printf("\n************************************Select集******************************\n\n");
        for(int i=0; i<procNum; i++)
        {
            printf("Select[%d] = ",i+1);
            for(int j=0;; j++)
            {
                if(select[i][j] == -1)
                {
                    break;
                }
                printf("%s ",searchMapping(select[i][j]));
            }
            printf("\n");
        }
    }
    //输出预测分析表
    void MTable()
    {
        fstream outfile;
        outfile.open("preciateTable.txt",ios::out);
    
        for(int i=0; i<procNum; i++)
        {
            int m = 0;//非终结符的序号
            for(int t=0; t<nonTerMap.size(); t++)
            {
                if(nonTerMap[t].second == proc[i+1][1])
                {
                    m = t;
                    break;
                }
            }
    
            for(int j=0;; j++)
            {
                if(select[i][j] == -1)
                {
                    break;
                }
                for(int k=0; k<terMap.size(); k++)
                {
                    if(terMap[k].second == select[i][j])
                    {
                        int n = 0;
                        for(n=1; n<=Max_Length2; n++)
                        {
                            M[m][k][n-1] = proc[i+1][n];
                            if(proc[i+1][n] == -1)
                            {
                                break;
                            }
                        }
                        break;
                    }
                }
            }
        }
        //printf("\n*********************************预测分析表******************************\n\n");
        outfile<<endl<<"*********************************预测分析表******************************"<<endl;
        for(int i=0; i<nonTerMap.size(); i++)
        {
            for(int j=0; j<terMap.size(); j++)
            {
                outfile<<"M["<<nonTerMap[i].first<<"]["<<terMap[j].first<<"] = ";
                //printf("M[%s][%s] = ",nonTerMap[i].first,terMap[j].first);
                for(int k=0;; k++)
                {
                    if(M[i][j][k] == -1)
                    {
                        break;
                    }
                    outfile<<searchMapping(M[i][j][k]);
                    //printf("%s ",searchMapping(M[i][j][k]));
                }
                outfile<<endl;
                //printf("\n");
            }
            outfile<<endl<<endl;
            //printf("\n\n");
        }
        outfile.close();
    }
    
    void InitStack(SeqStack *S)    /*初始化顺序栈*/
    {
        S->top = -1;
    }
    int Push(SeqStack *S,int x)   /*进栈*/
    {
        if(S->top ==Stack_Size-1)
            return 0;
        S->top++;
        S->elem[S->top]=x;
        return 1;
    }
    int Pop(SeqStack *S)   /*出栈*/
    {
        if(S->top==-1)
            return 0;
        else
        {
            S->top--;
            return 1;
        }
    }
    int GetTop(SeqStack *S,int *x)   /*取栈顶元素*/
    {
        if(S->top==-1)
            return 0;
        else
        {
            *x=S->elem[S->top];
            return 1;
        }
    }
    void ShowStack1(SeqStack *S)   /*显示栈的字符,先输出栈底元素*/
    {
    
        int i;
        for(i=S->top; i>=0; i--)
        {
            //printf("%s ",searchMapping(S->elem[i]));
            resultfile<<searchMapping(S->elem[i])<<" ";
        }
    }
    void ShowStack2(SeqStack *S)   /*显示栈的字符,先输出栈顶元素*/
    {
    
        int i;
        for(i=S->top; i>=0; i--)
        {
            //printf("%s ",searchMapping(S->elem[i]));
            resultfile<<searchMapping(S->elem[i])<<" ";
        }
    }
    //分析源程序
    void Analysis()
    {
        //分析结果输出
    
        resultfile.open("preciateResult.txt",ios::out);
    
        SeqStack s1,s2;
        int c1,c2;
        int i = 0;
        int reserve[Stack_Size];//符号栈反向入栈
        NormalNode * p = normalHead;
        int s1Length = 0;
        memset(reserve,-1,sizeof(reserve));
    
        InitStack(&s1);  /*初始化符号栈和输入串*/
        InitStack(&s2);
        Push(&s1,GRAMMAR_SPECIAL);
        Push(&s1,proc[1][1]);
        Push(&s2,GRAMMAR_SPECIAL);
    
        p = p->next;
        while(p!=NULL)
        {
    
            if(p->type == AUTO || p->type == CONST || p->type == UNSIGNED || p->type == SIGNED
                    || p->type ==STATIC || p->type == VOLATILE )
            {
                reserve[i++] =  DESCRIBE;
                //Push(&s2,DESCRIBE);
            }
            else if(p->type == INT_VAL)
            {
                reserve[i++] =  DIGIT;
                //Push(&s2,DIGIT);
            }
            else if(p->type == CHAR || p->type == DOUBLE || p->type == FLOAT || p->type == INT ||
                    p->type == LONG || p->type == SHORT || p->type == VOID)
            {
                reserve[i++] =  TYPE;
                //Push(&s2,TYPE);
            }
            else if(p->type == STRING_VAL)
            {
                reserve[i++] =  STRING;
                //Push(&s2,STRING);
            }
            else if(p->type == DOU_QUE || p->type == SIN_QUE)
            {
    
            }
            else
            {
                reserve[i++] =  p->type;
                //Push(&s2,p->type);
            }
            p = p->next;
        }
        //求左边栈的长度
        for(s1Length = 0;; s1Length++)
        {
            if(reserve[s1Length] == -1)
            {
                break;
            }
        }
        //反向入栈
        for(i = s1Length; i>0; i--)
        {
            Push(&s2,reserve[i-1]);
        }
    
        for(i=0;; i++)   /*分析*/
        {
            //getch();
            int flag = 0;
            int h1;
            int h2;
            //printf("第%d步:\n",i+1);  /*输出该步的相应信息*/
            resultfile<<"第"<<i + 1<<"步"<<endl;
            //printf("符号栈:");
            resultfile<<"符号栈:";
            ShowStack1(&s1);
            //printf("\n");
            resultfile<<endl;
            //printf("输入栈:");
            resultfile<<"输入栈:";
            ShowStack2(&s2);
            //printf("\n");
            resultfile<<endl;
    
            GetTop(&s1,&c1);   /*取栈顶元素,记为c1,c2*/
            GetTop(&s2,&c2);
            if(c1 == GRAMMAR_SPECIAL && c2 == GRAMMAR_SPECIAL)  /*当符号栈和输入栈都剩余#时,分析成功*/
            {
                //printf("成功!\n");
                resultfile<<"成功!"<<endl;
                break;
            }
            if(c1 == GRAMMAR_SPECIAL && c2!= GRAMMAR_SPECIAL)  /*当符号栈剩余#,而输入串未结束时,分析失败 */
            {
                //printf("失败!\n");
                resultfile<<"失败!"<<endl;
                break;
            }
            if(c1 == c2)/*符号栈的栈顶元素和输入串的栈顶元素相同时,同时弹出*/
            {
                Pop(&s1);
                Pop(&s2);
                flag = 1;
            }
    
            else /*查预测分析表*/
            {
                //记录下非终结符的位置
                for(h1=0; h1<nonTerMap.size(); h1++)
                {
                    if(nonTerMap[h1].second == c1)
                    {
                        break;
                    }
                }
                //记录下终结符的位置
                for(h2=0; h2<terMap.size(); h2++)
                {
                    if(terMap[h2].second == c2)
                    {
                        break;
                    }
                }
                if(M[h1][h2][0] == -1)
                {
                    //printf("Error\n");
                    resultfile<<"Error"<<endl;
                    break;//如果错误的话,直接终止分析
                }
                else
                {
                    int length = 0;
                    //记录下推导式的长度
                    for(length = 0;; length++)
                    {
                        if(M[h1][h2][length] == -1)
                        {
                            break;
                        }
                    }
                    Pop(&s1);
                    //如果不是空的话,反向入栈
                    if(M[h1][h2][2] != GRAMMAR_NULL)
                    {
                        for(int k = length-1; k>=2; k--)
                        {
                            Push(&s1,M[h1][h2][k]);
                        }
                    }
                }
            }
            if(flag == 1)
            {
                //printf("匹配!\n");
                resultfile<<"匹配!"<<endl;
            }
            else
            {
                resultfile<<"所用推出式:";
                //printf("所用推出式:");
                int w = 0;
                //记录下推导式的长度
                for(w = 0;; w++)
                {
                    if(M[h1][h2][w] == -1)
                    {
                        break;
                    }
                    //printf("%s ",searchMapping(M[h1][h2][w]));
                    resultfile<<searchMapping(M[h1][h2][w]);
                }
                //printf("\n\n");
                resultfile<<endl<<endl;
            }
        }
        resultfile.close();
    }
    

    主文件:

    main.cpp

    //main.cpp
    #include <iostream>
    #include <fstream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <iomanip>
    #include "LexAnalysis.h"
    #include "SynAnalysis.h"
    
    int main()
    {
        //词法分析部分
        initKeyMapping();
        initOperMapping();
        initLimitMapping();
        initNode();
        scanner();
        BraMappingError();
        printNodeLink();
    
        printErrorLink();
        printIdentLink();
    
        //语法分析部分
        initGrammer();
        First();
        Follow();
        Select();
        MTable();
        Analysis();
        close();
    	return 0;
    }
    

    测试程序(被分析的C代码):

    int main()
    {
    	int i = 7;
    	int j = 9;
    	int c[20] = 
    
    {2,10,10,19,3,4,5,5,34,6,54,52,34,55,68,10,90,78,56,20};
    	for (i=0;i<20;i++)
    	{
    		for(j=i+1;j<20;j--)
    		{
    			if(j == 19)
    			{
    				c[i] = j;
    			}
    		}
    	}
    	printf("Hello world");
    	return 0;
    }

    分析结果:


    ************************************C语言文法******************************
    
    <函数定义> -> <修饰词闭包> <类型> <变量> ( <参数声明> ) { <函数块> }
    <修饰词闭包> -> <修饰词> <修饰词闭包>
    <修饰词闭包> -> $
    <修饰词> -> describe
    <类型> -> type <取地址>
    <取地址> -> <星号闭包>
    <星号闭包> -> <星号> <星号闭包>
    <星号闭包> -> $
    <星号> -> *
    <变量> -> <标志符> <数组下标>
    <标志符> -> id
    <数组下标> -> [ <因式> ]
    <数组下标> -> $
    <因式> -> ( <表达式> )
    <因式> -> <变量>
    <因式> -> <数字>
    <数字> -> digit
    <表达式> -> <因子> <项>
    <因子> -> <因式> <因式递归>
    <因式递归> -> * <因式> <因式递归>
    <因式递归> -> / <因式> <因式递归>
    <因式递归> -> $
    <项> -> + <因子> <项>
    <项> -> - <因子> <项>
    <项> -> $
    <参数声明> -> <声明> <声明闭包>
    <参数声明> -> $
    <声明> -> <修饰词闭包> <类型> <变量> <赋初值>
    <赋初值> -> = <右值>
    <赋初值> -> $
    <右值> -> <表达式>
    <右值> -> { <多个数据> }
    <多个数据> -> <数字> <数字闭包>
    <数字闭包> -> , <数字> <数字闭包>
    <数字闭包> -> $
    <声明闭包> -> , <声明> <声明闭包>
    <声明闭包> -> $
    <函数块> -> <声明语句闭包> <函数块闭包>
    <声明语句闭包> -> <声明语句> <声明语句闭包>
    <声明语句闭包> -> $
    <声明语句> -> <声明> ;
    <函数块闭包> -> <赋值函数> <函数块闭包>
    <函数块闭包> -> <for循环> <函数块闭包>
    <函数块闭包> -> <条件语句> <函数块闭包>
    <函数块闭包> -> <函数返回> <函数块闭包>
    <函数块闭包> -> $
    <赋值函数> -> <变量> <赋值或函数调用>
    <赋值或函数调用> -> = <右值> ;
    <赋值或函数调用> -> ( <参数列表> ) ;
    <参数列表> -> <参数> <参数闭包>
    <参数闭包> -> , <参数> <参数闭包>
    <参数闭包> -> $
    <参数> -> <标志符>
    <参数> -> <数字>
    <参数> -> <字符串>
    <字符串> -> string
    <for循环> -> for ( <赋值函数> <逻辑表达式> ; <后缀表达式> ) { <函数块> }
    <逻辑表达式> -> <表达式> <逻辑运算符> <表达式>
    <逻辑运算符> -> <
    <逻辑运算符> -> >
    <逻辑运算符> -> ==
    <逻辑运算符> -> !=
    <后缀表达式> -> <变量> <后缀运算符>
    <后缀运算符> -> ++
    <后缀运算符> -> --
    <条件语句> -> if ( <逻辑表达式> ) { <函数块> } <否则语句>
    <否则语句> -> else { <函数块> }
    <否则语句> -> $
    <函数返回> -> return <因式> ;
    
    ************************************文法终结符******************************
    
    ( ) { } describe type * id [ ] digit / + - = , ; string for < > == != ++ -- if e
    lse return
    
    ************************************文法非终结符******************************
    
    <函数定义> <修饰词闭包> <类型> <变量> <参数声明> <函数块> <修饰词> <取地址> <星
    号闭包> <星号> <标志符> <数组下标> <因式> <表达式> <数字> <因子> <项> <因式递归>
     <声明> <声明闭包> <赋初值> <右值> <多个数据> <数字闭包> <声明语句闭包> <函数块
    闭包> <声明语句> <赋值函数> <for循环> <条件语句> <函数返回> <赋值或函数调用> <参
    数列表> <参数> <参数闭包> <字符串> <逻辑表达式> <后缀表达式> <逻辑运算符> <后缀
    运算符> <否则语句>
    
    
    ************************************First集******************************
    
    First[<函数定义>] = describe type
    First[<修饰词闭包>] = describe $
    First[<类型>] = type
    First[<变量>] = id
    First[<参数声明>] = describe type $
    First[<函数块>] = describe type id for if return $
    First[<修饰词>] = describe
    First[<取地址>] = * $
    First[<星号闭包>] = * $
    First[<星号>] = *
    First[<标志符>] = id
    First[<数组下标>] = [ $
    First[<因式>] = ( id digit
    First[<表达式>] = ( id digit
    First[<数字>] = digit
    First[<因子>] = ( id digit
    First[<项>] = + - $
    First[<因式递归>] = * / $
    First[<声明>] = describe type
    First[<声明闭包>] = , $
    First[<赋初值>] = = $
    First[<右值>] = ( id digit {
    First[<多个数据>] = digit
    First[<数字闭包>] = , $
    First[<声明语句闭包>] = describe type $
    First[<函数块闭包>] = id for if return $
    First[<声明语句>] = describe type
    First[<赋值函数>] = id
    First[<for循环>] = for
    First[<条件语句>] = if
    First[<函数返回>] = return
    First[<赋值或函数调用>] = = (
    First[<参数列表>] = id digit string
    First[<参数>] = id digit string
    First[<参数闭包>] = , $
    First[<字符串>] = string
    First[<逻辑表达式>] = ( id digit
    First[<后缀表达式>] = id
    First[<逻辑运算符>] = < > == !=
    First[<后缀运算符>] = ++ --
    First[<否则语句>] = else $
    
    ************************************Follow集******************************
    
    Follow[<函数定义>] = #
    Follow[<修饰词闭包>] = type
    Follow[<类型>] = id
    Follow[<变量>] = ( ] ) , ; < > == != + - * / = ++ --
    Follow[<参数声明>] = )
    Follow[<函数块>] = }
    Follow[<修饰词>] = type describe
    Follow[<取地址>] = id
    Follow[<星号闭包>] = id
    Follow[<星号>] = id *
    Follow[<标志符>] = ( ] ) , ; < > == != + - * / = ++ -- [
    Follow[<数组下标>] = ( ] ) , ; < > == != + - * / = ++ --
    Follow[<因式>] = ] ) , ; < > == != + - * /
    Follow[<表达式>] = ) , ; < > == !=
    Follow[<数字>] = ] ) , ; < > == != + - * / }
    Follow[<因子>] = ) , ; < > == != + -
    Follow[<项>] = ) , ; < > == !=
    Follow[<因式递归>] = ) , ; < > == != + -
    Follow[<声明>] = ) , ;
    Follow[<声明闭包>] = )
    Follow[<赋初值>] = ) , ;
    Follow[<右值>] = ) , ;
    Follow[<多个数据>] = }
    Follow[<数字闭包>] = }
    Follow[<声明语句闭包>] = } id for if return
    Follow[<函数块闭包>] = }
    Follow[<声明语句>] = } id for if return describe type
    Follow[<赋值函数>] = } id for if return ( digit
    Follow[<for循环>] = } id for if return
    Follow[<条件语句>] = } id for if return
    Follow[<函数返回>] = } id for if return
    Follow[<赋值或函数调用>] = } id for if return ( digit
    Follow[<参数列表>] = )
    Follow[<参数>] = ) ,
    Follow[<参数闭包>] = )
    Follow[<字符串>] = ) ,
    Follow[<逻辑表达式>] = ; )
    Follow[<后缀表达式>] = )
    Follow[<逻辑运算符>] = ( id digit
    Follow[<后缀运算符>] = )
    Follow[<否则语句>] = } id for if return
    
    ************************************Select集******************************
    
    Select[1] = describe type
    Select[2] = describe
    Select[3] = type
    Select[4] = describe
    Select[5] = type
    Select[6] = * id
    Select[7] = *
    Select[8] = id
    Select[9] = *
    Select[10] = id
    Select[11] = id
    Select[12] = [
    Select[13] = ( ] ) , ; < > == != + - * / = ++ --
    Select[14] = (
    Select[15] = id
    Select[16] = digit
    Select[17] = digit
    Select[18] = ( id digit
    Select[19] = ( id digit
    Select[20] = *
    Select[21] = /
    Select[22] = ) , ; < > == != + -
    Select[23] = +
    Select[24] = -
    Select[25] = ) , ; < > == !=
    Select[26] = describe type
    Select[27] = )
    Select[28] = describe type
    Select[29] = =
    Select[30] = ) , ;
    Select[31] = ( id digit
    Select[32] = {
    Select[33] = digit
    Select[34] = ,
    Select[35] = }
    Select[36] = ,
    Select[37] = )
    Select[38] = describe type id for if return }
    Select[39] = describe type
    Select[40] = } id for if return
    Select[41] = describe type
    Select[42] = id
    Select[43] = for
    Select[44] = if
    Select[45] = return
    Select[46] = }
    Select[47] = id
    Select[48] = =
    Select[49] = (
    Select[50] = id digit string
    Select[51] = ,
    Select[52] = )
    Select[53] = id
    Select[54] = digit
    Select[55] = string
    Select[56] = string
    Select[57] = for
    Select[58] = ( id digit
    Select[59] = <
    Select[60] = >
    Select[61] = ==
    Select[62] = !=
    Select[63] = id
    Select[64] = ++
    Select[65] = --
    Select[66] = if
    Select[67] = else
    Select[68] = } id for if return
    Select[69] = return
    
    Process returned 0 (0x0)   execution time : 4.317 s
    Press any key to continue.
    

    输出文件内容:

    preciateTable.txt(预测分析表):

    *********************************预测分析表******************************
    M[<函数定义>][(] = 
    M[<函数定义>][)] = 
    M[<函数定义>][{] = 
    M[<函数定义>][}] = 
    M[<函数定义>][describe] = <函数定义>-><修饰词闭包><类型><变量>(<参数声明>){<函数块>}
    M[<函数定义>][type] = <函数定义>-><修饰词闭包><类型><变量>(<参数声明>){<函数块>}
    M[<函数定义>][*] = 
    M[<函数定义>][id] = 
    M[<函数定义>][[] = 
    M[<函数定义>][]] = 
    M[<函数定义>][digit] = 
    M[<函数定义>][/] = 
    M[<函数定义>][+] = 
    M[<函数定义>][-] = 
    M[<函数定义>][=] = 
    M[<函数定义>][,] = 
    M[<函数定义>][;] = 
    M[<函数定义>][string] = 
    M[<函数定义>][for] = 
    M[<函数定义>][<] = 
    M[<函数定义>][>] = 
    M[<函数定义>][==] = 
    M[<函数定义>][!=] = 
    M[<函数定义>][++] = 
    M[<函数定义>][--] = 
    M[<函数定义>][if] = 
    M[<函数定义>][else] = 
    M[<函数定义>][return] = 
    
    
    M[<修饰词闭包>][(] = 
    M[<修饰词闭包>][)] = 
    M[<修饰词闭包>][{] = 
    M[<修饰词闭包>][}] = 
    M[<修饰词闭包>][describe] = <修饰词闭包>-><修饰词><修饰词闭包>
    M[<修饰词闭包>][type] = <修饰词闭包>->$
    M[<修饰词闭包>][*] = 
    M[<修饰词闭包>][id] = 
    M[<修饰词闭包>][[] = 
    M[<修饰词闭包>][]] = 
    M[<修饰词闭包>][digit] = 
    M[<修饰词闭包>][/] = 
    M[<修饰词闭包>][+] = 
    M[<修饰词闭包>][-] = 
    M[<修饰词闭包>][=] = 
    M[<修饰词闭包>][,] = 
    M[<修饰词闭包>][;] = 
    M[<修饰词闭包>][string] = 
    M[<修饰词闭包>][for] = 
    M[<修饰词闭包>][<] = 
    M[<修饰词闭包>][>] = 
    M[<修饰词闭包>][==] = 
    M[<修饰词闭包>][!=] = 
    M[<修饰词闭包>][++] = 
    M[<修饰词闭包>][--] = 
    M[<修饰词闭包>][if] = 
    M[<修饰词闭包>][else] = 
    M[<修饰词闭包>][return] = 
    
    
    M[<类型>][(] = 
    M[<类型>][)] = 
    M[<类型>][{] = 
    M[<类型>][}] = 
    M[<类型>][describe] = 
    M[<类型>][type] = <类型>->type<取地址>
    M[<类型>][*] = 
    M[<类型>][id] = 
    M[<类型>][[] = 
    M[<类型>][]] = 
    M[<类型>][digit] = 
    M[<类型>][/] = 
    M[<类型>][+] = 
    M[<类型>][-] = 
    M[<类型>][=] = 
    M[<类型>][,] = 
    M[<类型>][;] = 
    M[<类型>][string] = 
    M[<类型>][for] = 
    M[<类型>][<] = 
    M[<类型>][>] = 
    M[<类型>][==] = 
    M[<类型>][!=] = 
    M[<类型>][++] = 
    M[<类型>][--] = 
    M[<类型>][if] = 
    M[<类型>][else] = 
    M[<类型>][return] = 
    
    
    M[<变量>][(] = 
    M[<变量>][)] = 
    M[<变量>][{] = 
    M[<变量>][}] = 
    M[<变量>][describe] = 
    M[<变量>][type] = 
    M[<变量>][*] = 
    M[<变量>][id] = <变量>-><标志符><数组下标>
    M[<变量>][[] = 
    M[<变量>][]] = 
    M[<变量>][digit] = 
    M[<变量>][/] = 
    M[<变量>][+] = 
    M[<变量>][-] = 
    M[<变量>][=] = 
    M[<变量>][,] = 
    M[<变量>][;] = 
    M[<变量>][string] = 
    M[<变量>][for] = 
    M[<变量>][<] = 
    M[<变量>][>] = 
    M[<变量>][==] = 
    M[<变量>][!=] = 
    M[<变量>][++] = 
    M[<变量>][--] = 
    M[<变量>][if] = 
    M[<变量>][else] = 
    M[<变量>][return] = 
    
    
    M[<参数声明>][(] = 
    M[<参数声明>][)] = <参数声明>->$
    M[<参数声明>][{] = 
    M[<参数声明>][}] = 
    M[<参数声明>][describe] = <参数声明>-><声明><声明闭包>
    M[<参数声明>][type] = <参数声明>-><声明><声明闭包>
    M[<参数声明>][*] = 
    M[<参数声明>][id] = 
    M[<参数声明>][[] = 
    M[<参数声明>][]] = 
    M[<参数声明>][digit] = 
    M[<参数声明>][/] = 
    M[<参数声明>][+] = 
    M[<参数声明>][-] = 
    M[<参数声明>][=] = 
    M[<参数声明>][,] = 
    M[<参数声明>][;] = 
    M[<参数声明>][string] = 
    M[<参数声明>][for] = 
    M[<参数声明>][<] = 
    M[<参数声明>][>] = 
    M[<参数声明>][==] = 
    M[<参数声明>][!=] = 
    M[<参数声明>][++] = 
    M[<参数声明>][--] = 
    M[<参数声明>][if] = 
    M[<参数声明>][else] = 
    M[<参数声明>][return] = 
    
    
    M[<函数块>][(] = 
    M[<函数块>][)] = 
    M[<函数块>][{] = 
    M[<函数块>][}] = <函数块>-><声明语句闭包><函数块闭包>
    M[<函数块>][describe] = <函数块>-><声明语句闭包><函数块闭包>
    M[<函数块>][type] = <函数块>-><声明语句闭包><函数块闭包>
    M[<函数块>][*] = 
    M[<函数块>][id] = <函数块>-><声明语句闭包><函数块闭包>
    M[<函数块>][[] = 
    M[<函数块>][]] = 
    M[<函数块>][digit] = 
    M[<函数块>][/] = 
    M[<函数块>][+] = 
    M[<函数块>][-] = 
    M[<函数块>][=] = 
    M[<函数块>][,] = 
    M[<函数块>][;] = 
    M[<函数块>][string] = 
    M[<函数块>][for] = <函数块>-><声明语句闭包><函数块闭包>
    M[<函数块>][<] = 
    M[<函数块>][>] = 
    M[<函数块>][==] = 
    M[<函数块>][!=] = 
    M[<函数块>][++] = 
    M[<函数块>][--] = 
    M[<函数块>][if] = <函数块>-><声明语句闭包><函数块闭包>
    M[<函数块>][else] = 
    M[<函数块>][return] = <函数块>-><声明语句闭包><函数块闭包>
    
    
    M[<修饰词>][(] = 
    M[<修饰词>][)] = 
    M[<修饰词>][{] = 
    M[<修饰词>][}] = 
    M[<修饰词>][describe] = <修饰词>->describe
    M[<修饰词>][type] = 
    M[<修饰词>][*] = 
    M[<修饰词>][id] = 
    M[<修饰词>][[] = 
    M[<修饰词>][]] = 
    M[<修饰词>][digit] = 
    M[<修饰词>][/] = 
    M[<修饰词>][+] = 
    M[<修饰词>][-] = 
    M[<修饰词>][=] = 
    M[<修饰词>][,] = 
    M[<修饰词>][;] = 
    M[<修饰词>][string] = 
    M[<修饰词>][for] = 
    M[<修饰词>][<] = 
    M[<修饰词>][>] = 
    M[<修饰词>][==] = 
    M[<修饰词>][!=] = 
    M[<修饰词>][++] = 
    M[<修饰词>][--] = 
    M[<修饰词>][if] = 
    M[<修饰词>][else] = 
    M[<修饰词>][return] = 
    
    
    M[<取地址>][(] = 
    M[<取地址>][)] = 
    M[<取地址>][{] = 
    M[<取地址>][}] = 
    M[<取地址>][describe] = 
    M[<取地址>][type] = 
    M[<取地址>][*] = <取地址>-><星号闭包>
    M[<取地址>][id] = <取地址>-><星号闭包>
    M[<取地址>][[] = 
    M[<取地址>][]] = 
    M[<取地址>][digit] = 
    M[<取地址>][/] = 
    M[<取地址>][+] = 
    M[<取地址>][-] = 
    M[<取地址>][=] = 
    M[<取地址>][,] = 
    M[<取地址>][;] = 
    M[<取地址>][string] = 
    M[<取地址>][for] = 
    M[<取地址>][<] = 
    M[<取地址>][>] = 
    M[<取地址>][==] = 
    M[<取地址>][!=] = 
    M[<取地址>][++] = 
    M[<取地址>][--] = 
    M[<取地址>][if] = 
    M[<取地址>][else] = 
    M[<取地址>][return] = 
    
    
    M[<星号闭包>][(] = 
    M[<星号闭包>][)] = 
    M[<星号闭包>][{] = 
    M[<星号闭包>][}] = 
    M[<星号闭包>][describe] = 
    M[<星号闭包>][type] = 
    M[<星号闭包>][*] = <星号闭包>-><星号><星号闭包>
    M[<星号闭包>][id] = <星号闭包>->$
    M[<星号闭包>][[] = 
    M[<星号闭包>][]] = 
    M[<星号闭包>][digit] = 
    M[<星号闭包>][/] = 
    M[<星号闭包>][+] = 
    M[<星号闭包>][-] = 
    M[<星号闭包>][=] = 
    M[<星号闭包>][,] = 
    M[<星号闭包>][;] = 
    M[<星号闭包>][string] = 
    M[<星号闭包>][for] = 
    M[<星号闭包>][<] = 
    M[<星号闭包>][>] = 
    M[<星号闭包>][==] = 
    M[<星号闭包>][!=] = 
    M[<星号闭包>][++] = 
    M[<星号闭包>][--] = 
    M[<星号闭包>][if] = 
    M[<星号闭包>][else] = 
    M[<星号闭包>][return] = 
    
    
    M[<星号>][(] = 
    M[<星号>][)] = 
    M[<星号>][{] = 
    M[<星号>][}] = 
    M[<星号>][describe] = 
    M[<星号>][type] = 
    M[<星号>][*] = <星号>->*
    M[<星号>][id] = 
    M[<星号>][[] = 
    M[<星号>][]] = 
    M[<星号>][digit] = 
    M[<星号>][/] = 
    M[<星号>][+] = 
    M[<星号>][-] = 
    M[<星号>][=] = 
    M[<星号>][,] = 
    M[<星号>][;] = 
    M[<星号>][string] = 
    M[<星号>][for] = 
    M[<星号>][<] = 
    M[<星号>][>] = 
    M[<星号>][==] = 
    M[<星号>][!=] = 
    M[<星号>][++] = 
    M[<星号>][--] = 
    M[<星号>][if] = 
    M[<星号>][else] = 
    M[<星号>][return] = 
    
    
    M[<标志符>][(] = 
    M[<标志符>][)] = 
    M[<标志符>][{] = 
    M[<标志符>][}] = 
    M[<标志符>][describe] = 
    M[<标志符>][type] = 
    M[<标志符>][*] = 
    M[<标志符>][id] = <标志符>->id
    M[<标志符>][[] = 
    M[<标志符>][]] = 
    M[<标志符>][digit] = 
    M[<标志符>][/] = 
    M[<标志符>][+] = 
    M[<标志符>][-] = 
    M[<标志符>][=] = 
    M[<标志符>][,] = 
    M[<标志符>][;] = 
    M[<标志符>][string] = 
    M[<标志符>][for] = 
    M[<标志符>][<] = 
    M[<标志符>][>] = 
    M[<标志符>][==] = 
    M[<标志符>][!=] = 
    M[<标志符>][++] = 
    M[<标志符>][--] = 
    M[<标志符>][if] = 
    M[<标志符>][else] = 
    M[<标志符>][return] = 
    
    
    M[<数组下标>][(] = <数组下标>->$
    M[<数组下标>][)] = <数组下标>->$
    M[<数组下标>][{] = 
    M[<数组下标>][}] = 
    M[<数组下标>][describe] = 
    M[<数组下标>][type] = 
    M[<数组下标>][*] = <数组下标>->$
    M[<数组下标>][id] = 
    M[<数组下标>][[] = <数组下标>->[<因式>]
    M[<数组下标>][]] = <数组下标>->$
    M[<数组下标>][digit] = 
    M[<数组下标>][/] = <数组下标>->$
    M[<数组下标>][+] = <数组下标>->$
    M[<数组下标>][-] = <数组下标>->$
    M[<数组下标>][=] = <数组下标>->$
    M[<数组下标>][,] = <数组下标>->$
    M[<数组下标>][;] = <数组下标>->$
    M[<数组下标>][string] = 
    M[<数组下标>][for] = 
    M[<数组下标>][<] = <数组下标>->$
    M[<数组下标>][>] = <数组下标>->$
    M[<数组下标>][==] = <数组下标>->$
    M[<数组下标>][!=] = <数组下标>->$
    M[<数组下标>][++] = <数组下标>->$
    M[<数组下标>][--] = <数组下标>->$
    M[<数组下标>][if] = 
    M[<数组下标>][else] = 
    M[<数组下标>][return] = 
    
    
    M[<因式>][(] = <因式>->(<表达式>)
    M[<因式>][)] = 
    M[<因式>][{] = 
    M[<因式>][}] = 
    M[<因式>][describe] = 
    M[<因式>][type] = 
    M[<因式>][*] = 
    M[<因式>][id] = <因式>-><变量>
    M[<因式>][[] = 
    M[<因式>][]] = 
    M[<因式>][digit] = <因式>-><数字>
    M[<因式>][/] = 
    M[<因式>][+] = 
    M[<因式>][-] = 
    M[<因式>][=] = 
    M[<因式>][,] = 
    M[<因式>][;] = 
    M[<因式>][string] = 
    M[<因式>][for] = 
    M[<因式>][<] = 
    M[<因式>][>] = 
    M[<因式>][==] = 
    M[<因式>][!=] = 
    M[<因式>][++] = 
    M[<因式>][--] = 
    M[<因式>][if] = 
    M[<因式>][else] = 
    M[<因式>][return] = 
    
    
    M[<表达式>][(] = <表达式>-><因子><项>
    M[<表达式>][)] = 
    M[<表达式>][{] = 
    M[<表达式>][}] = 
    M[<表达式>][describe] = 
    M[<表达式>][type] = 
    M[<表达式>][*] = 
    M[<表达式>][id] = <表达式>-><因子><项>
    M[<表达式>][[] = 
    M[<表达式>][]] = 
    M[<表达式>][digit] = <表达式>-><因子><项>
    M[<表达式>][/] = 
    M[<表达式>][+] = 
    M[<表达式>][-] = 
    M[<表达式>][=] = 
    M[<表达式>][,] = 
    M[<表达式>][;] = 
    M[<表达式>][string] = 
    M[<表达式>][for] = 
    M[<表达式>][<] = 
    M[<表达式>][>] = 
    M[<表达式>][==] = 
    M[<表达式>][!=] = 
    M[<表达式>][++] = 
    M[<表达式>][--] = 
    M[<表达式>][if] = 
    M[<表达式>][else] = 
    M[<表达式>][return] = 
    
    
    M[<数字>][(] = 
    M[<数字>][)] = 
    M[<数字>][{] = 
    M[<数字>][}] = 
    M[<数字>][describe] = 
    M[<数字>][type] = 
    M[<数字>][*] = 
    M[<数字>][id] = 
    M[<数字>][[] = 
    M[<数字>][]] = 
    M[<数字>][digit] = <数字>->digit
    M[<数字>][/] = 
    M[<数字>][+] = 
    M[<数字>][-] = 
    M[<数字>][=] = 
    M[<数字>][,] = 
    M[<数字>][;] = 
    M[<数字>][string] = 
    M[<数字>][for] = 
    M[<数字>][<] = 
    M[<数字>][>] = 
    M[<数字>][==] = 
    M[<数字>][!=] = 
    M[<数字>][++] = 
    M[<数字>][--] = 
    M[<数字>][if] = 
    M[<数字>][else] = 
    M[<数字>][return] = 
    
    
    M[<因子>][(] = <因子>-><因式><因式递归>
    M[<因子>][)] = 
    M[<因子>][{] = 
    M[<因子>][}] = 
    M[<因子>][describe] = 
    M[<因子>][type] = 
    M[<因子>][*] = 
    M[<因子>][id] = <因子>-><因式><因式递归>
    M[<因子>][[] = 
    M[<因子>][]] = 
    M[<因子>][digit] = <因子>-><因式><因式递归>
    M[<因子>][/] = 
    M[<因子>][+] = 
    M[<因子>][-] = 
    M[<因子>][=] = 
    M[<因子>][,] = 
    M[<因子>][;] = 
    M[<因子>][string] = 
    M[<因子>][for] = 
    M[<因子>][<] = 
    M[<因子>][>] = 
    M[<因子>][==] = 
    M[<因子>][!=] = 
    M[<因子>][++] = 
    M[<因子>][--] = 
    M[<因子>][if] = 
    M[<因子>][else] = 
    M[<因子>][return] = 
    
    
    M[<项>][(] = 
    M[<项>][)] = <项>->$
    M[<项>][{] = 
    M[<项>][}] = 
    M[<项>][describe] = 
    M[<项>][type] = 
    M[<项>][*] = 
    M[<项>][id] = 
    M[<项>][[] = 
    M[<项>][]] = 
    M[<项>][digit] = 
    M[<项>][/] = 
    M[<项>][+] = <项>->+<因子><项>
    M[<项>][-] = <项>->-<因子><项>
    M[<项>][=] = 
    M[<项>][,] = <项>->$
    M[<项>][;] = <项>->$
    M[<项>][string] = 
    M[<项>][for] = 
    M[<项>][<] = <项>->$
    M[<项>][>] = <项>->$
    M[<项>][==] = <项>->$
    M[<项>][!=] = <项>->$
    M[<项>][++] = 
    M[<项>][--] = 
    M[<项>][if] = 
    M[<项>][else] = 
    M[<项>][return] = 
    
    
    M[<因式递归>][(] = 
    M[<因式递归>][)] = <因式递归>->$
    M[<因式递归>][{] = 
    M[<因式递归>][}] = 
    M[<因式递归>][describe] = 
    M[<因式递归>][type] = 
    M[<因式递归>][*] = <因式递归>->*<因式><因式递归>
    M[<因式递归>][id] = 
    M[<因式递归>][[] = 
    M[<因式递归>][]] = 
    M[<因式递归>][digit] = 
    M[<因式递归>][/] = <因式递归>->/<因式><因式递归>
    M[<因式递归>][+] = <因式递归>->$
    M[<因式递归>][-] = <因式递归>->$
    M[<因式递归>][=] = 
    M[<因式递归>][,] = <因式递归>->$
    M[<因式递归>][;] = <因式递归>->$
    M[<因式递归>][string] = 
    M[<因式递归>][for] = 
    M[<因式递归>][<] = <因式递归>->$
    M[<因式递归>][>] = <因式递归>->$
    M[<因式递归>][==] = <因式递归>->$
    M[<因式递归>][!=] = <因式递归>->$
    M[<因式递归>][++] = 
    M[<因式递归>][--] = 
    M[<因式递归>][if] = 
    M[<因式递归>][else] = 
    M[<因式递归>][return] = 
    
    
    M[<声明>][(] = 
    M[<声明>][)] = 
    M[<声明>][{] = 
    M[<声明>][}] = 
    M[<声明>][describe] = <声明>-><修饰词闭包><类型><变量><赋初值>
    M[<声明>][type] = <声明>-><修饰词闭包><类型><变量><赋初值>
    M[<声明>][*] = 
    M[<声明>][id] = 
    M[<声明>][[] = 
    M[<声明>][]] = 
    M[<声明>][digit] = 
    M[<声明>][/] = 
    M[<声明>][+] = 
    M[<声明>][-] = 
    M[<声明>][=] = 
    M[<声明>][,] = 
    M[<声明>][;] = 
    M[<声明>][string] = 
    M[<声明>][for] = 
    M[<声明>][<] = 
    M[<声明>][>] = 
    M[<声明>][==] = 
    M[<声明>][!=] = 
    M[<声明>][++] = 
    M[<声明>][--] = 
    M[<声明>][if] = 
    M[<声明>][else] = 
    M[<声明>][return] = 
    
    
    M[<声明闭包>][(] = 
    M[<声明闭包>][)] = <声明闭包>->$
    M[<声明闭包>][{] = 
    M[<声明闭包>][}] = 
    M[<声明闭包>][describe] = 
    M[<声明闭包>][type] = 
    M[<声明闭包>][*] = 
    M[<声明闭包>][id] = 
    M[<声明闭包>][[] = 
    M[<声明闭包>][]] = 
    M[<声明闭包>][digit] = 
    M[<声明闭包>][/] = 
    M[<声明闭包>][+] = 
    M[<声明闭包>][-] = 
    M[<声明闭包>][=] = 
    M[<声明闭包>][,] = <声明闭包>->,<声明><声明闭包>
    M[<声明闭包>][;] = 
    M[<声明闭包>][string] = 
    M[<声明闭包>][for] = 
    M[<声明闭包>][<] = 
    M[<声明闭包>][>] = 
    M[<声明闭包>][==] = 
    M[<声明闭包>][!=] = 
    M[<声明闭包>][++] = 
    M[<声明闭包>][--] = 
    M[<声明闭包>][if] = 
    M[<声明闭包>][else] = 
    M[<声明闭包>][return] = 
    
    
    M[<赋初值>][(] = 
    M[<赋初值>][)] = <赋初值>->$
    M[<赋初值>][{] = 
    M[<赋初值>][}] = 
    M[<赋初值>][describe] = 
    M[<赋初值>][type] = 
    M[<赋初值>][*] = 
    M[<赋初值>][id] = 
    M[<赋初值>][[] = 
    M[<赋初值>][]] = 
    M[<赋初值>][digit] = 
    M[<赋初值>][/] = 
    M[<赋初值>][+] = 
    M[<赋初值>][-] = 
    M[<赋初值>][=] = <赋初值>->=<右值>
    M[<赋初值>][,] = <赋初值>->$
    M[<赋初值>][;] = <赋初值>->$
    M[<赋初值>][string] = 
    M[<赋初值>][for] = 
    M[<赋初值>][<] = 
    M[<赋初值>][>] = 
    M[<赋初值>][==] = 
    M[<赋初值>][!=] = 
    M[<赋初值>][++] = 
    M[<赋初值>][--] = 
    M[<赋初值>][if] = 
    M[<赋初值>][else] = 
    M[<赋初值>][return] = 
    
    
    M[<右值>][(] = <右值>-><表达式>
    M[<右值>][)] = 
    M[<右值>][{] = <右值>->{<多个数据>}
    M[<右值>][}] = 
    M[<右值>][describe] = 
    M[<右值>][type] = 
    M[<右值>][*] = 
    M[<右值>][id] = <右值>-><表达式>
    M[<右值>][[] = 
    M[<右值>][]] = 
    M[<右值>][digit] = <右值>-><表达式>
    M[<右值>][/] = 
    M[<右值>][+] = 
    M[<右值>][-] = 
    M[<右值>][=] = 
    M[<右值>][,] = 
    M[<右值>][;] = 
    M[<右值>][string] = 
    M[<右值>][for] = 
    M[<右值>][<] = 
    M[<右值>][>] = 
    M[<右值>][==] = 
    M[<右值>][!=] = 
    M[<右值>][++] = 
    M[<右值>][--] = 
    M[<右值>][if] = 
    M[<右值>][else] = 
    M[<右值>][return] = 
    
    
    M[<多个数据>][(] = 
    M[<多个数据>][)] = 
    M[<多个数据>][{] = 
    M[<多个数据>][}] = 
    M[<多个数据>][describe] = 
    M[<多个数据>][type] = 
    M[<多个数据>][*] = 
    M[<多个数据>][id] = 
    M[<多个数据>][[] = 
    M[<多个数据>][]] = 
    M[<多个数据>][digit] = <多个数据>-><数字><数字闭包>
    M[<多个数据>][/] = 
    M[<多个数据>][+] = 
    M[<多个数据>][-] = 
    M[<多个数据>][=] = 
    M[<多个数据>][,] = 
    M[<多个数据>][;] = 
    M[<多个数据>][string] = 
    M[<多个数据>][for] = 
    M[<多个数据>][<] = 
    M[<多个数据>][>] = 
    M[<多个数据>][==] = 
    M[<多个数据>][!=] = 
    M[<多个数据>][++] = 
    M[<多个数据>][--] = 
    M[<多个数据>][if] = 
    M[<多个数据>][else] = 
    M[<多个数据>][return] = 
    
    
    M[<数字闭包>][(] = 
    M[<数字闭包>][)] = 
    M[<数字闭包>][{] = 
    M[<数字闭包>][}] = <数字闭包>->$
    M[<数字闭包>][describe] = 
    M[<数字闭包>][type] = 
    M[<数字闭包>][*] = 
    M[<数字闭包>][id] = 
    M[<数字闭包>][[] = 
    M[<数字闭包>][]] = 
    M[<数字闭包>][digit] = 
    M[<数字闭包>][/] = 
    M[<数字闭包>][+] = 
    M[<数字闭包>][-] = 
    M[<数字闭包>][=] = 
    M[<数字闭包>][,] = <数字闭包>->,<数字><数字闭包>
    M[<数字闭包>][;] = 
    M[<数字闭包>][string] = 
    M[<数字闭包>][for] = 
    M[<数字闭包>][<] = 
    M[<数字闭包>][>] = 
    M[<数字闭包>][==] = 
    M[<数字闭包>][!=] = 
    M[<数字闭包>][++] = 
    M[<数字闭包>][--] = 
    M[<数字闭包>][if] = 
    M[<数字闭包>][else] = 
    M[<数字闭包>][return] = 
    
    
    M[<声明语句闭包>][(] = 
    M[<声明语句闭包>][)] = 
    M[<声明语句闭包>][{] = 
    M[<声明语句闭包>][}] = <声明语句闭包>->$
    M[<声明语句闭包>][describe] = <声明语句闭包>-><声明语句><声明语句闭包>
    M[<声明语句闭包>][type] = <声明语句闭包>-><声明语句><声明语句闭包>
    M[<声明语句闭包>][*] = 
    M[<声明语句闭包>][id] = <声明语句闭包>->$
    M[<声明语句闭包>][[] = 
    M[<声明语句闭包>][]] = 
    M[<声明语句闭包>][digit] = 
    M[<声明语句闭包>][/] = 
    M[<声明语句闭包>][+] = 
    M[<声明语句闭包>][-] = 
    M[<声明语句闭包>][=] = 
    M[<声明语句闭包>][,] = 
    M[<声明语句闭包>][;] = 
    M[<声明语句闭包>][string] = 
    M[<声明语句闭包>][for] = <声明语句闭包>->$
    M[<声明语句闭包>][<] = 
    M[<声明语句闭包>][>] = 
    M[<声明语句闭包>][==] = 
    M[<声明语句闭包>][!=] = 
    M[<声明语句闭包>][++] = 
    M[<声明语句闭包>][--] = 
    M[<声明语句闭包>][if] = <声明语句闭包>->$
    M[<声明语句闭包>][else] = 
    M[<声明语句闭包>][return] = <声明语句闭包>->$
    
    
    M[<函数块闭包>][(] = 
    M[<函数块闭包>][)] = 
    M[<函数块闭包>][{] = 
    M[<函数块闭包>][}] = <函数块闭包>->$
    M[<函数块闭包>][describe] = 
    M[<函数块闭包>][type] = 
    M[<函数块闭包>][*] = 
    M[<函数块闭包>][id] = <函数块闭包>-><赋值函数><函数块闭包>
    M[<函数块闭包>][[] = 
    M[<函数块闭包>][]] = 
    M[<函数块闭包>][digit] = 
    M[<函数块闭包>][/] = 
    M[<函数块闭包>][+] = 
    M[<函数块闭包>][-] = 
    M[<函数块闭包>][=] = 
    M[<函数块闭包>][,] = 
    M[<函数块闭包>][;] = 
    M[<函数块闭包>][string] = 
    M[<函数块闭包>][for] = <函数块闭包>-><for循环><函数块闭包>
    M[<函数块闭包>][<] = 
    M[<函数块闭包>][>] = 
    M[<函数块闭包>][==] = 
    M[<函数块闭包>][!=] = 
    M[<函数块闭包>][++] = 
    M[<函数块闭包>][--] = 
    M[<函数块闭包>][if] = <函数块闭包>-><条件语句><函数块闭包>
    M[<函数块闭包>][else] = 
    M[<函数块闭包>][return] = <函数块闭包>-><函数返回><函数块闭包>
    
    
    M[<声明语句>][(] = 
    M[<声明语句>][)] = 
    M[<声明语句>][{] = 
    M[<声明语句>][}] = 
    M[<声明语句>][describe] = <声明语句>-><声明>;
    M[<声明语句>][type] = <声明语句>-><声明>;
    M[<声明语句>][*] = 
    M[<声明语句>][id] = 
    M[<声明语句>][[] = 
    M[<声明语句>][]] = 
    M[<声明语句>][digit] = 
    M[<声明语句>][/] = 
    M[<声明语句>][+] = 
    M[<声明语句>][-] = 
    M[<声明语句>][=] = 
    M[<声明语句>][,] = 
    M[<声明语句>][;] = 
    M[<声明语句>][string] = 
    M[<声明语句>][for] = 
    M[<声明语句>][<] = 
    M[<声明语句>][>] = 
    M[<声明语句>][==] = 
    M[<声明语句>][!=] = 
    M[<声明语句>][++] = 
    M[<声明语句>][--] = 
    M[<声明语句>][if] = 
    M[<声明语句>][else] = 
    M[<声明语句>][return] = 
    
    
    M[<赋值函数>][(] = 
    M[<赋值函数>][)] = 
    M[<赋值函数>][{] = 
    M[<赋值函数>][}] = 
    M[<赋值函数>][describe] = 
    M[<赋值函数>][type] = 
    M[<赋值函数>][*] = 
    M[<赋值函数>][id] = <赋值函数>-><变量><赋值或函数调用>
    M[<赋值函数>][[] = 
    M[<赋值函数>][]] = 
    M[<赋值函数>][digit] = 
    M[<赋值函数>][/] = 
    M[<赋值函数>][+] = 
    M[<赋值函数>][-] = 
    M[<赋值函数>][=] = 
    M[<赋值函数>][,] = 
    M[<赋值函数>][;] = 
    M[<赋值函数>][string] = 
    M[<赋值函数>][for] = 
    M[<赋值函数>][<] = 
    M[<赋值函数>][>] = 
    M[<赋值函数>][==] = 
    M[<赋值函数>][!=] = 
    M[<赋值函数>][++] = 
    M[<赋值函数>][--] = 
    M[<赋值函数>][if] = 
    M[<赋值函数>][else] = 
    M[<赋值函数>][return] = 
    
    
    M[<for循环>][(] = 
    M[<for循环>][)] = 
    M[<for循环>][{] = 
    M[<for循环>][}] = 
    M[<for循环>][describe] = 
    M[<for循环>][type] = 
    M[<for循环>][*] = 
    M[<for循环>][id] = 
    M[<for循环>][[] = 
    M[<for循环>][]] = 
    M[<for循环>][digit] = 
    M[<for循环>][/] = 
    M[<for循环>][+] = 
    M[<for循环>][-] = 
    M[<for循环>][=] = 
    M[<for循环>][,] = 
    M[<for循环>][;] = 
    M[<for循环>][string] = 
    M[<for循环>][for] = <for循环>->for(<赋值函数><逻辑表达式>;<后缀表达式>){<函数块>}
    M[<for循环>][<] = 
    M[<for循环>][>] = 
    M[<for循环>][==] = 
    M[<for循环>][!=] = 
    M[<for循环>][++] = 
    M[<for循环>][--] = 
    M[<for循环>][if] = 
    M[<for循环>][else] = 
    M[<for循环>][return] = 
    
    
    M[<条件语句>][(] = 
    M[<条件语句>][)] = 
    M[<条件语句>][{] = 
    M[<条件语句>][}] = 
    M[<条件语句>][describe] = 
    M[<条件语句>][type] = 
    M[<条件语句>][*] = 
    M[<条件语句>][id] = 
    M[<条件语句>][[] = 
    M[<条件语句>][]] = 
    M[<条件语句>][digit] = 
    M[<条件语句>][/] = 
    M[<条件语句>][+] = 
    M[<条件语句>][-] = 
    M[<条件语句>][=] = 
    M[<条件语句>][,] = 
    M[<条件语句>][;] = 
    M[<条件语句>][string] = 
    M[<条件语句>][for] = 
    M[<条件语句>][<] = 
    M[<条件语句>][>] = 
    M[<条件语句>][==] = 
    M[<条件语句>][!=] = 
    M[<条件语句>][++] = 
    M[<条件语句>][--] = 
    M[<条件语句>][if] = <条件语句>->if(<逻辑表达式>){<函数块>}<否则语句>
    M[<条件语句>][else] = 
    M[<条件语句>][return] = 
    
    
    M[<函数返回>][(] = 
    M[<函数返回>][)] = 
    M[<函数返回>][{] = 
    M[<函数返回>][}] = 
    M[<函数返回>][describe] = 
    M[<函数返回>][type] = 
    M[<函数返回>][*] = 
    M[<函数返回>][id] = 
    M[<函数返回>][[] = 
    M[<函数返回>][]] = 
    M[<函数返回>][digit] = 
    M[<函数返回>][/] = 
    M[<函数返回>][+] = 
    M[<函数返回>][-] = 
    M[<函数返回>][=] = 
    M[<函数返回>][,] = 
    M[<函数返回>][;] = 
    M[<函数返回>][string] = 
    M[<函数返回>][for] = 
    M[<函数返回>][<] = 
    M[<函数返回>][>] = 
    M[<函数返回>][==] = 
    M[<函数返回>][!=] = 
    M[<函数返回>][++] = 
    M[<函数返回>][--] = 
    M[<函数返回>][if] = 
    M[<函数返回>][else] = 
    M[<函数返回>][return] = <函数返回>->return<因式>;
    
    
    M[<赋值或函数调用>][(] = <赋值或函数调用>->(<参数列表>);
    M[<赋值或函数调用>][)] = 
    M[<赋值或函数调用>][{] = 
    M[<赋值或函数调用>][}] = 
    M[<赋值或函数调用>][describe] = 
    M[<赋值或函数调用>][type] = 
    M[<赋值或函数调用>][*] = 
    M[<赋值或函数调用>][id] = 
    M[<赋值或函数调用>][[] = 
    M[<赋值或函数调用>][]] = 
    M[<赋值或函数调用>][digit] = 
    M[<赋值或函数调用>][/] = 
    M[<赋值或函数调用>][+] = 
    M[<赋值或函数调用>][-] = 
    M[<赋值或函数调用>][=] = <赋值或函数调用>->=<右值>;
    M[<赋值或函数调用>][,] = 
    M[<赋值或函数调用>][;] = 
    M[<赋值或函数调用>][string] = 
    M[<赋值或函数调用>][for] = 
    M[<赋值或函数调用>][<] = 
    M[<赋值或函数调用>][>] = 
    M[<赋值或函数调用>][==] = 
    M[<赋值或函数调用>][!=] = 
    M[<赋值或函数调用>][++] = 
    M[<赋值或函数调用>][--] = 
    M[<赋值或函数调用>][if] = 
    M[<赋值或函数调用>][else] = 
    M[<赋值或函数调用>][return] = 
    
    
    M[<参数列表>][(] = 
    M[<参数列表>][)] = 
    M[<参数列表>][{] = 
    M[<参数列表>][}] = 
    M[<参数列表>][describe] = 
    M[<参数列表>][type] = 
    M[<参数列表>][*] = 
    M[<参数列表>][id] = <参数列表>-><参数><参数闭包>
    M[<参数列表>][[] = 
    M[<参数列表>][]] = 
    M[<参数列表>][digit] = <参数列表>-><参数><参数闭包>
    M[<参数列表>][/] = 
    M[<参数列表>][+] = 
    M[<参数列表>][-] = 
    M[<参数列表>][=] = 
    M[<参数列表>][,] = 
    M[<参数列表>][;] = 
    M[<参数列表>][string] = <参数列表>-><参数><参数闭包>
    M[<参数列表>][for] = 
    M[<参数列表>][<] = 
    M[<参数列表>][>] = 
    M[<参数列表>][==] = 
    M[<参数列表>][!=] = 
    M[<参数列表>][++] = 
    M[<参数列表>][--] = 
    M[<参数列表>][if] = 
    M[<参数列表>][else] = 
    M[<参数列表>][return] = 
    
    
    M[<参数>][(] = 
    M[<参数>][)] = 
    M[<参数>][{] = 
    M[<参数>][}] = 
    M[<参数>][describe] = 
    M[<参数>][type] = 
    M[<参数>][*] = 
    M[<参数>][id] = <参数>-><标志符>
    M[<参数>][[] = 
    M[<参数>][]] = 
    M[<参数>][digit] = <参数>-><数字>
    M[<参数>][/] = 
    M[<参数>][+] = 
    M[<参数>][-] = 
    M[<参数>][=] = 
    M[<参数>][,] = 
    M[<参数>][;] = 
    M[<参数>][string] = <参数>-><字符串>
    M[<参数>][for] = 
    M[<参数>][<] = 
    M[<参数>][>] = 
    M[<参数>][==] = 
    M[<参数>][!=] = 
    M[<参数>][++] = 
    M[<参数>][--] = 
    M[<参数>][if] = 
    M[<参数>][else] = 
    M[<参数>][return] = 
    
    
    M[<参数闭包>][(] = 
    M[<参数闭包>][)] = <参数闭包>->$
    M[<参数闭包>][{] = 
    M[<参数闭包>][}] = 
    M[<参数闭包>][describe] = 
    M[<参数闭包>][type] = 
    M[<参数闭包>][*] = 
    M[<参数闭包>][id] = 
    M[<参数闭包>][[] = 
    M[<参数闭包>][]] = 
    M[<参数闭包>][digit] = 
    M[<参数闭包>][/] = 
    M[<参数闭包>][+] = 
    M[<参数闭包>][-] = 
    M[<参数闭包>][=] = 
    M[<参数闭包>][,] = <参数闭包>->,<参数><参数闭包>
    M[<参数闭包>][;] = 
    M[<参数闭包>][string] = 
    M[<参数闭包>][for] = 
    M[<参数闭包>][<] = 
    M[<参数闭包>][>] = 
    M[<参数闭包>][==] = 
    M[<参数闭包>][!=] = 
    M[<参数闭包>][++] = 
    M[<参数闭包>][--] = 
    M[<参数闭包>][if] = 
    M[<参数闭包>][else] = 
    M[<参数闭包>][return] = 
    
    
    M[<字符串>][(] = 
    M[<字符串>][)] = 
    M[<字符串>][{] = 
    M[<字符串>][}] = 
    M[<字符串>][describe] = 
    M[<字符串>][type] = 
    M[<字符串>][*] = 
    M[<字符串>][id] = 
    M[<字符串>][[] = 
    M[<字符串>][]] = 
    M[<字符串>][digit] = 
    M[<字符串>][/] = 
    M[<字符串>][+] = 
    M[<字符串>][-] = 
    M[<字符串>][=] = 
    M[<字符串>][,] = 
    M[<字符串>][;] = 
    M[<字符串>][string] = <字符串>->string
    M[<字符串>][for] = 
    M[<字符串>][<] = 
    M[<字符串>][>] = 
    M[<字符串>][==] = 
    M[<字符串>][!=] = 
    M[<字符串>][++] = 
    M[<字符串>][--] = 
    M[<字符串>][if] = 
    M[<字符串>][else] = 
    M[<字符串>][return] = 
    
    
    M[<逻辑表达式>][(] = <逻辑表达式>-><表达式><逻辑运算符><表达式>
    M[<逻辑表达式>][)] = 
    M[<逻辑表达式>][{] = 
    M[<逻辑表达式>][}] = 
    M[<逻辑表达式>][describe] = 
    M[<逻辑表达式>][type] = 
    M[<逻辑表达式>][*] = 
    M[<逻辑表达式>][id] = <逻辑表达式>-><表达式><逻辑运算符><表达式>
    M[<逻辑表达式>][[] = 
    M[<逻辑表达式>][]] = 
    M[<逻辑表达式>][digit] = <逻辑表达式>-><表达式><逻辑运算符><表达式>
    M[<逻辑表达式>][/] = 
    M[<逻辑表达式>][+] = 
    M[<逻辑表达式>][-] = 
    M[<逻辑表达式>][=] = 
    M[<逻辑表达式>][,] = 
    M[<逻辑表达式>][;] = 
    M[<逻辑表达式>][string] = 
    M[<逻辑表达式>][for] = 
    M[<逻辑表达式>][<] = 
    M[<逻辑表达式>][>] = 
    M[<逻辑表达式>][==] = 
    M[<逻辑表达式>][!=] = 
    M[<逻辑表达式>][++] = 
    M[<逻辑表达式>][--] = 
    M[<逻辑表达式>][if] = 
    M[<逻辑表达式>][else] = 
    M[<逻辑表达式>][return] = 
    
    
    M[<后缀表达式>][(] = 
    M[<后缀表达式>][)] = 
    M[<后缀表达式>][{] = 
    M[<后缀表达式>][}] = 
    M[<后缀表达式>][describe] = 
    M[<后缀表达式>][type] = 
    M[<后缀表达式>][*] = 
    M[<后缀表达式>][id] = <后缀表达式>-><变量><后缀运算符>
    M[<后缀表达式>][[] = 
    M[<后缀表达式>][]] = 
    M[<后缀表达式>][digit] = 
    M[<后缀表达式>][/] = 
    M[<后缀表达式>][+] = 
    M[<后缀表达式>][-] = 
    M[<后缀表达式>][=] = 
    M[<后缀表达式>][,] = 
    M[<后缀表达式>][;] = 
    M[<后缀表达式>][string] = 
    M[<后缀表达式>][for] = 
    M[<后缀表达式>][<] = 
    M[<后缀表达式>][>] = 
    M[<后缀表达式>][==] = 
    M[<后缀表达式>][!=] = 
    M[<后缀表达式>][++] = 
    M[<后缀表达式>][--] = 
    M[<后缀表达式>][if] = 
    M[<后缀表达式>][else] = 
    M[<后缀表达式>][return] = 
    
    
    M[<逻辑运算符>][(] = 
    M[<逻辑运算符>][)] = 
    M[<逻辑运算符>][{] = 
    M[<逻辑运算符>][}] = 
    M[<逻辑运算符>][describe] = 
    M[<逻辑运算符>][type] = 
    M[<逻辑运算符>][*] = 
    M[<逻辑运算符>][id] = 
    M[<逻辑运算符>][[] = 
    M[<逻辑运算符>][]] = 
    M[<逻辑运算符>][digit] = 
    M[<逻辑运算符>][/] = 
    M[<逻辑运算符>][+] = 
    M[<逻辑运算符>][-] = 
    M[<逻辑运算符>][=] = 
    M[<逻辑运算符>][,] = 
    M[<逻辑运算符>][;] = 
    M[<逻辑运算符>][string] = 
    M[<逻辑运算符>][for] = 
    M[<逻辑运算符>][<] = <逻辑运算符>-><
    M[<逻辑运算符>][>] = <逻辑运算符>->>
    M[<逻辑运算符>][==] = <逻辑运算符>->==
    M[<逻辑运算符>][!=] = <逻辑运算符>->!=
    M[<逻辑运算符>][++] = 
    M[<逻辑运算符>][--] = 
    M[<逻辑运算符>][if] = 
    M[<逻辑运算符>][else] = 
    M[<逻辑运算符>][return] = 
    
    
    M[<后缀运算符>][(] = 
    M[<后缀运算符>][)] = 
    M[<后缀运算符>][{] = 
    M[<后缀运算符>][}] = 
    M[<后缀运算符>][describe] = 
    M[<后缀运算符>][type] = 
    M[<后缀运算符>][*] = 
    M[<后缀运算符>][id] = 
    M[<后缀运算符>][[] = 
    M[<后缀运算符>][]] = 
    M[<后缀运算符>][digit] = 
    M[<后缀运算符>][/] = 
    M[<后缀运算符>][+] = 
    M[<后缀运算符>][-] = 
    M[<后缀运算符>][=] = 
    M[<后缀运算符>][,] = 
    M[<后缀运算符>][;] = 
    M[<后缀运算符>][string] = 
    M[<后缀运算符>][for] = 
    M[<后缀运算符>][<] = 
    M[<后缀运算符>][>] = 
    M[<后缀运算符>][==] = 
    M[<后缀运算符>][!=] = 
    M[<后缀运算符>][++] = <后缀运算符>->++
    M[<后缀运算符>][--] = <后缀运算符>->--
    M[<后缀运算符>][if] = 
    M[<后缀运算符>][else] = 
    M[<后缀运算符>][return] = 
    
    
    M[<否则语句>][(] = 
    M[<否则语句>][)] = 
    M[<否则语句>][{] = 
    M[<否则语句>][}] = <否则语句>->$
    M[<否则语句>][describe] = 
    M[<否则语句>][type] = 
    M[<否则语句>][*] = 
    M[<否则语句>][id] = <否则语句>->$
    M[<否则语句>][[] = 
    M[<否则语句>][]] = 
    M[<否则语句>][digit] = 
    M[<否则语句>][/] = 
    M[<否则语句>][+] = 
    M[<否则语句>][-] = 
    M[<否则语句>][=] = 
    M[<否则语句>][,] = 
    M[<否则语句>][;] = 
    M[<否则语句>][string] = 
    M[<否则语句>][for] = <否则语句>->$
    M[<否则语句>][<] = 
    M[<否则语句>][>] = 
    M[<否则语句>][==] = 
    M[<否则语句>][!=] = 
    M[<否则语句>][++] = 
    M[<否则语句>][--] = 
    M[<否则语句>][if] = <否则语句>->$
    M[<否则语句>][else] = <否则语句>->else{<函数块>}
    M[<否则语句>][return] = <否则语句>->$
    
    

    语法分析表:

    preciateResult.txt:

    第1步
    符号栈:<函数定义> # 
    输入栈:type id ( ) { type id = digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<函数定义>-><修饰词闭包><类型><变量>(<参数声明>){<函数块>}
    
    第2步
    符号栈:<修饰词闭包> <类型> <变量> ( <参数声明> ) { <函数块> } # 
    输入栈:type id ( ) { type id = digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<修饰词闭包>->$
    
    第3步
    符号栈:<类型> <变量> ( <参数声明> ) { <函数块> } # 
    输入栈:type id ( ) { type id = digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<类型>->type<取地址>
    
    第4步
    符号栈:type <取地址> <变量> ( <参数声明> ) { <函数块> } # 
    输入栈:type id ( ) { type id = digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第5步
    符号栈:<取地址> <变量> ( <参数声明> ) { <函数块> } # 
    输入栈:id ( ) { type id = digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<取地址>-><星号闭包>
    
    第6步
    符号栈:<星号闭包> <变量> ( <参数声明> ) { <函数块> } # 
    输入栈:id ( ) { type id = digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<星号闭包>->$
    
    第7步
    符号栈:<变量> ( <参数声明> ) { <函数块> } # 
    输入栈:id ( ) { type id = digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<变量>-><标志符><数组下标>
    
    第8步
    符号栈:<标志符> <数组下标> ( <参数声明> ) { <函数块> } # 
    输入栈:id ( ) { type id = digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<标志符>->id
    
    第9步
    符号栈:id <数组下标> ( <参数声明> ) { <函数块> } # 
    输入栈:id ( ) { type id = digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第10步
    符号栈:<数组下标> ( <参数声明> ) { <函数块> } # 
    输入栈:( ) { type id = digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数组下标>->$
    
    第11步
    符号栈:( <参数声明> ) { <函数块> } # 
    输入栈:( ) { type id = digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第12步
    符号栈:<参数声明> ) { <函数块> } # 
    输入栈:) { type id = digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<参数声明>->$
    
    第13步
    符号栈:) { <函数块> } # 
    输入栈:) { type id = digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第14步
    符号栈:{ <函数块> } # 
    输入栈:{ type id = digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第15步
    符号栈:<函数块> } # 
    输入栈:type id = digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<函数块>-><声明语句闭包><函数块闭包>
    
    第16步
    符号栈:<声明语句闭包> <函数块闭包> } # 
    输入栈:type id = digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<声明语句闭包>-><声明语句><声明语句闭包>
    
    第17步
    符号栈:<声明语句> <声明语句闭包> <函数块闭包> } # 
    输入栈:type id = digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<声明语句>-><声明>;
    
    第18步
    符号栈:<声明> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:type id = digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<声明>-><修饰词闭包><类型><变量><赋初值>
    
    第19步
    符号栈:<修饰词闭包> <类型> <变量> <赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:type id = digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<修饰词闭包>->$
    
    第20步
    符号栈:<类型> <变量> <赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:type id = digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<类型>->type<取地址>
    
    第21步
    符号栈:type <取地址> <变量> <赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:type id = digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第22步
    符号栈:<取地址> <变量> <赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:id = digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<取地址>-><星号闭包>
    
    第23步
    符号栈:<星号闭包> <变量> <赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:id = digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<星号闭包>->$
    
    第24步
    符号栈:<变量> <赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:id = digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<变量>-><标志符><数组下标>
    
    第25步
    符号栈:<标志符> <数组下标> <赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:id = digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<标志符>->id
    
    第26步
    符号栈:id <数组下标> <赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:id = digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第27步
    符号栈:<数组下标> <赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:= digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数组下标>->$
    
    第28步
    符号栈:<赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:= digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<赋初值>->=<右值>
    
    第29步
    符号栈:= <右值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:= digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第30步
    符号栈:<右值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<右值>-><表达式>
    
    第31步
    符号栈:<表达式> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<表达式>-><因子><项>
    
    第32步
    符号栈:<因子> <项> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因子>-><因式><因式递归>
    
    第33步
    符号栈:<因式> <因式递归> <项> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因式>-><数字>
    
    第34步
    符号栈:<数字> <因式递归> <项> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字>->digit
    
    第35步
    符号栈:digit <因式递归> <项> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit ; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第36步
    符号栈:<因式递归> <项> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因式递归>->$
    
    第37步
    符号栈:<项> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<项>->$
    
    第38步
    符号栈:; <声明语句闭包> <函数块闭包> } # 
    输入栈:; type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第39步
    符号栈:<声明语句闭包> <函数块闭包> } # 
    输入栈:type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<声明语句闭包>-><声明语句><声明语句闭包>
    
    第40步
    符号栈:<声明语句> <声明语句闭包> <函数块闭包> } # 
    输入栈:type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<声明语句>-><声明>;
    
    第41步
    符号栈:<声明> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<声明>-><修饰词闭包><类型><变量><赋初值>
    
    第42步
    符号栈:<修饰词闭包> <类型> <变量> <赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<修饰词闭包>->$
    
    第43步
    符号栈:<类型> <变量> <赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<类型>->type<取地址>
    
    第44步
    符号栈:type <取地址> <变量> <赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:type id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第45步
    符号栈:<取地址> <变量> <赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<取地址>-><星号闭包>
    
    第46步
    符号栈:<星号闭包> <变量> <赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<星号闭包>->$
    
    第47步
    符号栈:<变量> <赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<变量>-><标志符><数组下标>
    
    第48步
    符号栈:<标志符> <数组下标> <赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<标志符>->id
    
    第49步
    符号栈:id <数组下标> <赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:id = digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第50步
    符号栈:<数组下标> <赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:= digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数组下标>->$
    
    第51步
    符号栈:<赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:= digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<赋初值>->=<右值>
    
    第52步
    符号栈:= <右值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:= digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第53步
    符号栈:<右值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<右值>-><表达式>
    
    第54步
    符号栈:<表达式> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<表达式>-><因子><项>
    
    第55步
    符号栈:<因子> <项> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因子>-><因式><因式递归>
    
    第56步
    符号栈:<因式> <因式递归> <项> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因式>-><数字>
    
    第57步
    符号栈:<数字> <因式递归> <项> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字>->digit
    
    第58步
    符号栈:digit <因式递归> <项> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit ; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第59步
    符号栈:<因式递归> <项> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因式递归>->$
    
    第60步
    符号栈:<项> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<项>->$
    
    第61步
    符号栈:; <声明语句闭包> <函数块闭包> } # 
    输入栈:; type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第62步
    符号栈:<声明语句闭包> <函数块闭包> } # 
    输入栈:type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<声明语句闭包>-><声明语句><声明语句闭包>
    
    第63步
    符号栈:<声明语句> <声明语句闭包> <函数块闭包> } # 
    输入栈:type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<声明语句>-><声明>;
    
    第64步
    符号栈:<声明> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<声明>-><修饰词闭包><类型><变量><赋初值>
    
    第65步
    符号栈:<修饰词闭包> <类型> <变量> <赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<修饰词闭包>->$
    
    第66步
    符号栈:<类型> <变量> <赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<类型>->type<取地址>
    
    第67步
    符号栈:type <取地址> <变量> <赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:type id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第68步
    符号栈:<取地址> <变量> <赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<取地址>-><星号闭包>
    
    第69步
    符号栈:<星号闭包> <变量> <赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<星号闭包>->$
    
    第70步
    符号栈:<变量> <赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<变量>-><标志符><数组下标>
    
    第71步
    符号栈:<标志符> <数组下标> <赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<标志符>->id
    
    第72步
    符号栈:id <数组下标> <赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:id [ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第73步
    符号栈:<数组下标> <赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:[ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数组下标>->[<因式>]
    
    第74步
    符号栈:[ <因式> ] <赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:[ digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第75步
    符号栈:<因式> ] <赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因式>-><数字>
    
    第76步
    符号栈:<数字> ] <赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字>->digit
    
    第77步
    符号栈:digit ] <赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit ] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第78步
    符号栈:] <赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:] = { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第79步
    符号栈:<赋初值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:= { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<赋初值>->=<右值>
    
    第80步
    符号栈:= <右值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:= { digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第81步
    符号栈:<右值> ; <声明语句闭包> <函数块闭包> } # 
    输入栈:{ digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<右值>->{<多个数据>}
    
    第82步
    符号栈:{ <多个数据> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:{ digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第83步
    符号栈:<多个数据> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<多个数据>-><数字><数字闭包>
    
    第84步
    符号栈:<数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字>->digit
    
    第85步
    符号栈:digit <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第86步
    符号栈:<数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字闭包>->,<数字><数字闭包>
    
    第87步
    符号栈:, <数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第88步
    符号栈:<数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字>->digit
    
    第89步
    符号栈:digit <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第90步
    符号栈:<数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字闭包>->,<数字><数字闭包>
    
    第91步
    符号栈:, <数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第92步
    符号栈:<数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字>->digit
    
    第93步
    符号栈:digit <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第94步
    符号栈:<数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字闭包>->,<数字><数字闭包>
    
    第95步
    符号栈:, <数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第96步
    符号栈:<数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字>->digit
    
    第97步
    符号栈:digit <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第98步
    符号栈:<数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字闭包>->,<数字><数字闭包>
    
    第99步
    符号栈:, <数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第100步
    符号栈:<数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字>->digit
    
    第101步
    符号栈:digit <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第102步
    符号栈:<数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字闭包>->,<数字><数字闭包>
    
    第103步
    符号栈:, <数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第104步
    符号栈:<数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字>->digit
    
    第105步
    符号栈:digit <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第106步
    符号栈:<数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字闭包>->,<数字><数字闭包>
    
    第107步
    符号栈:, <数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第108步
    符号栈:<数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字>->digit
    
    第109步
    符号栈:digit <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第110步
    符号栈:<数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字闭包>->,<数字><数字闭包>
    
    第111步
    符号栈:, <数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第112步
    符号栈:<数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字>->digit
    
    第113步
    符号栈:digit <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第114步
    符号栈:<数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字闭包>->,<数字><数字闭包>
    
    第115步
    符号栈:, <数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第116步
    符号栈:<数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字>->digit
    
    第117步
    符号栈:digit <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第118步
    符号栈:<数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字闭包>->,<数字><数字闭包>
    
    第119步
    符号栈:, <数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第120步
    符号栈:<数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字>->digit
    
    第121步
    符号栈:digit <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第122步
    符号栈:<数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字闭包>->,<数字><数字闭包>
    
    第123步
    符号栈:, <数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第124步
    符号栈:<数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字>->digit
    
    第125步
    符号栈:digit <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第126步
    符号栈:<数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字闭包>->,<数字><数字闭包>
    
    第127步
    符号栈:, <数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第128步
    符号栈:<数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字>->digit
    
    第129步
    符号栈:digit <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第130步
    符号栈:<数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字闭包>->,<数字><数字闭包>
    
    第131步
    符号栈:, <数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第132步
    符号栈:<数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字>->digit
    
    第133步
    符号栈:digit <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第134步
    符号栈:<数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字闭包>->,<数字><数字闭包>
    
    第135步
    符号栈:, <数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第136步
    符号栈:<数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字>->digit
    
    第137步
    符号栈:digit <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第138步
    符号栈:<数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字闭包>->,<数字><数字闭包>
    
    第139步
    符号栈:, <数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第140步
    符号栈:<数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字>->digit
    
    第141步
    符号栈:digit <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第142步
    符号栈:<数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字闭包>->,<数字><数字闭包>
    
    第143步
    符号栈:, <数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第144步
    符号栈:<数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字>->digit
    
    第145步
    符号栈:digit <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第146步
    符号栈:<数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字闭包>->,<数字><数字闭包>
    
    第147步
    符号栈:, <数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第148步
    符号栈:<数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字>->digit
    
    第149步
    符号栈:digit <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第150步
    符号栈:<数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字闭包>->,<数字><数字闭包>
    
    第151步
    符号栈:, <数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第152步
    符号栈:<数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字>->digit
    
    第153步
    符号栈:digit <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第154步
    符号栈:<数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字闭包>->,<数字><数字闭包>
    
    第155步
    符号栈:, <数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第156步
    符号栈:<数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字>->digit
    
    第157步
    符号栈:digit <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit , digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第158步
    符号栈:<数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字闭包>->,<数字><数字闭包>
    
    第159步
    符号栈:, <数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:, digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第160步
    符号栈:<数字> <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字>->digit
    
    第161步
    符号栈:digit <数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:digit } ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第162步
    符号栈:<数字闭包> } ; <声明语句闭包> <函数块闭包> } # 
    输入栈:} ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字闭包>->$
    
    第163步
    符号栈:} ; <声明语句闭包> <函数块闭包> } # 
    输入栈:} ; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第164步
    符号栈:; <声明语句闭包> <函数块闭包> } # 
    输入栈:; for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第165步
    符号栈:<声明语句闭包> <函数块闭包> } # 
    输入栈:for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<声明语句闭包>->$
    
    第166步
    符号栈:<函数块闭包> } # 
    输入栈:for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<函数块闭包>-><for循环><函数块闭包>
    
    第167步
    符号栈:<for循环> <函数块闭包> } # 
    输入栈:for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<for循环>->for(<赋值函数><逻辑表达式>;<后缀表达式>){<函数块>}
    
    第168步
    符号栈:for ( <赋值函数> <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:for ( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第169步
    符号栈:( <赋值函数> <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:( id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第170步
    符号栈:<赋值函数> <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<赋值函数>-><变量><赋值或函数调用>
    
    第171步
    符号栈:<变量> <赋值或函数调用> <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<变量>-><标志符><数组下标>
    
    第172步
    符号栈:<标志符> <数组下标> <赋值或函数调用> <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<标志符>->id
    
    第173步
    符号栈:id <数组下标> <赋值或函数调用> <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:id = digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第174步
    符号栈:<数组下标> <赋值或函数调用> <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:= digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数组下标>->$
    
    第175步
    符号栈:<赋值或函数调用> <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:= digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<赋值或函数调用>->=<右值>;
    
    第176步
    符号栈:= <右值> ; <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:= digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第177步
    符号栈:<右值> ; <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<右值>-><表达式>
    
    第178步
    符号栈:<表达式> ; <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<表达式>-><因子><项>
    
    第179步
    符号栈:<因子> <项> ; <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因子>-><因式><因式递归>
    
    第180步
    符号栈:<因式> <因式递归> <项> ; <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因式>-><数字>
    
    第181步
    符号栈:<数字> <因式递归> <项> ; <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字>->digit
    
    第182步
    符号栈:digit <因式递归> <项> ; <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:digit ; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第183步
    符号栈:<因式递归> <项> ; <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因式递归>->$
    
    第184步
    符号栈:<项> ; <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<项>->$
    
    第185步
    符号栈:; <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:; id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第186步
    符号栈:<逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<逻辑表达式>-><表达式><逻辑运算符><表达式>
    
    第187步
    符号栈:<表达式> <逻辑运算符> <表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<表达式>-><因子><项>
    
    第188步
    符号栈:<因子> <项> <逻辑运算符> <表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因子>-><因式><因式递归>
    
    第189步
    符号栈:<因式> <因式递归> <项> <逻辑运算符> <表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因式>-><变量>
    
    第190步
    符号栈:<变量> <因式递归> <项> <逻辑运算符> <表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<变量>-><标志符><数组下标>
    
    第191步
    符号栈:<标志符> <数组下标> <因式递归> <项> <逻辑运算符> <表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<标志符>->id
    
    第192步
    符号栈:id <数组下标> <因式递归> <项> <逻辑运算符> <表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:id < digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第193步
    符号栈:<数组下标> <因式递归> <项> <逻辑运算符> <表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:< digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数组下标>->$
    
    第194步
    符号栈:<因式递归> <项> <逻辑运算符> <表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:< digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因式递归>->$
    
    第195步
    符号栈:<项> <逻辑运算符> <表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:< digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<项>->$
    
    第196步
    符号栈:<逻辑运算符> <表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:< digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<逻辑运算符>-><
    
    第197步
    符号栈:< <表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:< digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第198步
    符号栈:<表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<表达式>-><因子><项>
    
    第199步
    符号栈:<因子> <项> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因子>-><因式><因式递归>
    
    第200步
    符号栈:<因式> <因式递归> <项> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因式>-><数字>
    
    第201步
    符号栈:<数字> <因式递归> <项> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字>->digit
    
    第202步
    符号栈:digit <因式递归> <项> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:digit ; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第203步
    符号栈:<因式递归> <项> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因式递归>->$
    
    第204步
    符号栈:<项> ; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<项>->$
    
    第205步
    符号栈:; <后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:; id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第206步
    符号栈:<后缀表达式> ) { <函数块> } <函数块闭包> } # 
    输入栈:id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<后缀表达式>-><变量><后缀运算符>
    
    第207步
    符号栈:<变量> <后缀运算符> ) { <函数块> } <函数块闭包> } # 
    输入栈:id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<变量>-><标志符><数组下标>
    
    第208步
    符号栈:<标志符> <数组下标> <后缀运算符> ) { <函数块> } <函数块闭包> } # 
    输入栈:id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<标志符>->id
    
    第209步
    符号栈:id <数组下标> <后缀运算符> ) { <函数块> } <函数块闭包> } # 
    输入栈:id ++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第210步
    符号栈:<数组下标> <后缀运算符> ) { <函数块> } <函数块闭包> } # 
    输入栈:++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数组下标>->$
    
    第211步
    符号栈:<后缀运算符> ) { <函数块> } <函数块闭包> } # 
    输入栈:++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<后缀运算符>->++
    
    第212步
    符号栈:++ ) { <函数块> } <函数块闭包> } # 
    输入栈:++ ) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第213步
    符号栈:) { <函数块> } <函数块闭包> } # 
    输入栈:) { for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第214步
    符号栈:{ <函数块> } <函数块闭包> } # 
    输入栈:{ for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第215步
    符号栈:<函数块> } <函数块闭包> } # 
    输入栈:for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<函数块>-><声明语句闭包><函数块闭包>
    
    第216步
    符号栈:<声明语句闭包> <函数块闭包> } <函数块闭包> } # 
    输入栈:for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<声明语句闭包>->$
    
    第217步
    符号栈:<函数块闭包> } <函数块闭包> } # 
    输入栈:for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<函数块闭包>-><for循环><函数块闭包>
    
    第218步
    符号栈:<for循环> <函数块闭包> } <函数块闭包> } # 
    输入栈:for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<for循环>->for(<赋值函数><逻辑表达式>;<后缀表达式>){<函数块>}
    
    第219步
    符号栈:for ( <赋值函数> <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:for ( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第220步
    符号栈:( <赋值函数> <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:( id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第221步
    符号栈:<赋值函数> <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<赋值函数>-><变量><赋值或函数调用>
    
    第222步
    符号栈:<变量> <赋值或函数调用> <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<变量>-><标志符><数组下标>
    
    第223步
    符号栈:<标志符> <数组下标> <赋值或函数调用> <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<标志符>->id
    
    第224步
    符号栈:id <数组下标> <赋值或函数调用> <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id = id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第225步
    符号栈:<数组下标> <赋值或函数调用> <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:= id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数组下标>->$
    
    第226步
    符号栈:<赋值或函数调用> <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:= id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<赋值或函数调用>->=<右值>;
    
    第227步
    符号栈:= <右值> ; <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:= id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第228步
    符号栈:<右值> ; <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<右值>-><表达式>
    
    第229步
    符号栈:<表达式> ; <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<表达式>-><因子><项>
    
    第230步
    符号栈:<因子> <项> ; <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因子>-><因式><因式递归>
    
    第231步
    符号栈:<因式> <因式递归> <项> ; <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因式>-><变量>
    
    第232步
    符号栈:<变量> <因式递归> <项> ; <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<变量>-><标志符><数组下标>
    
    第233步
    符号栈:<标志符> <数组下标> <因式递归> <项> ; <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<标志符>->id
    
    第234步
    符号栈:id <数组下标> <因式递归> <项> ; <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id + digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第235步
    符号栈:<数组下标> <因式递归> <项> ; <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:+ digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数组下标>->$
    
    第236步
    符号栈:<因式递归> <项> ; <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:+ digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因式递归>->$
    
    第237步
    符号栈:<项> ; <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:+ digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<项>->+<因子><项>
    
    第238步
    符号栈:+ <因子> <项> ; <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:+ digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第239步
    符号栈:<因子> <项> ; <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因子>-><因式><因式递归>
    
    第240步
    符号栈:<因式> <因式递归> <项> ; <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因式>-><数字>
    
    第241步
    符号栈:<数字> <因式递归> <项> ; <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字>->digit
    
    第242步
    符号栈:digit <因式递归> <项> ; <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:digit ; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第243步
    符号栈:<因式递归> <项> ; <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因式递归>->$
    
    第244步
    符号栈:<项> ; <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<项>->$
    
    第245步
    符号栈:; <逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:; id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第246步
    符号栈:<逻辑表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<逻辑表达式>-><表达式><逻辑运算符><表达式>
    
    第247步
    符号栈:<表达式> <逻辑运算符> <表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<表达式>-><因子><项>
    
    第248步
    符号栈:<因子> <项> <逻辑运算符> <表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因子>-><因式><因式递归>
    
    第249步
    符号栈:<因式> <因式递归> <项> <逻辑运算符> <表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因式>-><变量>
    
    第250步
    符号栈:<变量> <因式递归> <项> <逻辑运算符> <表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<变量>-><标志符><数组下标>
    
    第251步
    符号栈:<标志符> <数组下标> <因式递归> <项> <逻辑运算符> <表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<标志符>->id
    
    第252步
    符号栈:id <数组下标> <因式递归> <项> <逻辑运算符> <表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id < digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第253步
    符号栈:<数组下标> <因式递归> <项> <逻辑运算符> <表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:< digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数组下标>->$
    
    第254步
    符号栈:<因式递归> <项> <逻辑运算符> <表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:< digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因式递归>->$
    
    第255步
    符号栈:<项> <逻辑运算符> <表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:< digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<项>->$
    
    第256步
    符号栈:<逻辑运算符> <表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:< digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<逻辑运算符>-><
    
    第257步
    符号栈:< <表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:< digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第258步
    符号栈:<表达式> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<表达式>-><因子><项>
    
    第259步
    符号栈:<因子> <项> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因子>-><因式><因式递归>
    
    第260步
    符号栈:<因式> <因式递归> <项> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因式>-><数字>
    
    第261步
    符号栈:<数字> <因式递归> <项> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字>->digit
    
    第262步
    符号栈:digit <因式递归> <项> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:digit ; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第263步
    符号栈:<因式递归> <项> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因式递归>->$
    
    第264步
    符号栈:<项> ; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<项>->$
    
    第265步
    符号栈:; <后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:; id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第266步
    符号栈:<后缀表达式> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<后缀表达式>-><变量><后缀运算符>
    
    第267步
    符号栈:<变量> <后缀运算符> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<变量>-><标志符><数组下标>
    
    第268步
    符号栈:<标志符> <数组下标> <后缀运算符> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<标志符>->id
    
    第269步
    符号栈:id <数组下标> <后缀运算符> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id -- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第270步
    符号栈:<数组下标> <后缀运算符> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:-- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数组下标>->$
    
    第271步
    符号栈:<后缀运算符> ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:-- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<后缀运算符>->--
    
    第272步
    符号栈:-- ) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:-- ) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第273步
    符号栈:) { <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:) { if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第274步
    符号栈:{ <函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:{ if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第275步
    符号栈:<函数块> } <函数块闭包> } <函数块闭包> } # 
    输入栈:if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<函数块>-><声明语句闭包><函数块闭包>
    
    第276步
    符号栈:<声明语句闭包> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<声明语句闭包>->$
    
    第277步
    符号栈:<函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<函数块闭包>-><条件语句><函数块闭包>
    
    第278步
    符号栈:<条件语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<条件语句>->if(<逻辑表达式>){<函数块>}<否则语句>
    
    第279步
    符号栈:if ( <逻辑表达式> ) { <函数块> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:if ( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第280步
    符号栈:( <逻辑表达式> ) { <函数块> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:( id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第281步
    符号栈:<逻辑表达式> ) { <函数块> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<逻辑表达式>-><表达式><逻辑运算符><表达式>
    
    第282步
    符号栈:<表达式> <逻辑运算符> <表达式> ) { <函数块> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<表达式>-><因子><项>
    
    第283步
    符号栈:<因子> <项> <逻辑运算符> <表达式> ) { <函数块> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因子>-><因式><因式递归>
    
    第284步
    符号栈:<因式> <因式递归> <项> <逻辑运算符> <表达式> ) { <函数块> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因式>-><变量>
    
    第285步
    符号栈:<变量> <因式递归> <项> <逻辑运算符> <表达式> ) { <函数块> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<变量>-><标志符><数组下标>
    
    第286步
    符号栈:<标志符> <数组下标> <因式递归> <项> <逻辑运算符> <表达式> ) { <函数块> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<标志符>->id
    
    第287步
    符号栈:id <数组下标> <因式递归> <项> <逻辑运算符> <表达式> ) { <函数块> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id == digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第288步
    符号栈:<数组下标> <因式递归> <项> <逻辑运算符> <表达式> ) { <函数块> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:== digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数组下标>->$
    
    第289步
    符号栈:<因式递归> <项> <逻辑运算符> <表达式> ) { <函数块> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:== digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因式递归>->$
    
    第290步
    符号栈:<项> <逻辑运算符> <表达式> ) { <函数块> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:== digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<项>->$
    
    第291步
    符号栈:<逻辑运算符> <表达式> ) { <函数块> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:== digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<逻辑运算符>->==
    
    第292步
    符号栈:== <表达式> ) { <函数块> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:== digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第293步
    符号栈:<表达式> ) { <函数块> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<表达式>-><因子><项>
    
    第294步
    符号栈:<因子> <项> ) { <函数块> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因子>-><因式><因式递归>
    
    第295步
    符号栈:<因式> <因式递归> <项> ) { <函数块> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因式>-><数字>
    
    第296步
    符号栈:<数字> <因式递归> <项> ) { <函数块> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数字>->digit
    
    第297步
    符号栈:digit <因式递归> <项> ) { <函数块> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:digit ) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第298步
    符号栈:<因式递归> <项> ) { <函数块> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因式递归>->$
    
    第299步
    符号栈:<项> ) { <函数块> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<项>->$
    
    第300步
    符号栈:) { <函数块> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:) { id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第301步
    符号栈:{ <函数块> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:{ id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第302步
    符号栈:<函数块> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<函数块>-><声明语句闭包><函数块闭包>
    
    第303步
    符号栈:<声明语句闭包> <函数块闭包> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<声明语句闭包>->$
    
    第304步
    符号栈:<函数块闭包> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<函数块闭包>-><赋值函数><函数块闭包>
    
    第305步
    符号栈:<赋值函数> <函数块闭包> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<赋值函数>-><变量><赋值或函数调用>
    
    第306步
    符号栈:<变量> <赋值或函数调用> <函数块闭包> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<变量>-><标志符><数组下标>
    
    第307步
    符号栈:<标志符> <数组下标> <赋值或函数调用> <函数块闭包> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<标志符>->id
    
    第308步
    符号栈:id <数组下标> <赋值或函数调用> <函数块闭包> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id [ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第309步
    符号栈:<数组下标> <赋值或函数调用> <函数块闭包> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:[ id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数组下标>->[<因式>]
    
    第310步
    符号栈:[ <因式> ] <赋值或函数调用> <函数块闭包> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:[ id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第311步
    符号栈:<因式> ] <赋值或函数调用> <函数块闭包> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因式>-><变量>
    
    第312步
    符号栈:<变量> ] <赋值或函数调用> <函数块闭包> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<变量>-><标志符><数组下标>
    
    第313步
    符号栈:<标志符> <数组下标> ] <赋值或函数调用> <函数块闭包> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id ] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<标志符>->id
    
    第314步
    符号栈:id <数组下标> ] <赋值或函数调用> <函数块闭包> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id ] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第315步
    符号栈:<数组下标> ] <赋值或函数调用> <函数块闭包> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:] = id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数组下标>->$
    
    第316步
    符号栈:] <赋值或函数调用> <函数块闭包> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:] = id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第317步
    符号栈:<赋值或函数调用> <函数块闭包> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:= id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<赋值或函数调用>->=<右值>;
    
    第318步
    符号栈:= <右值> ; <函数块闭包> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:= id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第319步
    符号栈:<右值> ; <函数块闭包> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<右值>-><表达式>
    
    第320步
    符号栈:<表达式> ; <函数块闭包> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<表达式>-><因子><项>
    
    第321步
    符号栈:<因子> <项> ; <函数块闭包> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因子>-><因式><因式递归>
    
    第322步
    符号栈:<因式> <因式递归> <项> ; <函数块闭包> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因式>-><变量>
    
    第323步
    符号栈:<变量> <因式递归> <项> ; <函数块闭包> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<变量>-><标志符><数组下标>
    
    第324步
    符号栈:<标志符> <数组下标> <因式递归> <项> ; <函数块闭包> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id ; } } } id ( string ) ; return digit ; } # 
    所用推出式:<标志符>->id
    
    第325步
    符号栈:id <数组下标> <因式递归> <项> ; <函数块闭包> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:id ; } } } id ( string ) ; return digit ; } # 
    匹配!
    第326步
    符号栈:<数组下标> <因式递归> <项> ; <函数块闭包> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:; } } } id ( string ) ; return digit ; } # 
    所用推出式:<数组下标>->$
    
    第327步
    符号栈:<因式递归> <项> ; <函数块闭包> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:; } } } id ( string ) ; return digit ; } # 
    所用推出式:<因式递归>->$
    
    第328步
    符号栈:<项> ; <函数块闭包> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:; } } } id ( string ) ; return digit ; } # 
    所用推出式:<项>->$
    
    第329步
    符号栈:; <函数块闭包> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:; } } } id ( string ) ; return digit ; } # 
    匹配!
    第330步
    符号栈:<函数块闭包> } <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:} } } id ( string ) ; return digit ; } # 
    所用推出式:<函数块闭包>->$
    
    第331步
    符号栈:} <否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:} } } id ( string ) ; return digit ; } # 
    匹配!
    第332步
    符号栈:<否则语句> <函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:} } id ( string ) ; return digit ; } # 
    所用推出式:<否则语句>->$
    
    第333步
    符号栈:<函数块闭包> } <函数块闭包> } <函数块闭包> } # 
    输入栈:} } id ( string ) ; return digit ; } # 
    所用推出式:<函数块闭包>->$
    
    第334步
    符号栈:} <函数块闭包> } <函数块闭包> } # 
    输入栈:} } id ( string ) ; return digit ; } # 
    匹配!
    第335步
    符号栈:<函数块闭包> } <函数块闭包> } # 
    输入栈:} id ( string ) ; return digit ; } # 
    所用推出式:<函数块闭包>->$
    
    第336步
    符号栈:} <函数块闭包> } # 
    输入栈:} id ( string ) ; return digit ; } # 
    匹配!
    第337步
    符号栈:<函数块闭包> } # 
    输入栈:id ( string ) ; return digit ; } # 
    所用推出式:<函数块闭包>-><赋值函数><函数块闭包>
    
    第338步
    符号栈:<赋值函数> <函数块闭包> } # 
    输入栈:id ( string ) ; return digit ; } # 
    所用推出式:<赋值函数>-><变量><赋值或函数调用>
    
    第339步
    符号栈:<变量> <赋值或函数调用> <函数块闭包> } # 
    输入栈:id ( string ) ; return digit ; } # 
    所用推出式:<变量>-><标志符><数组下标>
    
    第340步
    符号栈:<标志符> <数组下标> <赋值或函数调用> <函数块闭包> } # 
    输入栈:id ( string ) ; return digit ; } # 
    所用推出式:<标志符>->id
    
    第341步
    符号栈:id <数组下标> <赋值或函数调用> <函数块闭包> } # 
    输入栈:id ( string ) ; return digit ; } # 
    匹配!
    第342步
    符号栈:<数组下标> <赋值或函数调用> <函数块闭包> } # 
    输入栈:( string ) ; return digit ; } # 
    所用推出式:<数组下标>->$
    
    第343步
    符号栈:<赋值或函数调用> <函数块闭包> } # 
    输入栈:( string ) ; return digit ; } # 
    所用推出式:<赋值或函数调用>->(<参数列表>);
    
    第344步
    符号栈:( <参数列表> ) ; <函数块闭包> } # 
    输入栈:( string ) ; return digit ; } # 
    匹配!
    第345步
    符号栈:<参数列表> ) ; <函数块闭包> } # 
    输入栈:string ) ; return digit ; } # 
    所用推出式:<参数列表>-><参数><参数闭包>
    
    第346步
    符号栈:<参数> <参数闭包> ) ; <函数块闭包> } # 
    输入栈:string ) ; return digit ; } # 
    所用推出式:<参数>-><字符串>
    
    第347步
    符号栈:<字符串> <参数闭包> ) ; <函数块闭包> } # 
    输入栈:string ) ; return digit ; } # 
    所用推出式:<字符串>->string
    
    第348步
    符号栈:string <参数闭包> ) ; <函数块闭包> } # 
    输入栈:string ) ; return digit ; } # 
    匹配!
    第349步
    符号栈:<参数闭包> ) ; <函数块闭包> } # 
    输入栈:) ; return digit ; } # 
    所用推出式:<参数闭包>->$
    
    第350步
    符号栈:) ; <函数块闭包> } # 
    输入栈:) ; return digit ; } # 
    匹配!
    第351步
    符号栈:; <函数块闭包> } # 
    输入栈:; return digit ; } # 
    匹配!
    第352步
    符号栈:<函数块闭包> } # 
    输入栈:return digit ; } # 
    所用推出式:<函数块闭包>-><函数返回><函数块闭包>
    
    第353步
    符号栈:<函数返回> <函数块闭包> } # 
    输入栈:return digit ; } # 
    所用推出式:<函数返回>->return<因式>;
    
    第354步
    符号栈:return <因式> ; <函数块闭包> } # 
    输入栈:return digit ; } # 
    匹配!
    第355步
    符号栈:<因式> ; <函数块闭包> } # 
    输入栈:digit ; } # 
    所用推出式:<因式>-><数字>
    
    第356步
    符号栈:<数字> ; <函数块闭包> } # 
    输入栈:digit ; } # 
    所用推出式:<数字>->digit
    
    第357步
    符号栈:digit ; <函数块闭包> } # 
    输入栈:digit ; } # 
    匹配!
    第358步
    符号栈:; <函数块闭包> } # 
    输入栈:; } # 
    匹配!
    第359步
    符号栈:<函数块闭包> } # 
    输入栈:} # 
    所用推出式:<函数块闭包>->$
    
    第360步
    符号栈:} # 
    输入栈:} # 
    匹配!
    第361步
    符号栈:# 
    输入栈:# 
    成功!
    




    展开全文
  •  从第3章开始,我们进入UCC编译器的语法分析阶段。相关的代码主要在ucl\decl.c、ucl\expr.c和ucl\stmt.c,分别对应声明Declaration、表达式Expression和语句Statement。在第一章时,我们已经通过一个简单的例子ucc\...

    3.1  C语言的表达式

        从第3章开始,我们进入UCC编译器的语法分析阶段。相关的代码主要在ucl\decl.c、ucl\expr.c和ucl\stmt.c,分别对应声明Declaration、表达式Expression和语句Statement。在第一章时,我们已经通过一个简单的例子ucc\examples\sc对这些概念有了一个直观的体会,在这一章中,我们需要结合IT大佬们制定的C标准文法来进行语法分析。基本的分析方法和第1章的例子类似,只是所涉及到的文法更加复杂,所构建的语法树也更加庞大。《K&R》的附录”A.13Grammar”一节给出了完整的C89标准文法,可把这一节不到6页的C文法打印出来,对照着UCC的源代码来看。在本章中,我们要完成的任务很明确,就是把C源代码转换成更加适合编译器处理的语法树。我们需要先熟悉一下语法树上最基本的结点,如图3.1.1所示。


    图3.1.1   struct astNode

        图中第34行的结构体struct astNode就是语法树中一个最基本的结点,第30行的kind用于记录结点的类别,其取值范围由第6至第23行的枚举常量来确定,第8至14行的NK_Function等枚举常量主要用于标识语法树中与“声明Declaration”相关的结点,而第16行的NK_Expression就用于标识“表达式Expression”结点,第18至22行的NK_IfStatement等主要用于与“语句Statement”相关的结点。第31行的next域用于构成链表。第32行的coord主要用于记录与语法树结点对应的C源代码的位置。结构体struct astNode相当于是所有语法树结点的父类,如果要描述表达式对应的结点,我们需要引入能记录更多信息的结构体struct  astExpression,如图3.1.2所示。


    图3.1.2   struct astExpression

          图3.1.2第44行的ty用于记录表达式对应的类型,我们在2.4节中初步介绍过C语言的类型系统。第45行的op是operator的缩写,用于记录表达式的运算符,而第52行的kids则用于记录表达式的运算数。第46行的isarray用于标记当前结点是否为数组,本来第44行的ty域就已记录了结点的类型信息,但是因为数组名在C语言中会被当作“指向数组第0个元素的指针”,此时在ty域中记录的类型已转变为指针类型,所以需要isarray来标记这个结点原本是个数组。第48行的lvalue则是left value的缩写,代表对应的表达式是否为左值。而第49行的bitfld用来标记当前结点是否为结构体对象的位域成员,对位域成员的访问比较特殊,需要进行移位操作。有了这个基础后,我们就可以来看一下ucl\expr.c中对表达式Expression的语法分析了,如图3.1.3所示。


    图3.1.3 ParseExpression()

         图3.1.3第514至516行注释中的产生式告诉我们,C语言的表达式Expression由若干个被逗号隔开的赋值表达式AssignmentExpression构成。我们以下面”a,b,c”这个简单的表达式来说明一下由函数ParseExpression()所构成的语法树,如图3.1.4所示。


    图3.1.4   表达式“a,b,c”对应的语法树

          图3.1.4中op类别为OP_COMMA的结点是通过图3.1.3的第525至530行构建的,第525行的宏CREATE_AST_NODE()创建了一个kind为NK_Expression的结点,接下来的代码用于对该结点进行赋值。子表达式”a”对应的语法树结点会在第522行被构建,而子表达式”b”和子表达式”c”则会通过第530行的ParseAssignmentExpression()函数来构建,如图3.1.5所示。


    图3.1.5 ParseAssignmentExpression()

          图3.1.5第466至468行的注释告诉我们,赋值表达式AssignmentExpression由条件表达式ConditionalExpression或者由”UnaryExpressionAssignmentOpeator AssignmentExpression”构成,UnaryExpression是由一元运算符构成的表达式,第470行的注释列出了”+=”等被称为赋值运算符AssignmentOperator的符号。而UnaryExpression只是ConditionalExpression的一个特例,这就给语法分析带来了难题。在图3.1.5的第481行处,我们实际上有两个侯选式可用,我们没有办法根据当前读头下的token来决定是按UnaryExpression()还是按ConditionalExpression()进行分析。这需要向前扫描多个token之后,如果遇到了形如”a?b:c”这样的条件表达式中的问号”?”时,我们才能确定我们要遇到的原来是条件表达式。UCC采取的策略是通过修改文法来简化语法分析工作,图3.1.5中的代码实际上是按以下文法进行的语法分析的。

    assignment-expression:

          conditional-expression

          conditional-expression assignment-operator  assignment-expression

        当然,修改后的文法所对应的语言就发生了变化,正如第478和479行的注释所言。按修改后的文法进行构建的语法分析器是不够准确的。例如,按照C标准文法,以下代码在语法上就是非法的。但UCC编译器修改了赋值表达式AssignmentExpression的文法后,会导致” (a?b:c)= d”被当作符合文法的赋值表达式。所以在语法分析阶段,UCC编译器并没有报错。

    // hello.c

    int a,b,c,d;

    int main(){

             (a?b:c) = d;

             return 0;

    }

        不过,这个错误可在UCC编译器进行语义检查时被发现。如下所示,错误提示告诉我们,UCC编译器是在exprchk.c这个UCC源代码文件的第1196行检测到这个错误的。文件名exprchk.c告诉我们,这文件中的代码是用来对表达式expression进行语义检查(check)的。

    iron@ubuntu:demo$ ucc hello.c -o hello

    (exprchk.c,1196):(hello.c,4):error:The left operand cannot bemodified

        通过图3.1.5中的函数ParseAssignmentExpression(),我们可以为赋值表达式”a=b=c”构建一棵如图3.1.6所示的语法树。因为ParseAssignmentExpression()是个递归的函数,所以”a=b=c”的子表达式”a”、”b”和”c”对应的语法树结点,都是由图3.1.5第481行的函数调用ParseConditionalExpression()进行构造。而图中op类型为OP_ASSIGN的结点则由第500行的CREATE_AST_NODE()所创建,接下来的第502至505行则完成该结点的初始化。


    图3.1.6  “a=b=c”对应的语法树

        接下来,我们就来看一下ParseConditionalExpression()函数的代码,该函数完成了条件表达式的分析,如图3.1.7所示。


    图3.1.7 ParseConditionalExpression()

          图3.1.7第433至435行给出了条件表达式的产生式,C语言中有许多不同的二元运算符,在第1.3节时,我们就发现了不同的二元运算符表达式对应的语法分析函数除了运算符有所区别外,基本的分析套路几乎是一样的。UCC编译器为了避免冗余的代码,统一采用ParseBinaryExpression()来处理不同的二元运算符表达式,如图3.1.7第441行所示,函数调用时的参数Prec[OP_OR]指明了“逻辑或||”运算符的优先级。图3.1.8给出了经由上述代码为表达式”a?b:c”所构建的语法树。图3.17第441行的ParseBinaryExpression()函数调用创建了”a”对应的结点,而第444至450行则构造了图3.1.8中op域为OP_QUESTION的结点,第452行至457行构建了op域为OP_COLON的结点为,子表达式”b”由第455行的ParseExpression()所创建,而子表达式”c”则由第457行的ParseConditionalExpression()所创建。


    图3.1.8  “a?b:c”对应的语法树

         紧接着,让我们来看看C标准文法中的二元运算符表达式,如图3.1.9所示。图中越早出现的运算符,其运算符优先级越低,例如,”||”运算符是优先有最低的,其次是”&&”。例如,LogicalOrExpression实际上代表的是由若干个LogicalAndExpression进行”||”运算构成的表达式;而LogicalAndExpression代表是由若干个InclusiveOrExpresion进行”&&”运算构成的表达式。要得到LogicalOrExpression,就要先得到LogicalAndExpression。这意味着运算符”&&”的优先级要比”||”更高。C标准文法中为了表达不同二元运算符的优先级,定义了形如图3.1.9这样的模式几乎一样的但有层次结构的产生式。处于同一层次的运算符,其优先级是一样的,例如图中的”==”和”!=”。


    图3.1.9 二元运算符表达式

         语法分析时,也可以为图3.1.9中的每个非结符符编写一个分析函数,但很快我们就会发现,这些分析函数几乎雷同。此时,我们抽取这些不同函数的共性,把它们写到同一个函数ParseBinaryExpression()中,它们的个性则通过函数的参数来进行区别。如果我们定义”逻辑或||”运算的优先级为4,则优先级更高的”逻辑与&&”运算的优先级为5,值越大,表示优先级越高。如果我们把图3.1.9中的LogicalOrExpression用E4来表示,而LogicalAndExpression用E5来表示,优先级为4的二元运算符记为BOP4,则图3.1.9中和非终结符LogicalOrExpression相关的产生式可简写以下形式:

             E4:            

    E5    

                      E4     BOP4                  E5

          同理,我们可以写出跟E5相关的产生式,一般地,我们可以写出优先级为n的二元运算符BOPn所对应的产生式,如下所示。这些产生式全部是采用左递归的形式,暗示着其中的二元运算符是左结合的。

             En:

                       En+1

                       En     BOPn                  En+1

         当然,C语言的二元运算符个数是有限的,由C的标准文法,当n为13时,En+1即E14就不再是二元运算符表达式了,而是一个被称为CastExpression的表达式了,不过UCC的原作者对CastExpression的产生式进行了变换,最终这个E14表达式就被当作UnaryExpression来处理了。最终我们面对的不同优先级的二元表达式可表示为:

             E4:            

    E5    

                      E4     BOP4                  E5

             E5:            

    E6    

                      E5     BOP5                  E6

             …….

             E13:           

    UnaryExpression     

                      E13    BOP13                 UnaryExpression

             结合这些产生式,我们可以写出形如图3.1.10的分析函数。


    图3.1.10 ParseBinaryExpression()版本1

         图3.1.10第2行的函数参数prec表示当前正在分析的二元表达式的运算符优先级,对应上述递推公式En的下标n。第3行的宏HIGHEST_BIN_PREC定义了优先级最高的二元运算符所对应的优先级,在二元运算符中,乘法的优先级最高,所以Prec[OP_MUL]即为13。当调用ParseBinaryExpression(n)时,表示我们要分析En对应的表达式。而表达式En由若干个En+1表达式进行BOPn运算构成,可用如下集合来表示。

             En = {En+1 En+1 BOPn En+1,  En+1 BOPn En+1BOPn En+1 ,   }

         图3.1.10的第7至11行完成了En+1表达式的分析,第12行判断一下当前的token是否为二元运算符BOPn,第13至16行创建了一个运算符结点,而第17至21行实现了En+1表达式的分析,接着我们再通过第12行的while循环判断一下是否还有二元运算符BOPn

         这个版本的ParseBinaryExpression()已经把左结合的二元运算符进行统一处理了,但其效率还可进一步改进。实际上,由E13生成的表达式总是以UnarayExpression开始的,而E12又是由若干个E13进行BOP12运算构成,如果把E13代入E12,则E12也总是以UnaryExpresion开始。以此类推,可以发现由En生成的表达式总是以UnarayExpression开始的。按照这样的思路,UCC原作者给出了一个更高效率的ParseBinaryExpression()函数,如图3.1.11所示。

            

             图3.1.11 ParseBinaryExpression()版本2

         如果我们要调用ParseBinaryExpression(4)来对E4进行分析,但是此时实际上遇到的表达式可能只是”UnaryExpression1 BOP10 UnaryExpression2BOP4 UnaryExpression3”。因为由En生成的表达式总是以UnarayExpression开始,所以图3.1.11第8行我们直接调用ParseUnaryExpression()来识别UnaryExpression1,接下来我们遇到的是BOP10,根据En的递推公式,在BOPn之后的应是En+1,我们期望接下来的表达式是E11,所以在图3.1.11的第11行我们用newPrec记下优先级10,而此时局部变量prec为4,第19行的代码则调用ParseBinaryExpression(newPrec+1)来识别E11。在递归调用ParseBinaryExpression(11)中,我们又会在第8行识别UnaryExpression2,此时局部变量prec为11,而当前遇到的token为BOP4所以第11行的判断条件不成立,我们从ParseBinaryExpression(11)函数中返回,会回到ParseBinaryExpression(4)中,对ParseBinaryExpression(4)这个函数而言,其局部变量prec仍然为4,面对读头下的BOP4,此时newPrec为4,则第11行的判断条件再次成立,我们期望紧跟在BOP4后面的表达式是E5。第19行的ParseBinaryExpression(5)函数调用则完成了UnaryExpression3的识别。图3.1.12给出了”a+b+c”所对应的语法树。


    图3.1.12          a+b+c对应的语法树

             我们会在下一小节对ParseUnaryExpression()进行分析。

    展开全文
  • c语言实现一个简单的语法分析器

    万次阅读 多人点赞 2016-06-03 19:31:58
    简单来讲,语法分析器要实现的功能就是分析一个程序段是否是合法的,依据就是文法;我们依旧采取词法分析器的littleP文法来分析。大型的语法分析器,都是会提示多处错误,我就只实现了遇到一处错误就报错的策略,...
  • 基于c语言语法分析器的实现

    千次阅读 2016-10-20 09:53:03
    一. 总体实现思想 我采用自顶向下的预测...具体的非递归的预测语法分析结构如下所示: 非递归的预测分析不需要为每个非终结符编写递归下降过程,而是根据预测分析表构造一个自动机,也叫表驱动的预测分析 表驱动
  • 3.3 C语言的外部声明_ExternalDeclaration  在分析完表达式和语句之后,《K&R》附录中关于标准C的6页文法,我们就已经差不多已经理解了一半,另外的3页文法基本上都是关于声明Declaration的,与声明相关的代码在...
  • 编译原理课程设计报告 课题名称 编译原理课程设计 C-语言词法与语法分析器的实现 C-词法与语法分析器的实现 1.课程设计目标 1题目实用性 C-语言拥有一个完整语言的基本属性通过编写C-语言的词法分析和语法分析对于...
  • 在上一小节中,我们讨论了C标准文法中与声明Declaration有关的几个非终结符。在此基础上,接下来让我们看看ucl\...函数ParseCommonHeader()分析了“声明说明符”和“声明符”, 图3.3.10 ParseCommonHeader()  图3.
  • 实验一:词法分析器 词法分析器的思路: 1.首先是对关键词的识别 可以做一个数组存放关键词的所有单词,例如下列程序的 char *rwtab[6]={"begin","if","then","while","do","end"}; 2.然后是主程序的逻辑: * 循环...
  • 语法分析器

    2011-12-29 19:37:36
    实验目的:熟悉递归下降语法分析器设计 实验内容: 1.设计递归下降语法分析器算法; 2.编写代码并上机调试运行通过。 实验要求:( 用C语言或C++环境设计并实现) 1.输入——表达式; 2.输出——表达式语法是否...
  • Bison语法分析器-2

    2020-05-05 10:14:20
    建议只做参考使用,请勿抄袭 利用附录提供的C语言文法的相关参考资料,...利用语法分析器生成工具 Bison 编写一个语法分析程序,与词法分析器结合,能够根据语言的上下文无关文法,识别输入的单词序列是否文法的句子。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 32,165
精华内容 12,866
关键字:

语法分析器c语言编写

c语言 订阅