![](/img/trans.png)
[英]How to trigger functions in subnodes in Ruby Treetop tree. (was:How to prevent ruby Treetop doing AST squashing)
[英]How to code an action trigger with treetop?
每當解析器識別出令牌時,我都試圖運行一些代碼。
比方說
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
這里的想法是每次發現foo
令牌時都執行puts
操作。 照原樣編碼,它不起作用,因為它僅被觸發一次(在類加載時),當然, stuff_i_want.text_value
不存在。
任何想法? 可能嗎 庫上缺少文檔並不容易說明。
好吧,我不確定我應該做些什么來減少票數。
無論如何,這是我使用的解決方案:
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
方法。 您還可以返回一個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
這可能是比您可以使用的解決方案更簡單的解決方案。 我看不到為什么您需要打開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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.