- 作者:zhaozj
- 发表时间:2020-12-23 10:55
- 来源:未知
LET'S BUILD A COMPILER!(3)---第二部分:表达式分析续
括号
我们可以为分析器添加进处理括号的部分。括号是一种强制改变运算优先次序的机制。比如,表达式 2*(3+4) ,
括号强制使加法在乘法之前运算。更重要的是,括号为我们提供了一种定义任意复杂度的表达式的机制。比如表达式 (1+2)/((3+4)+(5-6))
将对括号的处理加到我们的分析器中,其关键在于认识到一个被括号括起来的表达式无论它有多复杂,相对于括号外的其他部分来说它看起来只是相当于一个简单的因子而已。所以term的一种表示形式就是: <factor> ::= (<expression>)
这已经涉及到递归的概念。一个表达式可以包含term,而这个term也可以包含另一个表达式,这个表达式又可以包含term…….以至于无穷。
不管它是否看起来很复杂,我们只要加进少数几条语句到Factor过程中就可以解决这个问题。
{---------------------------------------------------------------}
{ 分析并翻译因子 }
procedure Expression; Forward;
procedure Factor;
begin
if Look = '(' then begin
Match('(');
Expression;
Match(')');
end
else
EmitLn('MOVE #' + GetNum + ',D0');
end;
{--------------------------------------------------------------}
请再次留意,我们对这个分析器的扩展是很容易的,并且这些代码与BNF产生式匹配得也很好。
像以前一样,编译运行这个新版本的分析器,确保它能正确地分析合法的语句,并对非法语句给出错误信息。
一元减法
到现在为止,我们似乎已经能让这个分析器处理任何形式的表达式了,是这样吗?OK,输入这个语句试试: -1
噢!它不能正常工作,是吗?Expression过程希望每个表达式都以一个整数开始,所以它不能识别开头的减号。你会发现分析器不能识别+3,也不能识别 -(3-2) .这样的表达式。
有两种方法解决这个问题。最简单的方法(尽管不是最好的方法)是假想成表达式开头有一个0,所以-3就变成了0-3。我们可以很容易的用这种方法修正Expression现存的版本。
{---------------------------------------------------------------}
{分析并翻译表达式}
procedure Expression;
begin