使用treetop解析器库的问题

时间:2016-04-19 18:43:49

标签: ruby-on-rails ruby parsing treetop

我正在尝试使用treetop在ruby中创建一个简单的文本解析器。虽然我已遵循blog中提到的所有步骤,但我无法运行该程序。它失败并显示错误消息:

user1-mbp15:source user1$ ruby myParser.rb 
(eval):28:in `_nt_expression': undefined local variable or method `_nt_space' for #<SexpParser:0x007fad9b92b210> (NameError)
   from /usr/local/lib/ruby/gems/2.3.0/gems/treetop-1.6.5/lib/treetop/runtime/compiled_parser.rb:18:in `parse'
   from myParser.rb:19:in `parse'
   from myParser.rb:31:in `<main>'

我在树梢上找不到很多关于网络的资源,但很乐意得到一些帮助。以下是代码:

user1-mbp15:source user1$ ls
   myParser.rb
   node_extensions.rb
   sexp_extensions.rb
   sexp_parser.treetop

- myParser.rb -

# In file myParser.rb
require 'treetop'

# Find out what our base path is
$base_path = File.expand_path(File.dirname(__FILE__))

# Load our custom syntax node classes so the parser can use them
require File.join($base_path, 'node_extensions.rb')
class Parser
   # Load the Treetop grammar from the 'sexp_parser' file, and 
   # create a new instance of that parser as a class variable 
   # so we don't have to re-create it every time we need to 
   # parse a string
   Treetop.load(File.join($base_path, 'sexp_parser.treetop'))
   @@parser = SexpParser.new

   def self.parse(data)
      # Pass the data over to the parser instance
      tree = @@parser.parse(data)

      # If the AST is nil then there was an error during parsing
      # we need to report a simple error message to help the user
      if(tree.nil?)
         raise Exception, "Parse error at offset: #{@@parser.index}"
      end

      return tree
   end
end

Parser.parse('(this "is" a test( 1 2.0 3))')

- node_extensions.rb -

module Sexp
   class IntegerLiteral < Treetop::Runtime::SyntaxNode
   end

   class StringLiteral < Treetop::Runtime::SyntaxNode
   end

   class FloatLiteral < Treetop::Runtime::SyntaxNode
   end

   class Identifier < Treetop::Runtime::SyntaxNode
   end

   class Expression < Treetop::Runtime::SyntaxNode
   end

   class Body < Treetop::Runtime::SyntaxNode
   end
end

- sexp_extensions.rb -

grammar Sexp
    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 space
        [\s]+
    end
end

- sep_parser.treetop -

# In file sexp_parser.treetop
grammar Sexp
    rule expression
        space? '(' body ')' space? <Expression>
    end

    rule body
        (expression / identifier / float / integer / string / space )* <Body>
    end
end

1 个答案:

答案 0 :(得分:0)

我能够解决这个问题。这里的错误是sexp_extensions.rb无处使用。只需将sexp_extensions.rb中的代码复制到sep_parser.treetop,就可以了!