先贴代码
假设1. 小括号已匹配
我不做这个假设,如果括号不匹配,我写的这个程序会打印一个错误信息
假设3. 表达式中间没有多余的空格
要在程序中忽略这些多余的空格也不复杂呀,所以我写的这个程序依然不做这个假设
假设 所有操作数均为10以内的整数
这个假设没意思吧,就支持一位数字?你用scanf读取不就可以了
假设太多了,没意思
下面说一说这个代码的思路
1. 首先写出这个语言(表达式)的文法
- start: lines (EOF);
- lines: (EMPTY)
- | line lines
- ;
- line: expression '\n' {print(expression);}
- | '\n'
- | (ERROR) {printf("错误的表达式!\n");}
- ;
- expression: term
- | expression '+' term {$$ = $1 + $3;}
- | expression '-' term {$$ = $1 - $3;}
- ;
- term: factor
- | term '*' factor {$$ = $1 * $3;}
- | term '/' factor {$$ = $1 / $3;}
- ;
- factor: NUM
- | '(' expression ')' {$$ = $2;}
- ;
复制代码
2. 消除左递归, 因为要使用递归下降分析
- expression: term expression_;
- expression_: (EMPTY)
- | '+' term expression_
- | '-' term expression_
- ;
- term: factor term_;
- term_: (EMPTY)
- | '*' factor term_
- | '/' factor term_
- ;
复制代码
编译原理教材中用的是这种方法
但是,为什么不能改成这样?
- expression: term
- | term '+' expression {$$ = $1 + $3;}
- | term '-' expression {$$ = $1 - $3;}
- ;
- term: factor
- | factor '*' term {$$ = $1 * $3;}
- | factor '/' term {$$ = $1 / $3;}
- ;
复制代码
这样也没有左递归呀,上面的那个代码用的就是这种方法,到目前为止还没有发现 有什么问题
3. 照着这个文法,用递归下降分析,写代码
4. 调试,^_^