语法分析器_语法分析器的作用 - CSDN
精华内容
参与话题
  • C++写的一个简单的语法分析器(分析C语言)

    万次阅读 多人点赞 2012-11-23 15:36:26
    本程序实现一个分析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步
    符号栈:# 
    输入栈:# 
    成功!
    




    展开全文
  • 利用C语言编制递归下降分析程序,并对简单语言进行语法分析。 2.1 待分析的简单语言的语法 用扩充的BNF表示如下: ⑴<程序>::=begin<语句串>end ⑵<语句串>::=<语句>{;<语句>...

    一、实验目的

    编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。

    二、实验内容

    利用C语言编制递归下降分析程序,并对简单语言进行语法分析。

    2.1 待分析的简单语言的语法

    用扩充的BNF表示如下:

    ⑴<程序>::=begin<语句串>end

    ⑵<语句串>::=<语句>{;<语句>}

    ⑶<语句>::=<赋值语句>

    ⑷<赋值语句>::=ID:=<表达式>

    ⑸<表达式>::=<项>{+<项> | -<项>}

    ⑹<项>::=<因子>{*<因子> | /<因子>}

    ⑺<因子>::=ID | NUM | (<表达式>)

    2.2 实验要求说明

    输入单词串,以“#”结束,如果是文法正确的句子,则输出成功信息,打印“success”,否则输出“error”。

    例如:

        输入  begin a:=9; x:=2*3; b:=a+x end #

        输出  success!

        输入  x:=a+b*c end #

        输出  error!

     

     

    代码如下:

    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    using namespace std;
    //定义几个全局变量 
    int syn;
    char s[1000];
    int p=0;
    int k=0;// 定义 k 作为一个标记符,记录是否出错,若 k=0 ,则说明没有出错,否则发生错误 
    char key[6][20] = {"begin","if","then","while","do","end"};//定义一个二维数组存放关键字 
    char token[20];	//存放字符(单词) 
    void expression();
    //判断关键字 
    int isKey(char s[])
    {
    	for(int i = 0; i < 6;i++)
    	{
    		if(strcmp(s,key[i]) == 0)
    		{
    			return i+1;	//关键字的种别码依次为 begin=1,if=2,then=3,while=4,do=5,end=6即为 i+1 的值 
    		}
    	}
    	return -1;
    }
    //判断是不是字母 
    bool isChar(char ch)
    {
    	if((ch>='a' && ch<='z') || (ch>='A' && ch<='Z'))
    	return true;
    	else
    	return false;
    }
    //判断是不是数字 
    bool isNum(char ch)
    {
    	if(ch>='0' && ch<='9')
    	return true;
    	else
    	return false;
    }
    //词法分析器 
    void scanner()
    {
    	int count = 0;
    	if(s[p] == ' ') p++;
    	//开头是字母
    	if(isChar(s[p]))
    	{
    		while(isNum(s[p]) || isChar(s[p]))
    		{
    			token[count++] = s[p];
    			p++;
    		}
    		token[count] = '\0';	//'\0'作为结束符 ,将单词分隔开 
    		syn = isKey(token);
    		if(syn == -1)	
    		{
    			syn = 10;	//标识符letter(letter|digit) *
    		}
    	}
    	
    	//开头是数字
    	else if(isNum(s[p]))
    	{
    		while(isNum(s[p]))
    		{
    			token[count++] = s[p];
    			p++;
    		}
    		token[count] = '\0';//结束标识 
    		syn = 11;	//数字digit(digit) *
    	}
    	
    	//如果是运算符或者界符
    	else
    	{
    		//先处理没有争议的字符 
    		switch(s[p])
    		{
    			case '+': syn = 13;token[0] = s[p];token[1]='\0';break;
    			case '-': syn = 14;token[0] = s[p];token[1]='\0';break;
    			case '*': syn = 15;token[0] = s[p];token[1]='\0';break;
    			case '/': syn = 16;token[0] = s[p];token[1]='\0';break;
    			case '=': syn = 25;token[0] = s[p];token[1]='\0';break;
    			case ';': syn = 26;token[0] = s[p];token[1]='\0';break;
    			case '(': syn = 27;token[0] = s[p];token[1]='\0';break;
    			case ')': syn = 28;token[0] = s[p];token[1]='\0';break;
    			case '#': syn = 0 ;token[0] = s[p];token[1]='\0';break;
    		}
    		
    		
    		//处理有争议的
    		//: :=
    		if(s[p] == ':')
    		{
    			token[count++] = s[p];
    			if(s[p+1] == '=')
    			{
    				p++;
    				token[count++] = s[p];
    				syn = 18;
    			}
    			else
    			{
    				syn = 17;
    			}
    			token[count] = '\0';
    		}
    		
    		//< <> <=
    		if(s[p] == '<')
    		{
    			token[count++] = s[p];
    			if(s[p+1] == '>')
    			{
    				p++;
    				token[count++] = s[p];
    				syn = 21;
    			}
    			else if(s[p+1] == '=')
    			{
    				p++;
    				token[count++] = s[p];
    				syn = 22;
    			}
    			else
    			{
    				syn = 20;
    			}
    			token[count] = '\0';
    		}
    		
    		//> >=
    		if(s[p] == '>')
    		{
    			token[count++] = s[p];
    			if(s[p+1] == '=')
    			{
    				p++;
    				token[count++] = s[p];
    				syn = 24;
    			}
    			else
    			{
    				syn = 23;
    			}
    			token[count] = '\0';
    		}
    		
    		//后移 
    		p++;	//判断运算符和界符的这部分由于指针 p 没有向后指,所以需要将指针 p 向后移一位 
    	}
    	 
    } 
    
    以下各函数均要先调用 scanner()函数,用于首先产生 syn 的值 
    //因子-->项-->表达式-->赋值语句-->语句-->程序
    //由小到大逐层封装函数 
    void factor()	//因子 :<因子> :=ID | NUM | (<表达式>) 
    {
    	if(syn==10||syn==11)	//当扫描的是数字或者字母时,继续扫描
    	{
    		scanner();
    	} 
    	else if(syn==27)	//当扫描到 '('时,后面应该为一个表达式,继续扫描
    	{
    		scanner();
    		expression();
    		if(syn==28)		//当扫描的是 ')'时,继续扫描
    			scanner();
    		else
    		{
    			k=1;	//出错 
    			cout<<"ERROR!缺少')'"<<endl;	//表达式缺 ')',出错 
    		}
    	} 
    	else
    	{
    		k=1;
    		cout<<"ERROR!运算符号后面不是常数或'('或标识符"<<endl;	//扫描表达式 ,表达式不是以 '('开头 
    	}
    } 
    
    void term()//项 : <项> :=<因子>{*<因子> | /<因子> } 
    {
    	factor();
    	while(syn==15||syn==16)	//当开头扫描的是 '*' 或者 '/'时('*'或者'/'后面是因子),继续扫描
    	{
    		scanner();
    		factor();
    	} 
    } 
    
    void expression()//表达式 : <表达式> :=<项>{+<项> | -<项>}
    {
    	term();
    	while(syn==13||syn==14)	//当开头扫描的是 '+' 或者 '-'时('+'或者'-'后面是项),继续扫描
    	{
    		scanner();
    		term();
    	}
    } 
    
    void statement()//赋值语句 : ID = <表达式>
    {
    	if(syn==10)	//当开头扫描的是字母时,继续扫描
    	{
    		scanner();
    		if(syn==18)		//扫描的是 ':='时,继续扫描
    		{
    			scanner();
    			expression();
    		} 
    		else
    		{
    			k=1;
    			cout<<"ERROR!缺少 ':=' "<<endl;
    		 } 
    	 } 
    	else
    	{
    		k=1; 
    		cout<<"ERROR!开头不是标识符!"<<endl;
    	}
     } 
     
    void sens()//语句串 :<语句串>:=<语句>{;<语句>}
    {
    	statement();
    	while(syn==26)	//当开始扫描的是 ';'时,继续扫描
    	{
    		scanner();
    		statement();
    	 } 
    } 
    
    //程序 : <程序> :=begin<语句串>end
    void lrparser() 
    {
    	if(syn==1)	//当开头扫描的是 'begin'时,继续扫描
    	{
    		scanner() ;
    		sens();
    		if(syn==6) //扫描到 'end'时,继续扫描 
    		{
    			scanner();
    			if(syn==0&&k==0)	//当数字串最后扫描的是 '#',而且无出错,分析成功
    				cout<<"success!" <<endl;
    			else if(syn!=0||k==1)
    				cout<<"error!"<<endl;
    		} 
    		else
    		{
    			cout<<"ERROR!没有 'end'"<<endl;
    		}
     	}
     	else
     	{
     		cout<<"ERROR!没有 'begin'"<<endl;
    	}
    }
    int main()
    {
    	char ch;
    	while(true)
    	{
    		cout<<"Please input a string:  "<<endl;
    		cin.getline(s,1000);//getline()函数可以滤去空格 
    		p=0;
    		scanner();
    		lrparser();
    	}
    	return 0; 
    }
    

    展开全文
  • 编译原理:语法分析器

    万次阅读 多人点赞 2019-05-05 18:03:59
    通过设计、编制、调试一个典型的语法分析程序(任选有代表性的语法分析方法,如LL(1)、递归下降分析法、LR、算符优先分析法)等,作为编制语法分析程序的依据,对词法分析器所提供的单词序列进行语法检测和结构分析...

    语法分析程序



    一、作业目的和要求

    通过设计、编制、调试一个典型的语法分析程序(任选有代表性的语法分析方法,如LL(1)、递归下降分析法、LR、算符优先分析法)等,作为编制语法分析程序的依据,对词法分析器所提供的单词序列进行语法检测和结构分析,实现并进一步掌握常用的语法分析方法。


    二、作业内容

    选择对各种常见高级程序设计语言都较为通用的语法结构作为分析对象(例如表达式、if、while、for等等),给出其文法规则描述(注意,文法规则的描述要符合所选分析方法的要求,比如用LL(1)分析法,文法必须是LL(1)文法),设计并实现一个完整的语法分析程序。

    • 输入:源程序以文件的形式输入。
    • 输出:对于输入的源程序,如果输入源程序是给定文法定义的合法程序,则输出”success”,如果不是,即输入源程序有错误,则输出“Error”,并且尽可能指出出错位置和原因。

    三、作业要求

    1、说明语法分析的源语言是什么?
    能分析的语法成分有哪些(比如if、while、表达式、switch等等)。
    给出每个语法规则的文法描述。(可以自定义语法成分,设计合理的语法规则。)

    运用的Java语言写成的语法分析程序,
    语法成分包括:if选择结构,while循环结构,for循环结构。

    2、说明选择的语法分析方法是哪种?描述总体设计思路和主要的流程图。

    语法分析的方法是LL(1)文法。

    • 设计思路:

    • 1.构造单个文法符号X的first集:
      如果X为终结符,First(X)=X;
      如果X->ε是产生式,把ε加入First(X);
      如果X是非终结符,如X->YZW。从左往右扫描产生式右部,把First(Y)加入First(X); 如果First(Y)不包含ε,表示Y不可为空,便不再往后处理;如果First(Y)包含ε,表示Y可为空,则处理Z,依次类推。
      构造文法符号串的first集,如:X->YZW;求YZW的first集
      从左往右扫描该式,加入其非空first集:把First(Y)加入First(YZW)
      若包含空串,处理下一个符号:如果First(Y)包含空串,便处理Z;不包含就退出;处理到尾部,即所有符号的first集都包含空串 把空串加入First(YZW)。

    • 2.在计算First(X)集之后的基础上:
      (1)$属于FOLLOW(S),S是开始符;
      (2)查找输入的所有产生式,确定X后紧跟的终结符;
      (3)如果存在A->αBβ,(α、β是任意文法符号串,A、B为非终结符),把first(β)的非空符号加入follow(B);
      (4)如果存在A->αB或A->αBβ 但first(β)包含空,把follow(A)加入follow(B)。

    • 3.构造预测分析表:
      对于每个产生式A->α,first(α)中的终结符a,把A->α加入M[A,a]。
      如果空串在first(α)中,说明可为空,找它的follow集,对于follow(A)中的终结符b,把A->α加入M[A,b];
      如果空串在first(α)中,且 “$”也在follow(A)中,说明A后可以接终结符,故把A->α加入M[A,$]中。

    • 4.执行分析:
      输入一个串,文法G的预测分析表,输出推导过程:
      $ 和 开始符S入栈,栈顶符号X,index指向分析串的待分析符号a。
      栈非空执行以下循环:
      如果X==a,表示匹配,符号栈弹出一个,index++指向下一个符号;
      否则,如果X是终结符,出错;
      否则,如果查表为error,出错;
      否则,查表正确,弹出栈顶符号,把其右部各个符号进栈,令X为栈顶符号。

    • 流程图:
      在这里插入图片描述
      在这里插入图片描述

    3、编程实现,程序中编写的各种函数,需要给出注释,说明函数的作用。
    通过实现接口中的方法来完成语法分析的功能。

    package Try;
    
    interface MyAnalyseFun {
        void Init();//初始化
        void getVnVt();//获取非终结符和终结符的集合
        void getFirst(Character c);//first集
        void getFirst(String s);//任意字符的first集
        void getFollow(char c);//follow集
        void createTable();//构造表
        void analyzeLL();//LL(1)分析过程
        String find(char X, char a);//查找
        void insert(char X, char a,String s);//插入
        void displayLL();//输出分析过程
        void ouput();//其他输出信息
    }
    

        package Try;
        
        import java.io.*;
        import java.util.*;
        
        public class MyAnalyse implements MyAnalyseFun{
            /**
             * 几个比较重要的参数
             * @param MyfirstSet 终结符的first集合
             * @param MyfirstSetX 任意符号的first集合
             * @param start 文法的开始符
             * @param MyfollowSet follow集
             * @param VnSet 终结符的集合
             * @param VtSet 终结符的集合
             * @param inputStrings 文法拓展的输入
             * @param outputSet 输出的集合
             * @param table 分析表
             * @param MyAnaStatck 分析栈
             * @param strInput 需要使用预测分析器的输入串
             * @param MyAction 分析动作
             * @param Index 分析的索引值
             */
            //从文件中读入时后台无法识别空串ε,因此用符号&代替空串ε
    
        //first集是终结符的first集
        protected HashMap<Character, HashSet<Character>> MyfirstSet = new HashMap<>();
        //firstX集是指任意符号串的first集
        protected HashMap<String, HashSet<Character>> MyfirstSetX = new HashMap<>();
        //文法的开始符
        protected Character start = 'S';
        //follow集
        protected HashMap<Character, HashSet<Character>> MyfollowSet = new HashMap<>();
    
        //存储非终结符的结合
        protected HashSet<Character> VnSet = new HashSet<>();
        //存储终结符的结合
        protected HashSet<Character> VtSet = new HashSet<>();
        protected HashMap<Character, ArrayList<String>> outputSet = new HashMap<>();
        //输入文法
        //S->a|^|(T)
        //T->SU
        //U->,SU|&
    //    protected String [] inputStrings = {   "S->a",
    //                                        "S->^",
    //                                        "S->(T)",
    //                                        "T->SU",
    //                                        "U->,SU",
    //                                        //"U->ε",
    //                                        "U->&"   };
        //定义分析表
        protected String [][] table;
        //分析栈
        protected Stack<Character> MyAnaStatck = new Stack<>();
        //定义要分析的输入串
        protected String strInput = "(a,a)$";
        //对动作的初始化
        protected String MyAction = "";
        int Index = 0;
    
        //从文件中读入
        protected String[] inputStrings = getSource();
    
        protected MyAnalyse() {
        }
    
        public static void main(String[] args){
            MyAnalyse test = new MyAnalyse();
    
            test.getVnVt();
            test.Init();
            test.createTable();
            test.analyzeLL();
            test.ouput();
            
        }
    
        //从文件中读入文法的方法
        public  static  String[] getSource(){
            StringBuffer temp = new StringBuffer();
            FileInputStream fis= null;
            try {
                fis = new FileInputStream("E:\\readin.txt");
                byte[] buff=new byte[1024];
                int len=0;
                while((len=fis.read(buff))!=-1){
                    temp.append(new String(buff,0,len));
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return temp.toString().split("\n");
        }
    
        //初始化
        @Override
        public void Init() {
            for (String s1 : inputStrings) {
                //"S->a",
                //"S->^",
                //"S->(T)",
                //"T->SU",
                //"U->,SU",
                //"U->&"
                String[] str = s1.split("->");//通过符号“->”分隔每行的文法
                char c = str[0].charAt(0);//取得左边的非终结符
                ArrayList<String> list = outputSet.containsKey(c) ? outputSet.get(c) : new ArrayList<>();
                list.add(str[1]);//添加文法右边的内容到集合中
                outputSet.put(c, list);
            }
            //求非终结符的first集
            for (Character c1 : VnSet)
                getFirst(c1);
    
            for (Character c2 : VnSet) {
                ArrayList<String> l = outputSet.get(c2);
                for (String s2 : l)
                    getFirst(s2);
            }
            //求出follow集
            getFollow(start);
            for (Character c3 : VnSet) {
                getFollow(c3);
            }
        }
    
        @Override
        public void getVnVt() {//取出终结符和非终结符的集合
            for (String s3 : inputStrings) {
                String[] str = s3.split("->");
                VnSet.add(str[0].charAt(0));
            }
            for (String s4 : inputStrings) {
                String[] str = s4.split("->");
                String right = str[1];
                for (int i = 0; i < right.length(); i++)
                    if (!VnSet.contains(right.charAt(i)))
                        VtSet.add(right.charAt(i));
            }
        }
    
        @Override
        public void getFirst(Character c) {
            ArrayList<String> list = outputSet.get(c);
            HashSet<Character> set = MyfirstSet.containsKey(c) ? MyfirstSet.get(c) : new HashSet<Character>();
            // c为终结符 直接添加
            if (VtSet.contains(c)) {
                set.add(c);
                MyfirstSet.put(c, set);
                return;
            }
            // c为非终结符 处理其每条产生式
            for (String s5 : list) {
                // c 推出空串 直接添加
                if (s5 == Character.toString('&')) {
                    set.add('&');
                }
                // X -> Y1Y2Y3… 情况
                else {
                    // 从左往右扫描生成式右部
                    int i = 0;
                    while (i < s5.length()) {
                        char tn = s5.charAt(i);
                        //先处理防止未初始化
                        getFirst(tn);
                        HashSet<Character> tvSet = MyfirstSet.get(tn);
                        // 将其first集加入左部
                        for (Character tmp : tvSet)
                            set.add(tmp);
                        // 若包含空串 处理下一个符号
                        if (tvSet.contains('&'))
                            i++;
                            // 否则退出 处理下一个产生式
                        else
                            break;
                    }
                }
            }
            MyfirstSet.put(c, set);
        }
    
        @Override
        public void getFirst(String s) {
            HashSet<Character> set = (MyfirstSetX.containsKey(s))? MyfirstSetX.get(s) : new HashSet<Character>();
            // 从左往右扫描该式
            int i = 0;
            while (i < s.length()) {
                char tn = s.charAt(i);
                HashSet<Character> tvSet = MyfirstSet.get(tn);
                // 将其非空 first集加入左部
                for (Character tmp : tvSet)
                    if(tmp != '&')
                        set.add(tmp);
                // 若包含空串 处理下一个符号
                if (tvSet.contains('&'))
                    i++;
                    // 否则结束
                else
                    break;
                // 到了尾部 即所有符号的first集都包含空串 把空串加入
                if (i == s.length()) {
                    set.add('&');
                }
            }
            MyfirstSetX.put(s, set);
        }
    
        @Override
        public void getFollow(char ch) {
            ArrayList<String> list = outputSet.get(ch);
            HashSet<Character> setA = MyfollowSet.containsKey(ch) ? MyfollowSet.get(ch) : new HashSet<Character>();
            //如果是开始符 添加 $
            if (ch == start) {
                setA.add('$');
            }
            //查找输入的所有产生式,确定c的后跟 终结符
            for (Character cha : VnSet) {
                ArrayList<String> l = outputSet.get(cha);
                for (String s : l)
                    for (int i = 0; i < s.length(); i++)
                        if (s.charAt(i) == ch && i + 1 < s.length() && VtSet.contains(s.charAt(i + 1)))
                            setA.add(s.charAt(i + 1));
            }
            MyfollowSet.put(ch, setA);
            //处理c的每一条产生式
            for (String s : list) {
                int i = s.length() - 1;
                while (i >= 0 ) {
                    char tn = s.charAt(i);
                    //只处理非终结符
                    if(VnSet.contains(tn)){
                        // 都按 A->αB&  形式处理
                        //若&不存在   followA 加入 followB
                        //若&存在,把&的非空first集  加入followB
                        //若&存在  且 first(&)包含空串   followA 加入 followB
    
                        //若&存在
                        if (s.length() - i - 1 > 0) {
                            String right = s.substring(i + 1);
                            //非空first集 加入 followB
                            HashSet<Character> setF = null;
                            if( right.length() == 1 && MyfirstSet.containsKey(right.charAt(0))) {
                                setF = MyfirstSet.get(right.charAt(0));
                            }
                            else{
                                if(!MyfirstSetX.containsKey(right)){
                                    HashSet<Character> set = new HashSet<Character>();
                                    MyfirstSetX.put(right, set);
                                }
                                setF = MyfirstSetX.get(right);
                            }
                            HashSet<Character> setX = MyfollowSet.containsKey(tn) ? MyfollowSet.get(tn) : new HashSet<Character>();
                            for (Character cha : setF) {
                                if (cha != '&') {
                                    setX.add(cha);
                                }
                            }
                            MyfollowSet.put(tn, setX);
    
                            // 若first(&)包含&   followA 加入 followB
                            if(setF.contains('&')){
                                if(tn != ch){
                                    HashSet<Character> setB = MyfollowSet.containsKey(tn) ? MyfollowSet.get(tn) : new HashSet<Character>();
                                    for (Character cha : setA) {
                                        setB.add(cha);
                                    }
                                    MyfollowSet.put(tn, setB);
                                }
                            }
                        }
                        //若&不存在   followA 加入 followB
                        else{
                            // A和B相同不添加
                            if(tn != ch){
                                HashSet<Character> setB = MyfollowSet.containsKey(tn) ? MyfollowSet.get(tn) : new HashSet<Character>();
                                for (Character cha : setA)
                                    setB.add(cha);
                                MyfollowSet.put(tn, setB);
                            }
                        }
                        i--;
                    }
                    //如果是终结符往前扫描  如 A->aaaBCDaaaa  此时&为 CDaaaa
                    else i--;
                }
            }
        }
    
        @Override
        public void createTable() {//构造预测分析表的格式
            //终结符数组
            Object[] VtArray = VtSet.toArray();
            //非终结符数组
            Object[] VnArray = VnSet.toArray();
            // 预测分析表初始化
            table = new String[VnArray.length + 1][VtArray.length + 1];
            table[0][0] = "Vn/Vt";
            //初始化首行首列
            for (int i = 0; i < VtArray.length; i++)
                table[0][i + 1] = (VtArray[i].toString().charAt(0) == '&') ? "$" : VtArray[i].toString();
            for (int i = 0; i < VnArray.length; i++)
                table[i + 1][0] = VnArray[i] + "";
            //全部置error
            for (int i = 0; i < VnArray.length; i++)
                for (int j = 0; j < VtArray.length; j++)
                    table[i + 1][j + 1] = "error";
    
            //插入生成式
            for (char A : VnSet) {
                ArrayList<String> l = outputSet.get(A);
                for(String s : l){
                    HashSet<Character> set = MyfirstSetX.get(s);
                    for (char a : set)
                        insert(A, a, s);
                    if(set.contains('&'))  {//如果包含&
                        HashSet<Character> setFollow = MyfollowSet.get(A);
                        if(setFollow.contains('$'))//判断follow集中是否包含$
                            insert(A, '$', s);
                        for (char b : setFollow)
                            insert(A, b, s);
                    }
                }
            }
        }
    
        @Override
        public void analyzeLL() {
            System.out.println("-------------------1.LL分析过程-------------------");
            System.out.println("|               分析栈        输入串     动作|  ");
            MyAnaStatck.push('$');
            MyAnaStatck.push('S');
            displayLL();//调用分析过程方法
            char X = MyAnaStatck.peek();
            while (X != '$') {
                char a = strInput.charAt(Index);
                if (X == a) {
                    MyAction = "match " + MyAnaStatck.peek();
                    MyAnaStatck.pop();
                    Index++;
                } else if (VtSet.contains(X))
                    return;
                else if (find(X, a).equals("error"))
                    return;
                else if (find(X, a).equals("&")) {
                    MyAnaStatck.pop();
                    MyAction = X + "->&";
                } else {
                    String str = find(X, a);
                    if (str != "") {
                        MyAction = X + "->" + str;
                        MyAnaStatck.pop();
                        int len = str.length();
                        for (int i = len - 1; i >= 0; i--)
                            MyAnaStatck.push(str.charAt(i));
                    } else {
                        System.out.println("error at '" + strInput.charAt(Index) + " in " + Index);
                        return;
                    }
                }
                X = MyAnaStatck.peek();
                displayLL();
            }
            System.out.println("LL(1)文法分析成功!");
            System.out.println("-------------------LL分析过程-------------------");
        }
    
        @Override
        public String find(char X, char a) {
            for (int i = 0; i < VnSet.size() + 1; i++) {
                if (table[i][0].charAt(0) == X)
                    for (int j = 0; j < VtSet.size() + 1; j++) {
                        if (table[0][j].charAt(0) == a)
                            return table[i][j];
                    }
            }
            return "";
        }
    
        @Override
        public void insert(char X, char a, String s) {//插入
            if(a == '&')
                a = '$';
            for (int i = 0; i < VnSet.size() + 1; i++) {
                if (table[i][0].charAt(0) == X)
                    for (int j = 0; j < VtSet.size() + 1; j++) {
                        if (table[0][j].charAt(0) == a){
                            table[i][j] = s;
                            return;
                        }
                    }
            }
        }
    
        @Override
        public void displayLL() {// 对输入串(a,a)$ 输出 LL(1)分析过程
            Stack<Character> s = MyAnaStatck;
            System.out.printf("%23s", s );//输出第一列:分析栈
            System.out.printf("%13s", strInput.substring(Index));//输出第二列:输入串
            System.out.printf("%10s", MyAction);//输出第三列:动作
            System.out.println();
        }
    
        @Override
        public void ouput() {
            // 输出终结符的first集
            System.out.println("-------------------2.first集-------------------");
            for (Character c : VnSet) {
                HashSet<Character> set = MyfirstSet.get(c);
                System.out.printf("%10s",c + "  ->   ");
                for (Character cha : set)
                    System.out.print(cha+" ");
                System.out.println();
            }
            System.out.println("-------------------first集-------------------");
            // 输出任意符号串的first集
            System.out.println("-------------------firstX集-------------------");
            Set<String> setStr =  MyfirstSetX.keySet();
            for (String s : setStr) {
                HashSet<Character> set = MyfirstSetX.get(s);
                System.out.printf("%10s",s + "  ->   ");
                for (Character cha : set)
                    System.out.print(cha+" ");
                System.out.println();
            }
            System.out.println("-------------------firstX集-------------------");
            // 输出follow集
            System.out.println("-------------------3.follow集-------------------");
    
            for (Character c : VnSet) {
                HashSet<Character> set = MyfollowSet.get(c);
                System.out.print("Follow " + c + " : ");
                for (Character cha : set)
                    System.out.print(cha+" ");
                System.out.println();
            }
            System.out.println("-------------------follow集-------------------");
            //构造LL1文法预测分析表
            System.out.println("-------------------4.LL1预测分析表-------------------");
    
            for (int i = 0; i < VnSet.size() + 1; i++) {
                for (int j = 0; j < VtSet.size() + 1; j++) {
                    System.out.printf("%8s", table[i][j] + " ");
                }
                System.out.println();
            }
            System.out.println("-------------------LL1预测分析表-------------------");
        }
    }
    

    四、结果分析

    1、输入正确的源程序截图:
    将符号ε替换为&
    在这里插入图片描述

    输出结果截图:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    2、输入错误的源程序截图:
    输入错误文法
    在这里插入图片描述
    输出结果截图:
    在这里插入图片描述
    3、总结(自己的心得体会、你编写的语法分析程序的优缺点)
    S->a|^|(T)
    T->SU
    U->,SU|ε

    • 优点:文法分析过程比较详细,任务整个完成过程是充实的,这个实验报告相当于对编译原理理论课的一次实践尝试,能收获很多课堂上面学不到的知识,同时也能巩固老师所教授的知识。

    • 缺点:在写程序的时候,卡在了空串那个点。最开始尝试直接在程序中定义文法时,ε能在程序中分析成功。后来在用读入文件的方式定义文法时,控制台出现乱码,这个点解决起来花了一点时间,最后决定将符号ε替换为&,程序才能运行成功。

    展开全文
  • 语法分析器(含完整源码)
  • 编译原理c++语法分析器

    万次阅读 2017-07-05 11:57:05
    语法分析器  针对编译原理第三版-何炎祥主编的书中一个 LL(1)语法分析表,利用c++编写了语法分析程序,下附加代码: /* Name: LL(1)语法分析器  Copyright:  Author:y cc  Date: 18/04/17 16:26 Description: ...

    语法分析器

         针对编译原理第三版-何炎祥主编的书中一个 LL(1)语法分析表利用c++编写了语法分析程序,下附加代码

    /*
    Name: LL(1)语法分析器 
    Copyright: 
    Author:y cc 
    Date: 18/04/17 16:26
    Description: 根据固定的分析表,这里是编译原理第三版-何炎祥主编的书中一个语法分析表 对输入以$结尾的字符串进行判断是否符合语法 
    */
    #include<iostream>
    #include<stdlib.h>
    #include<string.h>
    using namespace std;
    typedef struct
    {
    char data[10];
    int top;
    } message;//栈内元素对象 
    void create(message *&m)
    {
    m=(message *)malloc(sizeof(message));
    m->top=-1;
    }
    void push(message *&m,char i)//进栈操作 
    {
    if(m->top<10)
    {
    m->top++;
    m->data[m->top]=i;
    }
    else
    cout<<"栈满"; 
    }
    char pop(message *&m)//出栈操作 
    {
    char i;
    if(m->top!=-1)
    {
    i=m->data[m->top];
    m->top--;
    return i;
    }
    else
    cout<<"栈空"; 
    }
    void getStr(char str[])//将输入的以$结尾的字符串 保存于字符串数组中 
    {
    int j=0;
    while(true)
    {
    cin>>str[j];
    if(str[j]=='$')
    break;
    else
    j++;
    }
    }
    void output(message *m,char *j)//用于输出符号栈与输入串的代码 
    {
        int counti=0,countj=0;
        while(m->top>-1)
        {
        cout<<m->data[m->top];
        m->top--;
        counti++;
        }
        cout<<"   ";
        while(*j!='$')
        {
        cout<<*j;
        j++;
        countj++;
        }
            cout<<"$";
        while(counti!=0)
        {
        m->top++;
    counti--; 
        }
        while(countj!=0)
        {
        j--;
    countj--; 
        } 
    }
    int main() //main方法 
    {
    string b[6][6]={{""," "," ","a","a"," "},//对应分析表 
    {" "," "," ","bA","bA"," "},
    {"ibA"," ","#"," "," ","#"},
    {" "," "," ","cB","cB"," "},
    {"#","+cB","#"," "," ","#"},
    {" "," "," ","(",")a*"," "}};
    int i=-1;
    message *m;
    create(m);
        cout<<"输入字符串,字符串以$结尾,注意调成英文输入法。例如 (i($"<<endl; 
        char str[20];
        getStr(str);//获取字符串 
        char *j=str;
    push(m,'$');//'$'进栈 
        push(m,'s');//'s'进栈 
        cout<<"        符号串分析过程          "<<endl;
        cout<<"符号栈m 输入串str[j] 产生式b[][]"<<endl;
        while(true)  
      {
      //终结符时的判断 
         if(m->data[m->top]=='i'||m->data[m->top]=='+'||m->data[m->top]=='*'||m->data[m->top]=='('||m->data[m->top]==')'||m->data[m->top]=='#'||m->data[m->top]=='$')
        {
        if(m->data[m->top]==*j)
        {
        if(m->data[m->top]=='$')//设定终结条件 
        {
                  output(m,j);//用于输出符号栈与输入串的代码 
                cout<<"           ";
        cout<<"ok";
        break;
        }
        else
        {
                output(m,j);//用于输出符号栈与输入串的代码 
                cout<<endl; 
        j++;
       pop(m); 
        }
        } 
    else 
    {
        cout<<"不是一个句子";
        break;
        }
        }
        //非终结符的判断开始 
    else if(m->data[m->top]=='s')//非终结符's' 
        {
        output(m,j);//用于输出符号栈与输入串的代码 
        int m1=0;
        int n;
        int k;
        switch(*j) //利用这种方式查找产生式,这是我觉得比较得意的方式 
        {
        case 'i':n=0;break;
        case '+':n=1;break;
        case '*':n=2;break;
        case '(':n=3;break;
        case ')':n=4;break;
        case '$':n=5;break;
        }
        if(b[m1][n]=="#")
        {
        cout<<"     ";
        cout<<"#"<<endl; 
        pop(m);
        }
        else
         {
          cout<<"     ";
          cout<<b[m1][n]<<endl; 
          pop(m);
            k=b[m1][n].size();
        if(b[m1][n]!=" ")
      {
      char c[k];
    strcpy(c,b[m1][n].c_str());//将String转化为 char[] 
        for(int j=0;j<k;j++)
    {
    push(m,c[k-j-1]);
    }
      } 
        else
      {
        cout<<"不是一个句子";
        break;
        }
         } 
        } //非终结符's' 
        else if(m->data[m->top]=='a') //非终结符'a' 
        {
        output(m,j);//用于输出符号栈与输入串的代码 
        int m1=1;
        int n;
        int k;
        switch(*j)
        {
        case 'i':n=0;break;
        case '+':n=1;break;
        case '*':n=2;break;
        case '(':n=3;break;
        case ')':n=4;break;
        case '$':n=5;break;
        }
          if(b[m1][n]=="#")
        {
        cout<<"     ";
        cout<<"#"<<endl; 
        pop(m);
        }
        else
         {
          cout<<"     ";
          cout<<b[m1][n]<<endl; 
          pop(m);
            k=b[m1][n].size();
        if(b[m1][n]!=" ")
      {
      char c[k];
    strcpy(c,b[m1][n].c_str());//将String转化为 char[] 
        for(int j=0;j<k;j++)
    {
    push(m,c[k-j-1]);
    }
      } 
        else
      {
        cout<<"不是一个句子";
        break;
        }
         } 
        }//非终结符'a' 
        else if(m->data[m->top]=='A')//非终结符'A' 
        {
        output(m,j);//用于输出符号栈与输入串的代码  
        int m1=2;
        int n;
        int k;
        switch(*j)
        {
        case 'i':n=0;break;
        case '+':n=1;break;
        case '*':n=2;break;
        case '(':n=3;break;
        case ')':n=4;break;
        case '$':n=5;break;
        }
          if(b[m1][n]=="#")
        {
        cout<<"     ";
        cout<<"#"<<endl; 
        pop(m);
        }
        else
         {
          cout<<"     ";
          cout<<b[m1][n]<<endl; 
          pop(m);
            k=b[m1][n].size();
        if(b[m1][n]!=" ")
      {
      char c[k];
    strcpy(c,b[m1][n].c_str());//将String转化为 char[] 
        for(int j=0;j<k;j++)
    {
    push(m,c[k-j-1]);
    }
      } 
        else
      {
        cout<<"不是一个句子";
        break;
        }
         } 
        }//非终结符'A' 
       else if(m->data[m->top]=='b')//非终结符'b' 
        {
        output(m,j);//用于输出符号栈与输入串的代码 
        int m1=3;
        int n;
        int k;
        switch(*j)
        {
        case 'i':n=0;break;
        case '+':n=1;break;
        case '*':n=2;break;
        case '(':n=3;break;
        case ')':n=4;break;
        case '$':n=5;break;
        }
          if(b[m1][n]=="#")
        {
        cout<<"     ";
        cout<<"#"<<endl; 
        pop(m);
        }
        else
         {
          cout<<"     ";
          cout<<b[m1][n]<<endl; 
          pop(m);
            k=b[m1][n].size();
        if(b[m1][n]!=" ")
      {
      char c[k];
    strcpy(c,b[m1][n].c_str());//将String转化为 char[] 
        for(int j=0;j<k;j++)
    {
    push(m,c[k-j-1]);
    }
      } 
        else
      {
        cout<<"不是一个句子";
        break;
        }
         } 
        }//非终结符'b' 
        else if(m->data[m->top]=='B')//非终结符'B' 
        {
        output(m,j);//用于输出符号栈与输入串的代码 
        int m1=4;
        int n;
        int k;
        switch(*j)
        {
        case 'i':n=0;break;
        case '+':n=1;break;
        case '*':n=2;break;
        case '(':n=3;break;
        case ')':n=4;break;
        case '$':n=5;break;
        } 
        if(b[m1][n]=="#")
        {
        cout<<"     ";
        cout<<"#"<<endl; 
        pop(m);
        }
        else
        {
          cout<<"     ";
          cout<<b[m1][n]<<endl; 
        pop(m);
            k=b[m1][n].size();
        if(b[m1][n]!=" ")
      {
      char c[k];
    strcpy(c,b[m1][n].c_str());//将String转化为 char[] 
        for(int j=0;j<k;j++)
    {
    push(m,c[k-j-1]);
    }
      } 
        else
      {
        cout<<"不是一个句子";
        break;
        }
        }  
        }//非终结符'B' 
        else//非终结符'C' 
        { 
        output(m,j);//用于输出符号栈与输入串的代码 
        int m1=5;
        int n;
        int k;
        switch(*j)
        {
        case 'i':n=0;break;
        case '+':n=1;break;
        case '*':n=2;break;
        case '(':n=3;break;
        case ')':n=4;break;
        case '$':n=5;break;
        }
        if(b[m1][n]=="#")
        {
        cout<<"     ";
        cout<<"#"<<endl; 
        pop(m);
        }
        else
        {
        cout<<"     ";
          cout<<b[m1][n]<<endl; 
        pop(m);
            k=b[m1][n].size();
        if(b[m1][n]!=" ")
      {
      char c[k];
    strcpy(c,b[m1][n].c_str());//将String转化为 char[] 
        for(int j=0;j<k;j++)
    {
    push(m,c[k-j-1]);
    }
      } 
        else
     {
        cout<<"不是一个句子";
        break;
    }
        }  
        }//非终结符'C' 
    }
    return 0;
    }


       运行结果截图:



    展开全文
  • 编译原理词法分析器和语法分析器,简单易懂,超强大,尤其适合自己动手模仿写编译器的同学。
  • C# 可视化——LR语法分析器

    千次阅读 2018-11-02 15:56:12
    用C#完成了一个可视化的LR语法分析器,源代码从文件读取。点击选择文件按钮选择源文件,源文件的内容显示在textBox1中。  点击开始分析按钮,启动语法分析程序,分析过程和结果显示在textBox2中: ...
  • 编译原理实验 —— 语法分析器

    千次阅读 2018-11-03 13:59:11
    分析的简单语言的语法 用扩充的BNF表示如下: ⑴&lt;程序&gt;::=begin&lt;语句串&gt;end ⑵&lt;语句串&gt;::=&lt;语句&gt;{;&lt;语句&gt;} ⑶&lt;语句&gt;...
  • 【编译原理】LL(1)语法分析器

    万次阅读 多人点赞 2018-05-10 20:44:43
    1.项目要求文法要求:(1)从文件读入,每条产生式占用一行(2)文法为LL(1)文法从文件中读入文法,从键盘上输入待分析的符号串,采用 LL(1)分析算法判断该符号串是否为该文法的句子。2.实验思路:首先实现集合FIRST...
  • 语法分析器实现过程(java)

    千次阅读 多人点赞 2019-10-16 11:23:35
    语法分析器是编译原理的一个实验,本文将会详细给出实现的具体步骤,利用java进行示例讲解,源码(包含java和c++两种实现方式)可在处下载。 一、实验目的 设计、编写一个语法分析程序,加深对语法分析原理的理解。 ...
  • 语法分析器java实现

    2020-07-23 23:30:33
    语法分析器java实现,包含词法分析器。程序代码作为词法分析器的输入,词法分析器的输出作为语法分析器的输入,由语法分析器输出语法分析的结果。
  • 通过本次实验,进一步加深对递归下降算法与抽象语法树的理解,学习程序设计语言的语法分析器的手工编程方法。 二、实验任务: 仔细阅读并测试TINY语言的语法分析器的相关程序,同时复习递归下降算法与抽象语法树的...
  • 使用C++实现LR(0)语法分析器的操作

    千次阅读 2018-10-29 10:23:15
    使用C++ 完成LR(0)的语法分析器 由于最近学校里在学习编译原理,而且要求实现语法分析器,于是我用了几天的时间搞明白了语法分析器的原理并且将其实现了。由于编者还是本科生而且还在学习中,因此出现什么错误请各位...
  • 学习如何使用Yacc设计一个语法分析器,并与用lex写的词法分析器链接起来。 实验内容: 使用yacc为实验2所给的语言写一个语法分析器(你可以重新设计该语言的文法,但不能改变语言)。其中,词法分析使用实验3中已...
  • 语法分析器 二丶实验目的及要求 通过设计、编制、调试-个典型的语法分析程序(任选有代表性的语法分析方法,如LL(1)、递归下降分析法、LR、 算符优先分析法)等,作为编制语法分析程序的依据,对词法分析器所提供的...
  • 语法分析器根据语言的语法规则来解析代码,解析阶段决定了输入的代码是否能够根据既定的语法组成token流 语法分析器则会定义一些函数来把代码组织成一种被称为AST的数据结构。解析器可以采用递归下降的解析技术...
  • c语言语法分析器

    2020-06-13 16:52:51
    本程序实现一个分析C语言的词法分析+语法分析。 注意: 1.文法简略,没有实现的部分,可以在此文法的基础上进行扩充,本程序的采用自顶向下的LL(1)文法。 2.可以自动实现求First 集和 Follow 集。 3.处终结符外...
  • 编译原理 lr语法分析器 课程实验报告 编译原理 lr语法分析器 课程实验报告
  • 这是一个单文档的tiny语言语法分析器,良好的MFC单文档界面。
  • 语法分析器的任务主要是确定是否可以以及如何从语法的起始符号推导出输入符号串(输入文本),主要可以通过两种方式完成: 1. 自顶向下分析 根据形式语法规则,在语法分析树的自顶向下展开中搜索输入符号串可能的最...
1 2 3 4 5 ... 20
收藏数 274,353
精华内容 109,741
关键字:

语法分析器