0

我有一个匹配某些键的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并在外面查找。)

4

1 回答 1

1

这是 Treetop 设计中的一个重大弱点。

我(作为维护者)不想通过向每个 SyntaxNode 传递另一个参数来进一步减慢它,并破坏人们编写的任何自定义 SyntaxNode 类。这些构造函数获取“输入”对象、选择部分输入的 Range,以及可选的子 SyntaxNode 数组。他们应该收到解析器本身而不是作为成员的输入。

因此,为了我自己的使用(几年前),我为“输入”制作了一个自定义代理并将我的上下文附加到它。你可能会逃避做类似的事情:

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

于 2018-04-05T10:14:07.243 回答