Подтвердить что ты не робот

Обучение Treetop

Я пытаюсь научить грамматического генератора 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.

4b9b3361

Ответ 1

К сожалению, документация Treetop отстойна. Много. И примеры на веб-сайте не помогают. Я обнаружил, что у dzone есть довольно большая коллекция вершинных грамматик:

Treetop grammars

Ответ 2

Вы могли бы оценить Пола Бэттли, хороший учебник по Начало работы с Treetop

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

Ответ 5

Я последовал за этим Treetop Introductory Tutorial пару лет назад, чтобы понять основы treetop.

А затем Быстрое введение в парсер с Treetop, полезное для меня, потому что оно объясняло, как сопоставить узлы синтаксического дерева с экземплярами класса ruby.

Ответ 6

Я только что начал экспериментировать с TreeTop.

Я попробовал изменить

 rule num
      (float / integer)
 end

к

 rule num
      (float / integer)
      {
       def eval
            text_value.to_f
       end
      }
 end

И это работает.

Ответ 7

Документы Treetop, похоже, предполагают, что вы уже знаете достаточную сумму для разбора грамматических выражений выражения (PEG). Treetop полностью основан на PEG. PEGs больше, чем Treetop, хотя они также используются в других библиотеках разбора. Изучая Treetop, мне было очень полезно изучать PEG в целом. Это помогло заполнить много пробелов в документации.

Ответ 8

Это ошибка. Необязательные круглые скобки вокруг правила для целого числа приводят к созданию дополнительного модуля для определения определения eval, и этот модуль не смешивается с node, поэтому "eval" недоступен. Это можно увидеть, если сравнить код Ruby (сгенерированный с помощью команды tt) для версий с этими скобками и без них.