Treetop 入门

来源:互联网 发布:苹果6s数据在哪里设置 编辑:程序博客网 时间:2024/06/08 15:23

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 在同一目录下)

 

原创粉丝点击