簡體   English   中英

如何用樹梢編碼動作觸發器?

[英]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值( 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

這可能是比您可以使用的解決方案更簡單的解決方案。 我看不到為什么您需要打開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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM