我想自学ruby的树梢语法生成器。我发现,对于“最好的”文档来说,文档不仅少得可怜,而且看起来并不像我所希望的那样直观。
在高层次上,我真的很喜欢一个比现场文档或视频更好的教程,如果有的话。
在较低的层次上,这里有一个语法我根本无法工作:

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'#
如果我在描述中反转integer和float,那么integer和float都会给出这个错误。我认为这可能与有限的展望有关,但我在任何文档中都找不到任何信息,甚至无法涵盖在“或”上下文中进行评估的想法
更多可能有用的信息。下面是这两个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()方法的类。我不知道为什么会这样。
我还在寻找更多关于树梢的信息。

最佳答案

可悲的是,树顶的文件很糟糕。很多。网站上的例子也没有帮助。我发现Dzone有很多树梢语法:
Treetop grammars

07-28 06:06