我有一个匹配某些键的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
并在外面查找。)
答案 0 :(得分:1)
这是Treetop设计的一个重大缺陷。
我(作为维护者)并不想进一步放慢速度 将另一个参数传递给每个SyntaxNode, 并打破民间拥有的任何自定义SyntaxNode类 书面。这些构造函数得到了&#34;输入&#34;对象,范围 选择该输入的一部分,以及可选的数组 子语法SyntaxNodes。他们应该收到了 解析器本身而不是作为成员的输入。
相反,为了我自己的使用(几年前),我做了 &#34;输入&#34;的自定义代理并附上我的背景 它。你可能会做类似的事情:
https://github.com/cjheath/activefacts-cql/blob/master/lib/activefacts/cql/parser.rb#L203-L249