Treetop Ruby Parser - не мог разобрать заказанный выбор
Вопрос
Я определил простую грамматику для разбора строки и числа, используя 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 (и в целом, на самом деле) оператор выбора упорядоченный, в отличие от большинства других формализмов.
Итак, в
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
Что даст вам примерно так:
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"