我已经定义了使用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
我希望解析器返回字符串节点,但看起来解析器无法理解输入。任何想法都将不胜感激。
答案 0 :(得分:4)
在Treetop(实际上是PEG)中,选择运算符是有序的,与大多数其他解析形式不同。
所以,在
rule value
number / string
end
你告诉Treetop你更喜欢 number
而不是string
。
您的输入以1
开头, number
和string
(通过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"