java开发编译器:构建LR语法的有限状态自动机

构建LR语法的有限状态自动机

大家好,欢迎大家来到Coding迪斯尼。

阅读博客的朋友可以到我的网易云课堂中,通过视频的方式查看代码的调试和执行过程:

http://study.163.com/course/courseMain.htm?courseId=1002830012

我开启了新的算法课程:
如何进入google,算法面试技能全面提升指南
http://study.163.com/course/courseMain.htm?courseId=1002942008

在课程中,我将facebook, google, ms,amazon, BAT等公司使用的面试算法题收集起来进行分析,喜欢算法,特别是准备面试,冲击一线互联网公司的朋友不要错过。

前一节,我们看到,要使用LR语法来解析输入文本,需要根据语法规则构建一个有限状态自动机,然后根据自动机创建一个解析表,然后我们的解析程序才能依赖解析表对输入文本进行解析。本节我们主要研究,在给定了LR语法后,有限状态自动机是如何构建的。

我们先给定一组LR语法,如下:
0. s -> e
1. e -> e + t
2. e -> t
3. t -> t * f
4. t -> f
5. f -> ( e )
6. f -> NUM

当利用本节的算法后,上面语法将构建出如下形式的有限状态自动机:

这里写图片描述

上面的图看起来复杂凌乱,只要大家理解了本节描述的算法,上面的状态机图完全可以由程序自动生成。

接下来我们看看,构建算法的具体步骤:
(1) 初始化:状态0是状态机的初始状态,它包含着语法表达式中的起始表达式,也就是编号为0的表达式:
0
s -> . e
表达式我们做了一些更改,就是在表达式 -> 右边, 它跟着一个符号 “.”, 这个点的作用很重要。

(2) 对 . 右边的符号做闭包操作:如果 . 右边的符号是一个非终结符,那么肯定有某个表达式,-> 左边是该非终结符,把这些表达式添加进来,当前,. 右边的非终结符是 e, 于是把 e在 -> 左边的表达式添加进来:
0
s -> . e
e -> . e + t
e -> .t

对于新加进来的表达式,如果 . 右边的非终结符对应的表达式没有加进来,则继续将他们对应的表达式添加进来,根据上面的例子,我们需要把 t 对应的表达式添加进来:
0
s -> . e
e -> . e + t
e -> . t
t ->. t * f
t -> . f
继续重复闭包操作,新引入的表达式中,. 右边的非终结符f 对应的表达式还没有引入,于是下一步是引入f 对应的表达式:
0
s -> . e
e -> . e + t
e -> . t
t ->. t * f
t -> . f
f -> . ( e )
f -> . NUM
由于引入的表达式, . 右边都是终结符,所以闭包操作结束。

(3) 对引入的表达式进行分区:把 . 右边拥有相同非终结符的表达式划入一个分区:
0
e -> . t
t -> . t * f
s -> . e
e -> . e + t
f -> . NUM
f -> . ( e )
t -> . f

把每个分区中的表达式中的 . 右移动一位,形成新的状态节点,例如第一个分区中,表达式中的 . 右移一位后生成新节点1:
1
e -> t .
t ->t . * f

第二个分区表达式, . 右移一位后形成新的节点2:
2
s -> e .
e ->e . + t

第三个分区, . 右移一位后形成新的节点3:
3
f -> NUM .

第四个分区, . 右移动一位后形成新的节点4:
4
f -> ( . e )

第5个分区,. 右移动一位后形成新的节点5
5
t -> f .

(4) 构建原有节点与新生节点间的跳转关系
由于节点1表达式中, . 左边的符号是 t, 所以当状态机处于状态0时,输入时 t 时, 跳转到状态1:
0 – t -> 1

由于节点2表达式中,. 左边的符号是e, 所以当状态机处于状态 0 ,且输入时符号e时,跳转到状态2:
0 – e -> 2

由于节点 3 表达式中, . 左边的符号是 NUM, 所以当状态机处于状态 0 , 输入是符号 NUM时,跳转到状态 3:
0 – NUM -> 3

由于节点4表达式中,. 左边的符号是 (, 所以当状态机处于状态0,输入是 ( 时, 状态机跳转到状态4:
0 – ( -> 4.

由于节点5表达式中,. 左边的符号是f, 所以当状态机处于状态0,输入是符号 f 时,状态机由状态0跳转到状态5:
0 – f -> 5.

对每个新生成的状态节点重复上面的算法,最终将构成给定的状态机图。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值