LL(1)文法求算数表达式的值
递归子程序法
分析过程:
表达式文法G[E]:
E->E+T|E-T|T
T->T*F|T/F|T%F|F
F->N^F|N
N->(E)|NUM|+NUM|-NUM
消除左递归、左公共因子
E ->TE'
E'->+TE'|-TE'|ε
T ->FT'
T'->*FT'|/FT'|%FT'|ε
F ->NF'
F'->^F|ε
N->(E)|NUM|+NUM|-NUM
FIRST集和FOLLOW集
LL(1)分析表
(应该没错吧……表示昨天刚考完试……)
(嗯。。我承认我抄。。咳咳。。借鉴了这份代码http://ideone.com/o2Ag4。。还是炮姐写的好。。)

#include <cstdio> #include <cmath> /** * LL(1)文法求算数表达式的值 * 递归子程序法 **/ enum SYM_KIND { // 符号类型 SYM_NUM, // num SYM_ADD, // + SYM_SUB, // - SYM_MUL, // * SYM_DIV, // / SYM_MOD, // % SYM_POW, // ^ SYM_LBR, // ( SYM_RBR, // ) SYM_END, // ' ' SYM_ERR // 其他不合法符号 }; enum ERR_KIND { // 状态 ERR_OK, ERR_INVALID_CHAR, ERR_NO_OPERATOR, ERR_BR_NOT_MATCH, ERR_NO_NUM, ERR_END }; char expr[2000]; // 表达式 int pos; // 读取到表达式的位置 double val; ERR_KIND err; void F(); void E(); void NUM() { val = 0; while (expr[pos] <= '9' && expr[pos] >= '0') { val = val * 10 + expr[pos] - '0'; pos++; } if (expr[pos] == '.') { pos++; double eo = 0.1; while (expr[pos] <= '9' && expr[pos] >= '0') { val += (expr[pos] - '0') * eo; eo *= 0.1; pos++; } } } SYM_KIND get_sym() // 读取一个单词 { char ch = expr[pos++]; while (ch == ' ' || ch == ' ') // 忽略空格 ch = expr[pos++]; if (ch <= '9' && ch >= '0') { pos--; NUM(); return SYM_NUM; } else if (ch == '+') return SYM_ADD; else if (ch == '-') return SYM_SUB; else if (ch == '*') return SYM_MUL; else if (ch == '/') return SYM_DIV; else if (ch == '%') return SYM_MOD; else if (ch == '^') return SYM_POW; else if (ch == '(') return SYM_LBR; else if (ch == ')') return SYM_RBR; else if (ch == '