簡體   English   中英

如何在Ruby Treetop樹的子節點中觸發函數。 (是:如何防止紅寶石Treetop進行AST壓榨)

[英]How to trigger functions in subnodes in Ruby Treetop tree. (was:How to prevent ruby Treetop doing AST squashing)

我使用樹梢已有一段時間了。 我寫了以下規則

http://thingsaaronmade.com/blog/a-quick-intro-to-writing-a-parser-using-treetop.html

我可以解析我的整個輸入字符串,但是除了初始的之外,沒有其他to_array函數被觸發。

然后,我發現https://whitequark.org/blog/2011/09/08/treetop-typical-errors/談論AST squashing ,我發現我的規則也是如此。

我的第一個規則是

  rule bodies
    blankLine* interesting:(body+) blankLine* <Bodies>
  end

一切都被body吞噬了。

有人可以建議我該怎么做才能解決此問題?

編輯添加代碼段:

grammar Sexp

  rule bodies
    blankLine* interesting:(body+) blankLine* <Bodies>
  end

  rule body
    commentPortString (ifdef_blocks / interface)+ (blankLine / end_of_file) <Body>
  end

  rule interface
    space? (intf / intfWithSize) space?  newLine <Interface>
  end

  rule commentPortString
    space? '//' space portString space?  <CommentPortString>
  end

  rule portString
    'Port' space? '.' newLine <PortString>
  end

  rule expression
    space? '(' body ')' space? <Expression>
  end

  rule intf
    (input / output) space wire:wireName space? ';' <Intf>
  end

  rule intfWithSize
    (input / output) space? width:ifWidth space? wire:wireName space? ';' <IntfWithSize>
  end

  rule input
    'input' <InputDir>
  end

  rule output
    'output' <OutputDir>
  end

  rule ifdef_blocks
    ifdef_line (interface / ifdef_block)* endif_line <IfdefBlocks>
  end

  rule ifdef_block
    ifdef_line interface* endif_line <IfdefBlocks>
  end

  rule ifdef_line
    space? (ifdef / ifndef) space+  allCaps space? newLine <IfdefLine>
  end

  rule endif_line
    space? (endif) space? newLine <EndifLine>
  end

  rule ifdef
    '`ifdef' <Ifdef>
  end

  rule ifndef
    '`ifndef' <Ifndef>
  end

  rule endif
    '`endif' <Endif>
  end

  rule ifWidth
    '[' space? msb:digits space? ':' space? lsb:digits ']' <IfWidth>
  end

  rule digits
    [0-9]+ <Digits>
  end

  rule integer
    ('+' / '-')? [0-9]+ <IntegerLiteral>
  end

  rule float
    ('+' / '-')? [0-9]+ (('.' [0-9]+) / ('e' [0-9]+)) <FloatLiteral>
  end

  rule string
    '"' ('\"' / !'"' .)* '"' <StringLiteral>
  end

  rule identifier
    [a-zA-Z\=\*] [a-zA-Z0-9_\=\*]* <Identifier>
  end

  rule allCaps
    [A-Z] [A-Z0-9_]*
  end

  rule wireName
    [a-zA-Z] [a-zA-Z0-9_]* <WireName>
  end

  rule non_space
    !space .
  end

  rule space
    [^\S\n]+
  end

  rule non_space
    !space .
  end

  rule blankLine
    space* newLine
  end

  rule not_newLine
    !newLine .
  end

  rule newLine
    [\n\r]
  end

  rule end_of_file
    !.
  end

end

測試字符串

// Port.
input         CLK;

// Port.
input         REFCLK;

// Port.
input [ 41:0] mem_power_ctrl;
output data;

編輯:添加更多詳細信息

測試代碼已簽入: https : //github.com/justrajdeep/treetop_ruby_issue

如您在我的node_extensions.rb看到的node_extensions.rb ,除了Bodies之外,所有節點都在to_array方法中引發異常。 但是沒有異常觸發。

您在tree調用to_array ,它是一個Bodies 那是您曾經調用過to_array to_array方法,因此不會調用其他to_array方法。

如果你想to_array的子節點上被稱為Bodies的節點, Bodies#to_array需要調用to_array這些子節點上。 因此,如果要在標記為“ interestingBody節點上調用它,則應遍歷interesting並在每個元素上調用.to_array

嘗試將(body+)分解成這樣的新規則:

rule bodies
   blankLine* interesting:interesting blankLine* <Bodies>
end

rule interesting
   body+ <Interesting>
end

否則,查看SyntaxNode類將很有幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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