Treetop ruby​​解析器 - 无法解析Ordered Choice

时间:2010-12-22 23:30:30

标签: ruby rubygems treetop peg

我已经定义了使用Treetop解析字符串和数字的简单语法,如下所示。

grammar Simple
    rule value
        number / string
    end 

    rule string
        word space string
        /
        word
    end

    rule word
        [0-9a-zA-Z]+
    end

    rule number
        [1-9] [0-9]*
    end

    rule space
        ' '+
    end
end

红宝石:

parser = SimpleParser.new
parser.parse('123abc wer') # => nil

我希望解析器返回字符串节点,但看起来解析器无法理解输入。任何想法都将不胜感激。

1 个答案:

答案 0 :(得分:4)

在Treetop(实际上是PEG)中,选择运算符是有序的,与大多数其他解析形式不同。

所以,在

rule value
  number / string
end

你告诉Treetop你更喜欢 number而不是string

您的输入以1开头, numberstring(通过word),但您告诉Treetop更喜欢number解释,因此它将其解析为number。当涉及输入中的a时,它没有更多的规则要应用,因此它不返回任何内容(nil),因为在Treetop中不消耗整个输入流是错误的。

如果您只是颠倒选择的顺序,整个输入将被解释为string而不是number

SyntaxNode+String0 offset=0, "123abc wer" (word,space,string):
  SyntaxNode offset=0, "123abc":
    SyntaxNode offset=0, "1"
    SyntaxNode offset=1, "2"
    SyntaxNode offset=2, "3"
    SyntaxNode offset=3, "a"
    SyntaxNode offset=4, "b"
    SyntaxNode offset=5, "c"
  SyntaxNode offset=6, " ":
    SyntaxNode offset=6, " "
  SyntaxNode offset=7, "wer":
    SyntaxNode offset=7, "w"
    SyntaxNode offset=8, "e"
    SyntaxNode offset=9, "r"

或者,您可以保持订单不变,但允许value规则多次匹配。插入一个新的顶级规则,如下所示:

rule values
  value+
end

或修改value规则,如下所示:

rule value
  (number / string)+
end

这将给你一个大致相同的AST:

SyntaxNode offset=0, "123abc wer":
  SyntaxNode+Number0 offset=0, "123":
    SyntaxNode offset=0, "1"
    SyntaxNode offset=1, "23":
      SyntaxNode offset=1, "2"
      SyntaxNode offset=2, "3"
      SyntaxNode+String0 offset=3, "abc wer" (word,space,string):
        SyntaxNode offset=3, "abc":
          SyntaxNode offset=3, "a"
          SyntaxNode offset=4, "b"
      SyntaxNode offset=5, "c"
    SyntaxNode offset=6, " ":
      SyntaxNode offset=6, " "
    SyntaxNode offset=7, "wer":
      SyntaxNode offset=7, "w"
      SyntaxNode offset=8, "e"
      SyntaxNode offset=9, "r"