Изучение Treetop - PullRequest
       34

Изучение Treetop

16 голосов
/ 06 февраля 2009

Я пытаюсь научить себя грамматическому генератору Ruby's 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 'вызван для #

Если я переверну целое число и число с плавающей запятой в описании, то и целые числа, и число с плавающей запятой выдаст мне эту ошибку. Я думаю, что это может быть связано с ограниченным прогнозом, но я не могу найти какую-либо информацию в любом из документов, чтобы даже охватить идею оценки в «или» контексте

Немного больше информации, которая может помочь. Вот информация о 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"

Целое число ... обратите внимание, что, похоже, оно определено как правило целых чисел, но не перехватило метод eval ():

SyntaxNode+Integer0 offset=0, "3" (plain_digits):
  SyntaxNode offset=0, ""
  SyntaxNode+PlainDigits0 offset=0, "3":
    SyntaxNode offset=0, "3"
    SyntaxNode offset=1, ""

Обновление:

У меня сработала конкретная проблема, но я понятия не имею, почему:

  rule integer
    ( '+' / '-' )? plain_digits
     {
      def eval
        text_value.to_i
      end
    }
  end

Это не имеет смысла для документов, которые присутствуют, но просто удаление лишних скобок сделало совпадение как с классом Integer1, так и с Integer0. Integer1, по-видимому, является классом, содержащим метод eval (). Я понятия не имею, почему это так.

Я все еще ищу больше информации о верхушке дерева.

Ответы [ 8 ]

15 голосов
/ 30 декабря 2009

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

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

10 голосов
/ 10 февраля 2009

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

Грамматика верхушек деревьев

3 голосов
/ 07 июля 2010

Цитрус - намного более легкая альтернатива верхушке дерева: http://github.com/mjijackson/citrus

3 голосов
/ 22 марта 2010

Роланд Свинглер выступил с презентацией на Treetop для LRUG: http://skillsmatter.com/podcast/ajax-ria/treetop что я нашел полезным начать.

2 голосов
/ 06 сентября 2013

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

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

1 голос
/ 11 сентября 2009

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

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

 rule num
      (float / integer)
 end

до

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

И, похоже, работает.

0 голосов
/ 19 ноября 2014

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

0 голосов
/ 26 октября 2012

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

...