我已经定义了简单的语法,用于使用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

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

有帮助吗?

解决方案

在Treetop中(实际上,实际上是PEG)选择操作员是 订购, ,与大多数其他解析形式主义不同。

所以,在

rule value
  number / string
end

你在告诉树梢你 更喜欢 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"
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top