日常练习代码

根据上下文无关文法(LL(1)文法),构建预测分析程序,完成给出的输入串的自上而下的语法分析,并返回语法分析结果。
给定文法–>消除左递归–>提左因子–>First集;Follow集–>分析表 M[A,a]矩阵–>预测分析程序
LL(1)文法:
G [E]:E→E+T
E→T
T→T*F
T→F
F→(E)|i
经消去直接左递归之后,得到的文法如下:
G[E]: E -> TE’
E
-> +TE’ | Ɛ
T -> FT’
T`->*FT’| Ɛ
F -> (E) | i

消除回溯和提取左因子:消除回溯必须保证对文法的任何非终结符,当要它去匹配输入串时,能够根据它所面临的输入符号准确的指派它的一个候选去执行任务,并且此候选的工作结果应是确信无疑的。提取左因子就是不断的提取公共左因子,把每个非终结符的所有候选首符集变成亮两两不相交。

对于任何(X,a),总控程序每次都执行下述三种可能的动作之一:
(1)若X=a=’#’,则宣布分析成功,停止分析过程;
(2)若X=a!=‘#’,则把X从栈顶逐出,让a指向下一个输入符号;
(3)若X是一个非终结符,则查看分析表M。
LL(1)分析表:
这里写图片描述
代码:

#include <bits/stdc++.h>
using namespace std;
map<char, map<char,string> > FORECAST_TABLE;
const int maxn = 500 + 50;
void Init_Table(){
    FORECAST_TABLE['E']['i'] = "TG";
    FORECAST_TABLE['E']['('] = "TG";

    FORECAST_TABLE['G']['+'] = "+TG";
    FORECAST_TABLE['G'][')'] = "";
    FORECAST_TABLE['G']['#'] = "";

    FORECAST_TABLE['T']['i'] = "FH";
    FORECAST_TABLE['T']['('] = "FH";

    FORECAST_TABLE['H']['+'] = "";
    FORECAST_TABLE['H']['*'] = "*FH";
    FORECAST_TABLE['H']['#'] = "";
    FORECAST_TABLE['H'][')'] = "";


    FORECAST_TABLE['F']['i'] = "i";
    FORECAST_TABLE['F']['('] = "(E)";

}
char tmpSTACK[maxn];
int stackTOP;
bool Anayse(char *str,int len){
    int step = 0;
    stackTOP = 0;
    stack<char> STACK;
    while(!STACK.empty()) STACK.pop();
    int pos = 0;
    char topChar;
    STACK.push('#');
    STACK.push('E');
    tmpSTACK[stackTOP++] = '#';
    tmpSTACK[stackTOP++] = 'E';
    while(true){
        string tmp = "";
        topChar = STACK.top();
        STACK.pop();
        stackTOP--;
        if(topChar == 'i' || topChar == '(' || topChar == ')'
            || topChar == '+' || topChar == '*'){
            if(topChar == str[pos]){
                pos++;
            }
            else return false;
        }
        else if(topChar == '#'){
            if(topChar == str[pos]) return true;
            else return false;
        }
        else{
            if(FORECAST_TABLE[topChar].count(str[pos]) == 0) return false;
            else{
                tmp = FORECAST_TABLE[topChar][str[pos]];
                int len = tmp.length();
                for(int i = len - 1;i >= 0;--i) STACK.push(tmp[i]),tmpSTACK[stackTOP++] = tmp[i];
            }
        }
        printf("%d ",step++);
        for(int i = 0;i < stackTOP;++i) printf("%c",tmpSTACK[i]);
        printf("  ");
        for(int i = 0;i <= len;++i) printf("%c",str[i]);
        printf("  ");
        cout << tmp << endl;
    }
}
int main(){
    char str[maxn];
    scanf("%s",str);
    int len = strlen(str);
    str[len] = '#';
    Init_Table();
    bool res = Anayse(str,len);
    if(res) printf("YES\n");
    else printf("NO\n");
}

运行结果:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值