从零开始开发JVM语言(五)语法分析

目录戳这里

上一篇描述了“四则运算”乃至任何二元运算都适用的解析。这一篇继续讲述语法分析的内容。

语法分析从Token根节点开始,跑完整个序列,最终生成AST

那么,可以从最简单的表达式,例如四则运算入手,也可以从最顶级的语句Statement入手。

parse_statement()

这个方法将开始将输入串看作一个statement进行解析。

这时候可以了解一下“产生式”。(至于BNF,如果用语法分析器生成器,例如yacc,可以仔细研究一下,否则大致知道,不会写错就好了。BNF的规则很简单的。。)

什么叫产生式呢

例如

val n = 2 * 3

这是一个表达式Expression,它定义了一个变量,所以它也是VariableDef。那么它是语句Statement吗?是的,它也是语句

可以有

Statement -> Expression
Expression -> VariableDef
VariableDef -> modifier VariableDef
            -> validName : TypeSpec
            -> validName : TypeSpec = Expression
            -> validName = Expression

产生式大致可以这么写。

使用递归下降,可以写出这样的方法(伪代码)

parse_statement()
    if current is Modifier
        parse_modifier()
    if current is VariableDef
        parse_variableDef()
    ...
parse_modifier()
    ...
    if current is VariableDef
        parse_variableDef()
    ...
parse_variableDef()
    ...

写出来的形式与“产生式”几乎一模一样。

这里也许会需要向前多读几个字符以确定匹配哪种生成式。

比如

val n = 2 * 3
^
是Modifier,也许是VariableDef

val n = 2 * 3
    ^
是合法的变量名,也许是VariableDef。也有可能是方法定义,例如val n() 所以再读一位

val n = 2 * 3
      ^
是等于号,那跑不了,就是VariableDef了

当然,还有另一种思路,遇到任何一个Token就立即解析。解析依据不但是后续的串,还有已经解析完毕存放在栈中的“中间结果”

val n = 2 * 3
^
这是个Modifier,先记录一下

[val]
val n = 2 * 3
    ^
是合法的变量名,先把它解析出来。由于附带了个Modifier,把它也加上去。由于有Modifier,那(val n)这一小块一定是VariableDef

[]
[(val n)]
val n = 2 * 3
      ^
等于号,那就是给(val n)赋值,取出值然后解析`Expression`,最后存入(val n=2*3)

这种方式叫做移进-归约,从结束符开始逆推产生式

实际上,parser的写法并不难,代码量也不多(相比Spring这样的库,动不动一个“非核心”文件就得6000多行比起来代码量简直忽略不计啊!)。它不是一个技术活。编译原理中的文法限制摆在手写parser面前都不是事。

即使你设计的文法是一个上下文有关文法,你也可以将上下文传入并解析。理论只是为了更好的实践,而不是对实践进行限制。

希望看官能够关注我的编译器哦~Latte

PS:说实话,我对语法分析研究并不深入,只是拿着两种最基本的理论一路走到黑。这也是手写Parser的一个好处:管他什么理论呢,怎么着都能写出来(其实用生成器比手写还要简单,只是生成器本身的理论并不简单)。许多人都说,看龙/虎书,一个星期就能撸个Parser,确实如此。仅仅是_做出_一个Parser需要的理论,即使这个人对自动机、形式语言一窍不通,一个星期的时间也确实能学懂。 就像大学里“编译原理”或者“形式语言”考试,牛人只要一天的"预习"就能80+。 由于手写的“繁杂”,造成错误报告和错误恢复特别容易写,提示也更加人性化。

转载于:https://my.oschina.net/wkgcass/blog/686834

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值