代码之家  ›  专栏  ›  技术社区  ›  justrajdeep

如何使用RubyTreetop解析多行?

  •  0
  • justrajdeep  · 技术社区  · 8 年前

    我是新来的 ruby treetop .

    我经历了 this tutorial 并提出了以下规则。

    grammar Sexp
    
      rule body
        commentPortString *(I am stuck here)*
      end
    
      rule interface
        space? (intf / intfWithSize) space? ('\n' / end_of_file) <Interface>
      end
    
      rule commentPortString
        space? '//' space portString space? ('\n' / end_of_file) <CommentPortString>
      end
    
      rule portString
        'Port' space? '.' <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'
      end
    
      rule output
        'output'
      end
    
      rule ifWidth
        '[' space? msb:digits space? ':' space? lsb:digits ']' <IfWidth>
      end
    
      rule digits
        [0-9]+
      end
    
      rule integer
        ('+' / '-')? [0-9]+ <IntegerLiteral>
      end
    
      rule float
        ('+' / '-')? [0-9]+ (('.' [0-9]+) / ('e' [0-9]+)) <FloatLiteral>
      end
    
      rule string
        '"' ('\"' / !'"' .)* '"' <StringLiteral>
      end
    
      rule signalTypeString
        '"' if_sig_name:signalType '"' <SignalTypeString>
      end
    
      rule signalType
        [a-zA-Z] [a-zA-Z0-9_]* (receiveLiteral / transmitLiteral) <SignalType>
      end
    
      rule receiveLiteral
        '.receive'
      end
    
      rule transmitLiteral
        '.transmit'
      end
    
      rule identifier
        [a-zA-Z\=\*] [a-zA-Z0-9_\=\*]* <Identifier>
      end
    
      rule wireName
        [a-zA-Z] [a-zA-Z0-9_]* <WireName>
      end
    
      rule non_space
        !space .
      end
    
      rule space
        [\s\t]+
      end
    
      rule newLine
        [\n\r]+
      end
    
      rule end_of_file
        !.
      end
    
    end
    

    我想让解析器提取出下面这样的blob。它总是以 Port. 以空行结尾。

        // Port.
        output        send;
        input         free;
        output        fgcg;
        output[  2:0] state_id;
        output[  1:0] stream_id;
    `ifdef SIMULATION
        output[ 83:0] dbg_id;
    `endif
    

    上面提到的规则可以在单独传递时识别文本中的所有行,但我无法提取blob。另外,我只想提取出匹配的文本并忽略其余部分。

    有人能给我指个方向吗?

    1 回复  |  直到 8 年前
        1
  •  1
  •   Josh Voigts    8 年前

    就像下面你要找的那样。如果没有更多的信息,很难完全理解您的问题。

    这个 space 规则包括 \s 其中包括 \n 已经有了,所以如果你想再找一个 \n ,它无法正确解析。如果您修改 空间 法则 [^\S\n]+ 它将排除 \n 所以你可以明确地寻找它。

    如果你在找一个完全空白的行来结束 Port. 块,您应该明确查找 "\n" ("\n" / end_of_file) .

    希望这有意义…

    grammar Sexp
    
      rule body
        commentPortString interface* portEnd
      end
    
      rule interface
        space? (intf / intfWithSize) space? "\n" <Interface>
      end
    
      rule commentPortString
        space? '//' space? portString space? "\n" <CommentPortString>
      end
    
      rule portString
        'Port' space? '.' <PortString>
      end
    
      # Port block ends with a blank line
      rule portEnd
        "\n" / end_of_file
      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'
      end
    
      rule output
        'output'
      end
    
      rule ifWidth
        '[' space? msb:digits space? ':' space? lsb:digits ']' <IfWidth>
      end
    
      rule digits
        [0-9]+
      end
    
      rule integer
        ('+' / '-')? [0-9]+ <IntegerLiteral>
      end
    
      rule float
        ('+' / '-')? [0-9]+ (('.' [0-9]+) / ('e' [0-9]+)) <FloatLiteral>
      end
    
      rule string
        '"' ('\"' / !'"' .)* '"' <StringLiteral>
      end
    
      rule signalTypeString
        '"' if_sig_name:signalType '"' <SignalTypeString>
      end
    
      rule signalType
        [a-zA-Z] [a-zA-Z0-9_]* (receiveLiteral / transmitLiteral) <SignalType>
      end
    
      rule receiveLiteral
        '.receive'
      end
    
      rule transmitLiteral
        '.transmit'
      end
    
      rule identifier
        [a-zA-Z\=\*] [a-zA-Z0-9_\=\*]* <Identifier>
      end
    
      rule wireName
        [a-zA-Z] [a-zA-Z0-9_]* <WireName>
      end
    
      rule non_space
        !space .
      end
    
      rule space
        [^\S\n]+
      end
    
      rule newLine
        [\n\r]+
      end
    
      rule end_of_file
        !.
      end
    
    end
    
    推荐文章