2016-04-19 9 views
0

Ich versuche, einen einfachen Textparser in Ruby mit Treetop zu erstellen. Obwohl ich alle Schritte wie in der blog erwähnt ausgeführt habe, kann ich das Programm nicht ausführen. Es schlägt fehl mit der Fehlermeldung:Probleme mit Treetop Parser-Bibliothek

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>' 

ich nicht viel von Ressourcen im Internet auf Baumwipfel finden kann, wäre aber froh, etwas Hilfe zu bekommen. Es folgt der Code:

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 

Antwort

0

Ich konnte das lösen. Der Fehler hier ist, dass sexp_extensions.rb nirgends verwendet wird. Kopieren Sie einfach den Code von sexp_extensions.rb nach sep_parser.treetop, und es funktioniert!