两百行写一个递归下降解析器
来源:互联网 发布:必利劲有依赖性吗 知乎 编辑:程序博客网 时间:2024/04/29 21:32
最近看到Peter Cooper 用Ruby 实现了一个Recursive Descent Parser。让我惊讶的是,作者仅仅用了255 行Ruby 代 码就实现了。于是我决定分析一下这个神奇的rdparser。
先看看它怎么用吧。
初始化需要定义语法规则:如果左边是终结符,右边对于正则表达式;如果是非终结符,对于非终结符或终结符组成的字符串。并列规则用竖线("|")连接。
输出如下:
对照下面的图就更明白一些了。
图上有一些位置上的错误,比如brkt-expression 的子结点从左至右的顺序应是(, expression, )。我是用ruby-graphviz 画的,有些问题还没找到解决办法。
rdparser 先把输入规则转换成hash。传给parse_section 分析,得到一个类似s-exp 的数列。最后交给text_syntax_tree 显示出来。
首先分析它是怎么把rules 转变成hash 的。我把代码简化了一下。
yield 获得代码块想调用g.×× 但没找到,这时发现了method_missing,把方法名和原本要传递给××方法的所有参数传递给它。
这里还要解释一下
经常看到这种用法,这次好好地查了一下。相当于以下代码:
这是用来检查是否定义了@h。
接着把起始规则(:main)和待解析的字串(content)传给parse。
to_sym 是把字符串变为symbol。Scanner 是作者定义的一个包装类。Scanner.new 其实很简单。
其中用到了strscan 库的StringScanner 类。strscan是一个字符串扫描器库。StringScanner 对象是由被扫字符串和"扫描点"构成的. 扫描点是一个索引值,它表示已扫描的位置. 刚开始的时候, 扫描点位于字符串头部, 此时(且只有此时)扫描点将尝试进行匹配. 若匹配成功则推进扫描点.
重点是parse_section。伪代码:
parse_section(rule)
@depth += 1
rule 对应的各条并列的语法规则ruleset :
对ruleset 的各个语法元素r :
suboutput = []
如果当前字符串的某个前缀能匹配上r :
把[{非终结符=>匹配的字串}] 添加进suboutput
如果全匹配上了 :
@depth -= 1
return output
框架如下:
sub_rulesets 把那些用竖线(“|”)分隔的规则断开。而sub_rules 把各条规则用空格断开的语法单元全部抽出来。接着一个接一个地分析这些语法元素。主要是根据后缀(s 就相当于正则表达式中的+,? 和正则表达式中的? 作用一模一样)分类讨论。
最后一个关键:match_for_rule,用来根据语法规则解析字串的内容。
Peter 还提供了一个显示词法解析树的打印程序:
如果是数组就依次显示各个元素;如果是hash 表,才进入正题,根据depth 缩进显示。
抛开注释和调试语句,真正的程序不到161 行。啊,god-like。
顺便说一句,把DEBUG 置为true 就可以看到浩如烟海的调试信息。作者调试的方法很有趣。还记得Ruby 的每条语句都是一个表达式吗,还记得布尔表达式的短路求值吗?
如果DEBUG 为false,就不会执行debug_message。
P.S.: 看了代码之后觉得Peter 大哥很牛,去翻了一下他的主页,原来他是Ruby Inside 的写手,写过N多作品。总之,神牛!
- 两百行写一个递归下降解析器
- 70 行 Python 代码编写一个递归下降解析器
- 一个递归下降的数字表达式解析器
- 递归下降方式的运算解析器
- 递归下降的表达式解析器
- java实现递归下降的表达式解析器
- 递归下降的带变量的表达式解析器
- 如何写一个递归!
- 20170219C++项目班02_02递归下降算法/解析器/Scanner实现
- 从一个小巧的计算器,体会递归下降的方法
- 如何写一个递归程序
- 怎么写一个递归程序
- 一起写一个JSON解析器
- 一起写一个 JSON 解析器
- 用递归个方式写dom解析
- 递归下降分析程序
- 递归下降分析法
- 递归下降分析子程序
- 有过完一学期了!!
- SET不同!(补3月6日的作业)
- TCP不适用于实时传输的原因
- (转)我们三十以后才明白
- 如何手写代码以生成Composite图表?
- 两百行写一个递归下降解析器
- 我们毕业了。
- java读大文件
- web标准化设计:常用的CSS命名规则
- 位图在内存中的存储方式
- 使用gdb调试多线程
- 开放源代码
- 测试中如何使用自动化脚本?
- 增量模型(Incremental Model)