Compiler 学习之Parsing(1)

我实在是不怎么能写博客。。。就当Coursera课程的笔记了。

parsing是继lexical analysis之后的第二个内容,在我们完成了Lexical analysis之后,我们需要将输入的token对组成一个Parse Tree,为后来的语义分析做准备。那么Parsing到底有哪些内容呢?

Context Free Grammar,Derviation, Recursive Decent Algorithm, Bottom-up Parsing等等,我们一个一个看。


一: Context Free Grammar 又叫 CFG, 根据 CFG的定义,它包含以下几个方面:

{

a set of terminals;

a set of non-terminals;

a start symbol (non-terminals);

a set of production (can be anything);

}

先解释以下terminal 和non-terminal的问题,terminal是parsing中的最后单元,它不能被解释成其它东西了,好比说数字 int(我们不关心int的具体值),操作符(*+-/),关键字。而non-terminal是一种抽象的标号,它可以被解释成terminal或者non-terminal。看一个例子:

E -> E + E | E - E | E * E | E / E | int | epsilon

这句话的意思就是 E可以被解释成以下集中形式 E + E, E - E ..., 其中包括 int这样的 terminal还有一个特殊的符号 epsilon(它表示空)。 值得注意的是这种解释方法和Regular Expr很相近,其中的 '|' 和 Regular Expr 当中的 '|' 有相同的作用,“可以将E替换成右边的任何一种 production”。

总结以下,对CFG的操作:

1:从 Start Symbol开始(通常叫S);

2:将左边的任何一个non-terminal 替换为Production;

3:重复第二步知道没有全部都为terminal位置;


顺便我们可以定义CFG的 语言 L(G): 所有可以被G规则解释出来的字符串,我们就认为它在G的语言中(In the language of G)。

不幸的是,识别两种Grammar是否相同是一种non-trival的工作。由于很多时候你不能穷举所有在Language中的String,所以我们只能取写出一个足够好的Grammar,让它识别String是否在L(G)中。


二:Derviation:这是我们得到Parse Tree的方法。

一般构建的方法有两种,left most 和 right most, 它们是指我们要从当前的Production中的最左边的non-terminal开始还是从最右边的开始,该non-terminal可以被展开为Grammar当中的任何一种规则。

由于之前的CFG只能告诉我们一个string是否在L(G)中,我们确实需要一种方法来构建Parse树,还是举个例子:

假设我们的CFG为 "E -> E + E | E * E | (E) | id", 要匹配的string是 id * id + id, 则我们可以这样构建

     E                                                        E

-> E + E                                                /    \

-> E * E + E                                        E   +  E

-> id * E + E                                     /   \        |

-> id * id + E                                 E   *  E     id

-> id * id + id                                |        | 

                                                    id       id

同时我们又可以这么构建:

   E                                                      E
-> E * E                                             /   \
-> E * E + E                                     E  *  E
-> id * E + E                                     |   /   \
-> id * id + E                                  id  E  +  E
-> id * id + id                                       |     |
                                                           id    id
这样就带了了ambiguity, and ambiguity is BAD! 下一篇我们在讨论ambiguity

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值