树顶语法节点的自定义方法
Custom Methods for Treetop Syntax Nodes
我有一个 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
方法中可访问? (在真正的解析器中,这些规则是深度嵌套的,需要在不 return 将实际名称解析到解析树顶部的情况下解析值。我不能只 return text_value
到外面看看。)
这是 Treetop 设计中的一个重大弱点。
我(作为维护者)不想通过
将另一个参数传递给每个 SyntaxNode,
并打破任何自定义 SyntaxNode 类
书面。这些构造函数获取 "input" 对象,一个 Range
选择该输入的一部分,以及可选的数组
子句法节点。他们应该收到
解析器本身而不是输入作为成员。
因此,为了我自己使用(几年前),我制作了
"input" 的自定义代理并附上我的上下文
给它。你可能会逃避做类似的事情:
https://github.com/cjheath/activefacts-cql/blob/master/lib/activefacts/cql/parser.rb#L203-L249
我有一个 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
方法中可访问? (在真正的解析器中,这些规则是深度嵌套的,需要在不 return 将实际名称解析到解析树顶部的情况下解析值。我不能只 return text_value
到外面看看。)
这是 Treetop 设计中的一个重大弱点。
我(作为维护者)不想通过 将另一个参数传递给每个 SyntaxNode, 并打破任何自定义 SyntaxNode 类 书面。这些构造函数获取 "input" 对象,一个 Range 选择该输入的一部分,以及可选的数组 子句法节点。他们应该收到 解析器本身而不是输入作为成员。
因此,为了我自己使用(几年前),我制作了 "input" 的自定义代理并附上我的上下文 给它。你可能会逃避做类似的事情:
https://github.com/cjheath/activefacts-cql/blob/master/lib/activefacts/cql/parser.rb#L203-L249