每次解析器识别一个令牌时,我都会尝试运行一些代码。
让我们说
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
这里的想法是每次找到puts
令牌时执行此foo
操作。按原样编码,它不起作用,因为它只被触发一次(在类加载时),当然stuff_i_want.text_value
不存在。
有什么想法吗?它甚至可能吗?缺乏关于图书馆的文档并不容易说出来。
答案 0 :(得分:0)
好吧,我不确定我做了什么值得投票。
无论如何,这是我使用的解决方案:
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
然后剩下的就是在每个要触发效果的节点上定义一个action(*args)
方法,并且必须在顶层解析器节点上开始抓取(解析调用返回的那个
parse_tree = FooBarParser.new.parse "mycontent"
parse_tree.crawl # add optional parameters for context/state
可选参数传递给每个action
方法。您还可以返回虚假值(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
答案 1 :(得分:0)
这可能比您可以使用的解决方案更简单。我不明白为什么你需要打开SyntaxNode
类才能获得你想要的功能。您需要做的就是稍微遍历节点(除非我不理解您要完成的任务)。
以下是一个例子:
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