17

我正在尝试自学 Ruby 的 Treetop 语法生成器。我发现,对于那里的“最佳”文档而言,不仅文档非常稀少,而且它似乎不像我希望的那样直观地工作。

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

在较低级别上,这是我根本无法使用的语法:

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: private method `eval' called for #

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

更多信息可能会有所帮助。这是这两个 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"

Integer... 请注意,它似乎已被定义为遵循整数规则,但未捕获 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() 方法的类。我不知道为什么会这样。

我仍在寻找有关树梢的更多信息。

4

8 回答 8

17

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

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

于 2009-12-30T04:01:33.460 回答
10

可悲的是,Treetop 的文档很烂。很多。并且网站上的示例没有帮助。我发现 dzone 有大量的树顶语法:

树顶文法

于 2009-02-10T16:00:38.377 回答
3

Roland Swingler 向 LRUG 介绍了 Treetop: http ://skillsmatter.com/podcast/ajax-ria/treetop ,我发现它对入门很有用。

于 2010-03-22T08:38:54.377 回答
3

Citrus 是一种比树梢更轻的替代品:http: //github.com/mjijackson/citrus

于 2010-07-07T13:57:15.530 回答
2

几年前,我遵循了这个Treetop Introductory Tutorial来了解 treetop 的基础知识。

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

于 2013-09-06T16:36:26.213 回答
1

我刚刚开始尝试使用 TreeTop。

我试过改变

 rule num
      (float / integer)
 end

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

它似乎有效。

于 2009-09-11T17:16:27.673 回答
1

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

于 2014-11-18T23:22:00.390 回答
0

Treetop 文档似乎假设您已经对解析表达式语法(PEG) 有相当多的了解。Treetop 完全基于 PEG。PEG 不仅限于 Treetop,即它们也用于其他解析库。在学习 Treetop 时,我发现学习一般的 PEG 非常有帮助。这有助于填补文档中的许多空白。

于 2012-10-26T04:30:05.527 回答