学习树顶

我正在尝试自学Ruby的Treetop语法生成器。 我发现,不仅文档中的“最佳”文档非常稀疏,而且它似乎并不像我希望的那样直观。

在高层次上,我真的很喜欢比现场文档或video更好的教程,如果有的话。

在较低的层次上,这是一个我根本无法工作的语法:

grammar SimpleTest rule num (float / integer) end rule float ( (( '+' / '-')? plain_digits '.' plain_digits) / (( '+' / '-')? plain_digits ('E' / 'e') plain_digits ) / (( '+' / '-')? plain_digits '.') / (( '+' / '-')? '.' plain_digits) ) { def eval text_value.to_f end } end rule integer (( '+' / '-' )? plain_digits) { def eval text_value.to_i end } end rule plain_digits [0-9] [0-9]* end end 

当我加载它并在一个非常简单的测试对象中运行一些断言时,我发现:

 assert_equal @parser.parse('3.14').eval,3.14 

工作正常,而

 assert_equal @parser.parse('3').eval,3 

引发错误:NoMethodError:调用#的私有方法`eval’

如果我反转整数并浮动描述,整数和浮点数都会给我这个错误。 我认为这可能与有限的前瞻相关,但我无法在任何文档中找到任何信息甚至涵盖在“或”上下文中进行评估的想法

更多信息可能会有所帮助。 这是parse()块的pp信息。

浮动:

 SyntaxNode+Float4+Float0 offset=0, "3.14" (eval,plain_digits): SyntaxNode offset=0, "" SyntaxNode+PlainDigits0 offset=0, "3": SyntaxNode offset=0, "3" SyntaxNode offset=1, "" SyntaxNode offset=1, "." SyntaxNode+PlainDigits0 offset=2, "14": SyntaxNode offset=2, "1" SyntaxNode offset=3, "4": SyntaxNode offset=3, "4" 

整数…请注意,它似乎已被定义为遵循整数规则,但未捕获eval()方法:

 SyntaxNode+Integer0 offset=0, "3" (plain_digits): SyntaxNode offset=0, "" SyntaxNode+PlainDigits0 offset=0, "3": SyntaxNode offset=0, "3" SyntaxNode offset=1, "" 

更新:

我遇到了我的特殊问题,但我不知道为什么:

  rule integer ( '+' / '-' )? plain_digits { def eval text_value.to_i end } end 

这对于存在的文档没有意义,但只是删除了额外的括号使得匹配包括Integer1类和Integer0。 Integer1显然是持有eval()方法的类。 我不知道为什么会这样。

我还在寻找有关树顶的更多信息。

可悲的是,Treetop的文档很糟糕。 很多。 网站上的示例没有帮助。 我发现dzone有很多treetop语法集合:

树梢语法

您可能会欣赏Paul Battley在Treetop入门中的简单教程

从最小的语法开始,他展示了如何创建解析器,然后通过几次迭代添加了一些function。 这足以让我走出起跑线。

Roland Swingler向LRUG发表了关于Treetop的演讲: http ://skillsmatter.com/podcast/ajax-ria/treetop我发现它很有用。

Citrus是树梢上更轻松的替代品: http : //github.com/mjijackson/citrus

几年前我遵循了这个Treetop入门教程 ,以了解树梢的基础知识。

然后快速介绍用Treetop编写解析器 ,对我很有用,因为它解释了如何将语法树节点映射到ruby类实例。

我刚开始尝试使用TreeTop。

我试着改变了

  rule num (float / integer) end 

  rule num (float / integer) { def eval text_value.to_f end } end 

它似乎工作。

Treetop文档似乎假设您已经了解了大量有关解析表达式语法 (PEG)的知识。 树顶完全基于PEG。 虽然PEG比Treetop更大,但它们也用于其他解析库。 在学习Treetop时,我发现一般来说研究PEG非常有帮助。 这有助于填补文档中的许多空白。

这是一个错误。 整数规则周围不必要的括号会导致构造额外的模块以包含eval的定义,并且此模块不会混入节点,因此’eval’不可用。 如果比较使用和不使用这些额外括号的Ruby代码(使用tt命令生成),您可以清楚地看到这一点。