Пользовательские методы для узлов синтаксиса Treetop

У меня есть грамматика Treetop PEG, которая соответствует некоторым ключам. Я хочу посмотреть значения, связанные с этими ключами, в хэше, который я даю парсеру. Как я могу сделать так, чтобы синтаксические узлы имели доступ к методам или переменным из парсера?

Например, вот простая грамматика, которая находит одно слово и пытается найти его значение:

# var.treetop
grammar VarResolver
  include VarLookup

  rule variable
    [a-zA-Z] [a-zA-Z0-9_]*
    {
      def value
        p found:text_value
        find_variable(text_value)
      end
    }
  end
end

Вот тестовый файл, использующий его:

# test.rb
require 'treetop'

module VarLookup
  def set_variables(variable_hash)
    @vars = variable_hash
  end
  def find_variable(str)
    @vars[str.to_sym]
  end
end

Treetop.load('var.treetop')

@p = VarResolverParser.new
@p.set_variables name:'Phrogz'
p @p.parse('name').value

Запустив этот тест, я получаю вывод:

{:found=>"name"}
(eval):16:in `value': undefined method `find_variable'
     for #<Treetop::Runtime::SyntaxNode:0x00007f88e091b340> (NoMethodError)

Как я могу сделать find_variable доступны внутри value метод? (В реальном синтаксическом анализаторе эти правила глубоко вложены и должны разрешать значение, не возвращая фактическое имя в начало дерева разбора. Я не могу просто вернуть text_value и посмотреть его снаружи.)

1 ответ

Решение

Это существенный недостаток в дизайне Treetop.

Я (как сопровождающий) не хотел еще больше замедлять его, передавая еще один аргумент каждому синтаксическому узлу и нарушая любые написанные пользователем классы синтаксического узла. Эти конструкторы получают объект "input", Range, который выбирает часть этого ввода, и, необязательно, массив дочерних SyntaxNodes. Они должны были получить сам Parser вместо входных данных в качестве члена.

Поэтому вместо этого для собственного использования (несколько лет назад) я создал собственный прокси для "ввода" и прикрепил к нему свой контекст. Вы можете сойтись с чем-то похожим

https://github.com/cjheath/activefacts-cql/blob/master/lib/activefacts/cql/parser.rb#L203-L249

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