Я пытаюсь научить грамматического генератора Ruby Treetop. Я нахожу, что не только документация, крайне жалкая для "лучшего", там, но она не работает так интуитивно, как я надеялся.
На высоком уровне мне бы очень понравился лучший учебник, чем документы на сайте или видео, если они есть.
На более низком уровне, здесь грамматики, я не могу вообще работать:
grammar SimpleTest
rule num
(float / integer)
end
rule float
(
(( '+' / '-')? plain_digits '.' plain_digits) /
(( '+' / '-')? plain_digits ('E' / 'e') plain_digits ) /
(( '+' / '-')? plain_digits '.') /
(( '+' / '-')? '.' plain_digits)
) {
def eval
text_value.to_f
end
}
end
rule integer
(( '+' / '-' )? plain_digits) {
def eval
text_value.to_i
end
}
end
rule plain_digits
[0-9] [0-9]*
end
end
Когда я загружаю его и запускаю некоторые утверждения в очень простом тестовом объекте, я нахожу:
assert_equal @parser.parse('3.14').eval,3.14
Работает нормально, а
assert_equal @parser.parse('3').eval,3
вызывает ошибку: NoMethodError: частный метод `eval ', вызываемый для #
Если я отменяю целочисленное число и float в описании, как целые числа, так и поплавки дают мне эту ошибку. Я думаю, что это может быть связано с ограниченным взглядом, но я не могу найти какую-либо информацию в любом из документов, чтобы даже охватить идею оценки в "или" контексте
Немного больше информации, которая может помочь. Здесь pp информация для обоих блоков parse().
Поплавок:
SyntaxNode+Float4+Float0 offset=0, "3.14" (eval,plain_digits):
SyntaxNode offset=0, ""
SyntaxNode+PlainDigits0 offset=0, "3":
SyntaxNode offset=0, "3"
SyntaxNode offset=1, ""
SyntaxNode offset=1, "."
SyntaxNode+PlainDigits0 offset=2, "14":
SyntaxNode offset=2, "1"
SyntaxNode offset=3, "4":
SyntaxNode offset=3, "4"
Целое число... обратите внимание, что, по-видимому, было определено, чтобы следовать правилу integer, но не поймал метод eval():
SyntaxNode+Integer0 offset=0, "3" (plain_digits):
SyntaxNode offset=0, ""
SyntaxNode+PlainDigits0 offset=0, "3":
SyntaxNode offset=0, "3"
SyntaxNode offset=1, ""
Update:
У меня возникла моя особая проблема, но я не знаю, почему:
rule integer
( '+' / '-' )? plain_digits
{
def eval
text_value.to_i
end
}
end
Это не имеет никакого смысла в документах, которые присутствуют, но просто удаляет лишние круглые скобки, в результате чего они включают класс Integer1, а также Integer0. Integer1, по-видимому, является классом, содержащим метод eval(). Я понятия не имею, почему это так.
Я все еще ищу дополнительную информацию о treetop.