[英]Custom Methods for Treetop Syntax Nodes
I have a Treetop PEG grammar that matches some keys. 我有一个与某些键匹配的Treetop PEG语法。 I want to look up the values associated with those keys in a hash I give the parser.
我想在给解析器的哈希中查找与这些键相关联的值。 How can I make it so that the syntax nodes have access to methods or variables from the parser?
如何使语法节点可以访问解析器中的方法或变量?
For example, here's a simple grammar that finds a single word and tries to look up its value: 例如,下面是一个简单的语法,该语法找到一个单词并尝试查找其值:
# 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
Here's a test file using it: 这是使用它的测试文件:
# 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
Running this test, I get the output: 运行此测试,我得到输出:
{:found=>"name"}
(eval):16:in `value': undefined method `find_variable'
for #<Treetop::Runtime::SyntaxNode:0x00007f88e091b340> (NoMethodError)
How can I make find_variable
accessible inside the value
method? 如何在
value
方法中使find_variable
可访问? (In the real parser, these rules are deeply nested, and need to resolve the value without returning the actual name to the top of the parse tree. I cannot just return the text_value
and look it up outside.) (在真正的解析器中,这些规则是深层嵌套的,需要解析值而不将实际名称返回到解析树的顶部。我不能只返回
text_value
并在外部查找它。)
This is a significant weakness in the design of Treetop. 这是Treetop设计中的一个重大弱点。
I (as maintainer) didn't want to slow it down further by passing yet another argument to every SyntaxNode, and break any custom SyntaxNode classes folk have written. 我(作为维护人员)不想通过向每个SyntaxNode传递另一个参数来进一步降低它的速度,并破坏人们编写的任何自定义SyntaxNode类。 These constructors get the "input" object, a Range that selects part of that input, and optionally an array of child SyntaxNodes.
这些构造函数获得“输入”对象,一个选择该输入一部分的Range以及一个可选的子SyntaxNodes数组。 They should have received the Parser itself instead of the input as a member.
他们应该已经收到解析器本身,而不是作为成员输入。
So instead, for my own use (some years back), I made a custom proxy for the "input" and attached my Context to it. 因此,取而代之的是,为我自己使用(几年前),我为“输入”创建了一个自定义代理,并将上下文附加到该输入。 You might get away with doing something similar:
您可能会做类似的事情:
https://github.com/cjheath/activefacts-cql/blob/master/lib/activefacts/cql/parser.rb#L203-L249 https://github.com/cjheath/activefacts-cql/blob/master/lib/activefacts/cql/parser.rb#L203-L249
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.