【问题标题】:Learning Treetop学习树梢
【发布时间】:2009-02-06 15:51:44
【问题描述】:

我正在尝试自学 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() 方法的类。我不知道为什么会这样。

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

【问题讨论】:

    标签: ruby parsing grammar treetop


    【解决方案1】:

    您可能会喜欢 Paul Battley 在 Getting started with Treetop

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

    【讨论】:

      【解决方案2】:

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

      Treetop grammars

      【讨论】:

      • 谢谢 ;) 我会解决的
      • 祝你好运!也许你可以在完成后写一些文章/教程?
      • 很遗憾该页面由于某种原因被禁用。
      • @Geo 链接似乎已损坏。
      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        柑橘是比树梢更轻的替代品:http://github.com/mjijackson/citrus

        【讨论】:

          【解决方案5】:

          几年前我关注了Treetop Introductory Tutorial,以了解树梢的基础知识。

          然后是A quick intro to writing a parser with Treetop,对我很有用,因为它解释了如何将语法树节点映射到 ruby​​ 类实例。

          【讨论】:

            【解决方案6】:

            我刚刚开始尝试使用 TreeTop。

            我尝试了改变

             rule num
                  (float / integer)
             end
            

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

            而且它似乎有效。

            【讨论】:

              【解决方案7】:

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

              【讨论】:

                【解决方案8】:

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

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2011-05-06
                  • 2013-04-21
                  • 1970-01-01
                  • 2011-06-23
                  • 2011-01-29
                  • 1970-01-01
                  • 2016-12-29
                  相关资源
                  最近更新 更多