[英]How to code an action trigger with treetop?
I'm trying to have some bit of code running each time the parser recognises a token. 每当解析器识别出令牌时,我都试图运行一些代码。
Let's say 比方说
grammar FooBar
rule start
(foo "\n")+
end
rule foo
stuff_i_want:([a-z]+) {
puts "Hi there I found: #{stuff_i_want.text_value}"
}
end
end
The idea here would be to have this puts
action execute each time the foo
token is found. 这里的想法是每次发现foo
令牌时都执行puts
操作。 Coded as is, it does not work as it is triggered only once (at the class loading time) and of course stuff_i_want.text_value
does not exist then. 照原样编码,它不起作用,因为它仅被触发一次(在类加载时),当然, stuff_i_want.text_value
不存在。
Any idea? 任何想法? Is it even possible? 可能吗 The lack of documentation on the library does not make it easy to tell. 库上缺少文档并不容易说明。
Well, I'm not sure what I did to deserve the downvote. 好吧,我不确定我应该做些什么来减少票数。
Anyway, here is the solution I used: 无论如何,这是我使用的解决方案:
node_extension.rb node_extension.rb
module Crawlable
def crawl *args
continue = true
continue = action(*args) if respond_to? :action
return if !continue || elements.nil?
elements.each do |elt|
elt.crawl(*args)
end
end
end
# reopen the SyntaxNode class and include the module to add the functionality
class Treetop::Runtime::SyntaxNode
include Crawlable
end
then all is left is to define a action(*args)
method on each node you want to trigger an effect on and have to start the crawling on the top parser node (the one returned by the parse call 然后剩下的就是在每个要在其上触发效果的节点上定义一个action(*args)
方法,并且必须开始在顶部解析器节点上进行爬网(由解析调用返回的那个)
parse_tree = FooBarParser.new.parse "mycontent"
parse_tree.crawl # add optional parameters for context/state
The optional parameters are passed to each action
method. 可选参数传递给每个action
方法。 You can also return a falsey value ( false
or nil
) in action in order to stop the subtree crawling. 您还可以返回一个falsey值( false
或nil
)以停止子树爬网。
grammar FooBar
rule start
(foo "\n")+
end
rule foo
stuff_i_want:([a-z]+) {
def action
puts "Hi there I found: #{stuff_i_want.text_value}"
false
end
}
end
end
This might be a simpler solution than the one you can up with. 这可能是比您可以使用的解决方案更简单的解决方案。 I can't see why you would need open up the SyntaxNode
class in order to get the functionality that you want. 我看不到为什么您需要打开SyntaxNode
类才能获得所需的功能。 All you need to do is traverse the nodes a little bit more (unless I'm not understanding what you're trying to accomplish). 您需要做的是更多地遍历节点(除非我不理解您要完成的工作)。
Here's an example: 这是一个例子:
require 'treetop'
Treetop.load_from_string DATA.read
parser = FooBarParser.new
parser.parse("hello\nok\nmorestuff\n").action
__END__
grammar FooBar
rule start
(foo "\n")+
{
def action
elements.each {|e| e.elements[0].action }
end
}
end
rule foo
stuff_i_want:([a-z]+)
{
def action
puts "Hi there I found: #{stuff_i_want.text_value}"
end
}
end
end
# => Hi there I found: hello
# Hi there I found: ok
# Hi there I found: morestuff
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.