0

每次解析器识别令牌时,我都会尝试运行一些代码。

比方说

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那时不存在。

任何的想法?甚至可能吗?图书馆缺乏文档并不容易分辨。

4

2 回答 2

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方法。您还可以在操作中返回虚假值(falsenil)以停止子树爬行。

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
于 2013-08-09T01:52:49.320 回答
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
于 2013-08-09T13:33:52.783 回答