Treetop грамматика бесконечный цикл

У меня были некоторые идеи относительно нового языка программирования, плавающего в моей голове, поэтому я решил попробовать его реализовать. Друг предложил мне попробовать использовать Treetop (самоцвет Ruby) для создания парсера. Документация Treetop редкая, и я никогда раньше такого не делал.

Мой парсер работает так, как будто в нем бесконечный цикл, но без следов стека; это трудно отследить. Может кто-нибудь направить меня в сторону руководства по разбору /AST начального уровня? Мне действительно нужно что-то, что перечисляет правила, общее использование и т. Д. Для использования инструментов, таких как Treetop. Мой грамматик парсера находится на GitHub, на случай, если кто-то захочет помочь мне улучшить его.

class {
  initialize = lambda (name) {
    receiver.name = name
  }

  greet = lambda {
    IO.puts("Hello, #{receiver.name}!")
  }
}.new(:World).greet()

2 ответа

Я попросил treetop скомпилировать ваш язык в файл.rb. Это дало мне кое-что, чтобы покопаться:

$ tt -o /tmp/rip.rb /tmp/rip.treetop

Затем я использовал эту маленькую заглушку, чтобы воссоздать цикл:

require 'treetop'
load '/tmp/rip.rb'
RipParser.new.parse('')

Это висит. Разве это не интересно! Пустая строка воспроизводит поведение так же хорошо, как пример с дюжиной строк в вашем вопросе.

Чтобы выяснить, где он висит, я использовал макрос клавиатуры Emacs для редактирования rip.rb, добавив оператор отладки в запись каждого метода. Например:

def _nt_root
  p [__LINE__, '_nt_root'] #DEBUG
  start_index = index

Теперь мы можем увидеть область действия цикла:

[16, "root"]
[21, "_nt_root"]
[57, "_nt_statement"]
...
[3293, "_nt_eol"]
[3335, "_nt_semicolon"]
[3204, "_nt_comment"]
[57, "_nt_statement"]
[57, "_nt_statement"]
[57, "_nt_statement"]
...

Дальнейшая отладка показывает, что целое число может быть пустой строкой:

rule integer
   digit*
end

Это косвенно позволяет оператору быть пустой строкой и правилом верхнего уровня statement* навсегда потреблять пустые заявления. изменения * в + исправляет цикл, но выявляет еще одну проблему:

/tmp/rip.rb:777:in `_nt_object': stack level too deep (SystemStackError)
        from /tmp/rip.rb:757:in `_nt_compound_object'
        from /tmp/rip.rb:1726:in `_nt_range'
        from /tmp/rip.rb:1671:in `_nt_special_literals'
        from /tmp/rip.rb:825:in `_nt_literal_object'
        from /tmp/rip.rb:787:in `_nt_object'
        from /tmp/rip.rb:757:in `_nt_compound_object'
        from /tmp/rip.rb:1726:in `_nt_range'
        from /tmp/rip.rb:1671:in `_nt_special_literals'
         ... 3283 levels...

Диапазон является рекурсивным влево, косвенно, через special_literals, literal_object, object и component_object. Верхушка дерева при столкновении с левой рекурсией съедает стек до тех пор, пока его не стошнит. У меня нет быстрого решения этой проблемы, но, по крайней мере, теперь у вас есть трассировка стека.

Кроме того, это не ваша непосредственная проблема, но определение digit нечетно: может быть либо одна цифра, либо несколько. Это вызывает digit* или же digit+ разрешить (предположительно) незаконное целое число 1________2,

Мне очень понравились шаблоны реализации языка от Parr; Поскольку Парр создал генератор синтаксических анализаторов ANTLR, это инструмент, который он использует на протяжении всей книги, но он должен быть достаточно простым, чтобы учиться на нем.

Что мне действительно понравилось в этом, так это то, как каждый пример вырос по сравнению с предыдущим; он не начинает с гигантского синтаксического анализатора, способного работать с AST, вместо этого он медленно вводит проблемы, для выполнения которых требуется все больше и больше "умных механизмов", поэтому книга хорошо масштабируется вместе с языком, требующим синтаксического анализа.

Что бы я хотел, чтобы это было немного более подробно, это типы языков, на которых можно писать и давать советы о том, что можно и чего нельзя делать при разработке языков. Я видел несколько языков, которые очень трудно анализировать, и мне бы хотелось узнать больше о тех дизайнерских решениях, которые могли быть приняты по-другому.

Другие вопросы по тегам