1

我已经定义了使用 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

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

4

1 回答 1

4

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

所以,在

rule value
  number / string
end

您是在告诉 Treetop 您更喜欢 .numberstring

您的输入以 开头,它同时1匹配和(通过),但您告诉 Treetop 更喜欢解释,因此它将其解析为. 当涉及到输入时,它没有更多的规则可以应用,因此它什么也不返回 ( ),因为在 Treetop 中不消耗整个输入流是错误的。 numberstringwordnumbernumberanil

如果您只是颠倒选择的顺序,整个输入将被解释为 astring而不是 a 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"
于 2010-12-23T00:23:54.093 回答