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. 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.
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
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
parse_tree = FooBarParser.new.parse "mycontent"
parse_tree.crawl # add optional parameters for context/state
The optional parameters are passed to each action
method. You can also return a falsey value (false
or nil
) in action in order to stop the subtree crawling.
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