Treetop 入门

Treetop

Treetop 是一个出奇简单的Ruby 写的解析器。我知道Treetop 是因为看到Nathan Sobo在RubyConf 2007上做的一个报告

第一步:安装Treetop

第二步:新建一个叫arithmetic 的.treetop 文件

第三步:测试一下

done!

语法结构:

 

关键字grammar 定义一个新的语法。rule 定义这个语法的一条解析规则,rule 后面跟的名字可以被其他rule 引用。

每条rule 名都对应了一条解析规则。解析规则由终结符(Terminal Symbols)、非终结符(Nonterminal Symbols)和一些类似 正则表达式的特殊操作组成。终结符有:单引号或双引号括起来的字串、字符集、通配符(the anything symbol ".")。非终结符就是其他rules 的名字。前面提到的特殊操作包括:有序选择(Ordered Choice "/")、序列(Sequences)、出现次数("*+?")、前向断言(Lookahead Assertions "&!")。

其中有序选择是最不同于正则表达式的地方。有序选择可以看作一系列并列的rules (就像正则表达式中的"|"),不过匹配的时候是按从左至右的顺序,一旦匹配上就不再试探后面的规则。比如:

"foobar" / "foo" / "bar"

如果"foo" 在前,则"foobar" 永远不可能匹配上。

这是项很有用的技术,用它可以产生优先级。

光有语法还不足以解析表达式,还有配上语义解释。语义解释就是在识别语法单元的时候执行某些操作(比如:求值)。有两种方式为rule 添加动作。一种是在定义的时候嵌入方法。比如:

 

当方法太长时,还可以像JSP 那样做个标签,在专门的.rb 文件中定义相应的动作。

 

介绍几个Treetop::Runtime::SyntaxNode 的方法:

  • terminal?   当前结点是否由一个终结符产生?
  • nonterminal?   当前结点是否由一个非终结符产生?
  • text_value     返回一个String,当前结点所对应的输入子串。
  • elements    只能用于非终结结点。返回一个Array,里面是已解析出来的SyntaxNode 对象。

Treetop 使用起来很方便 bla, bla, bla.

James Coglan

heist 的作者jcoglan 写了一个tini Scheme 解释器,还贡献了胶片视频

还记得Lisp 吗?Scheme 是Lisp 的一个变种。这已不是第一个Ruby 写的Lisp 解释器了。Phil Hagelberg 写过James Coglan 写过Jim Weirich 写过……

这么多人热衷于用Scheme 来练手就是因为它实在是太简单了。一对圆括号把一个操作符、一堆操作数括起来,像这样:(op arg1 arg2 ... argn) 这就是传说中的list。

请看下面Treetop 版的Lisp 语法。

lisp.treetop

 

你看懂了吗?我的理解是:Lisp 程序由若干cell 构成;cell 的前后有若干space,中间要么是list,要么是atom;list 是圆括号括起来的若干cell;atom 有两种,datum 和identifier;datum 要么是boolean,要么是整数;boolean 只有#t 和#f;identifier 是没有前导空格或前导括号的任意字串。

function.rb

 

lisp.rb

 

scheme.rb

 

scope.rb

 

测试文件test.scm

 

执行(说明一下:lisp.treetop, function.rb, lisp.rb, scheme.rb, scope.rb 在lib 目录下;test.scm 和lib 在同一目录下)

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值