stanford compiler学习笔记(一)

lexical analysis:

根据输入,输出Tokens,即<Token Class, Lexeme>二元组。如<Identifier, "abc">, <key word, "if">, <Number, "1234"> etc.

look ahead sometimes


parse tree

叶子节点:终结符

内节点:非终结符


对上下文无关文法的展开(derivation):最左展开(left-most derivation),最右展开(right-most derivation)

正确的上下文无关文法应该能消除最左和最右展开的歧义,即无论哪种展开,都能返回一致的解析树。


消除歧义:

1. 重写文法

2. 将*/等高优先级操作符置于+-之前。


错误处理

1. panic mode

放弃当前token,直到找到下一个能够匹配的(略过当前statement/expression, etc)

e.g., (1+ +2) +3

1+之后期待另一个int,略过第二个+。直到2。


2. Error productions(错误产生式)

修改产生式:E--> int | E+E | (E) | error int | (error)

error int表示放弃当前token,直到遇到int为止。

注意修改产生式会使语法复杂化。


3. Automatic local or global correction

如短语层次的恢复:将一个逗号替换为分号,删除一个多余的分号或者插入一个遗漏的分号,等。


抽象语法树

精简的parse tree。


自顶向下(TOP-DOWN)构建语法树:

递归下降(Recursive Descent)

按照产生式,从上至下,逐条测试(若发现不匹配会有回溯)

E-->T

bool E1(){ return T();}

E-->T+E

bool E2(){ return T() && term(PLUS) && E();}

E->T | T+E

bool E(){
    TOKEN *save=next;
    return (next=save, E1()) 
        || (next=save, E2());
}

问题:

对于S--> Sa的产生式:

bool S1(){ return S() && term(a);}
bool S(){ return S1();}
产生式的最左端为非终结符,这种情况下,递归下降会产生死循环。

重写产生式,将左递归写为右递归。


将形如下列的左递归产生式:

S-->Sa1 | .... | San | b1 | ... | bm

重写为:

S-->b1S' | ... | bmS'

S'-->a1S' | ... | anS' | ε

(消除左递归)



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值