Ответ 1
К сожалению, документация Treetop отстойна. Много. И примеры на веб-сайте не помогают. Я обнаружил, что у dzone есть довольно большая коллекция вершинных грамматик:
Я пытаюсь научить грамматического генератора 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.
К сожалению, документация Treetop отстойна. Много. И примеры на веб-сайте не помогают. Я обнаружил, что у dzone есть довольно большая коллекция вершинных грамматик:
Вы могли бы оценить Пола Бэттли, хороший учебник по Начало работы с Treetop
Начиная с минимальной грамматики, он показывает, как создать парсер, а затем через пару итераций добавляет немного функциональности. Этого было достаточно, чтобы вытащить меня из стартовых блоков.
Роланд Свинглер выступил с докладом о Treetop LRUG: http://skillsmatter.com/podcast/ajax-ria/treetop что я нашел полезным начать работу.
Citrus - гораздо более легкая альтернатива верхушке верхушки: http://github.com/mjijackson/citrus
Я последовал за этим Treetop Introductory Tutorial пару лет назад, чтобы понять основы treetop.
А затем Быстрое введение в парсер с Treetop, полезное для меня, потому что оно объясняло, как сопоставить узлы синтаксического дерева с экземплярами класса ruby.
Я только что начал экспериментировать с TreeTop.
Я попробовал изменить
rule num
(float / integer)
end
к
rule num
(float / integer)
{
def eval
text_value.to_f
end
}
end
И это работает.
Документы Treetop, похоже, предполагают, что вы уже знаете достаточную сумму для разбора грамматических выражений выражения (PEG). Treetop полностью основан на PEG. PEGs больше, чем Treetop, хотя они также используются в других библиотеках разбора. Изучая Treetop, мне было очень полезно изучать PEG в целом. Это помогло заполнить много пробелов в документации.
Это ошибка. Необязательные круглые скобки вокруг правила для целого числа приводят к созданию дополнительного модуля для определения определения eval, и этот модуль не смешивается с node, поэтому "eval" недоступен. Это можно увидеть, если сравнить код Ruby (сгенерированный с помощью команды tt) для версий с этими скобками и без них.