Вопрос

Я пытаюсь научиться работать с генератором грамматики Treetop от Ruby.Я обнаружил, что документация не только крайне скудна для «лучшего» варианта, но и работает не так интуитивно, как я надеялся.

На высоком уровне мне бы очень хотелось, чтобы руководство было лучше, чем документация на сайте или видео, если оно есть.

На более низком уровне есть грамматика, с которой я вообще не могу работать:

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

выдает ошибку:НоМетодОшибка:частный метод `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().Я понятия не имею, почему это так.

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

Это было полезно?

Решение

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

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

Другие советы

Возможно, вы оцените красивое и простое руководство Пола Бэттли по адресуНачало работы с Treetop

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

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

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

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

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

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

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

 rule num
      (float / integer)
 end

к

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

И, кажется, это работает.

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top