Loading

[SDUT] 2147. 表达式语法分析——递归子程序法

https://acm.sdut.edu.cn/onlinejudge3/problems/2147

对于给定的输入串(长度不超过50个符号),请输出分析过程中用到的所有产生式,并指明该输入串是否为该文法能生成的表达式,输出共11行,前10行每行两个数据用空格隔开,表示推导时所用产生式顺序号(从0开始),最后一行是accept,表示i+i*i是文法能生成的合法表达式。注:其中&符号代表文法中的ε符号。

注意:

  • 实际上还是要算FIRST集的
  • 也就是说进入E,T的时候要判读一下是否 str[cur] == '(' || str[cur] == 'i'
#include <bits/stdc++.h>
using namespace std;

/*
E→TG
G→+TG | ε
T→FS
S→*FS | ε
F→(E) | i
*/

int cnt;
void prt(const char *str) { printf("%d %s\n", cnt ++, str); }
string str; int cur;

void assert0(bool flag) {
    if(!flag) {
        puts("error");
        exit(0);
    }
}

void E();
void T();
void F();

auto G() -> void {
    if(str[cur] == '+') {
        ++ cur;
        prt("G-->+TG"), T(), G();
    } else {
        prt("G-->&");
    }
}

auto S() -> void {
    if(str[cur] == '*') {
        ++ cur;
        prt("S-->*FS"), F(), S();
    } else {
        prt("S-->&");
    }
}

auto F() -> void {
    if(str[cur] == '(') {
        ++ cur;
        prt("F-->(E)"), E();
        assert0(str[cur ++] == ')');
    } else if(str[cur] == 'i'){
        ++ cur;
        prt("F-->i");
    } else {
        assert0(0);
    }
}

auto T() -> void {
    assert0(str[cur] == '(' || str[cur] == 'i');
    prt("T-->FS"), F(), S();
}

auto E() -> void {
    assert0(str[cur] == '(' || str[cur] == 'i');
    prt("E-->TG"), T(), G();
}


int main() {
    cin >> str;
    E();
    assert0(str[cur] == '#' && cur == str.length() - 1);
    puts("accept");
}
posted @ 2021-10-29 20:11  nekko  阅读(109)  评论(0)    收藏  举报