0

I am trying to create a simple text parser in ruby using treetop. Although I have followed all steps as mentioned in the blog, I am not being able to run the program. It fails with the error message:

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

I could not find a lot of resources on the web on treetop, but would be glad to get some help. Following is the 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
Stanislav Pankevich
  • 11,044
  • 8
  • 69
  • 129
Aditya Kotwal
  • 101
  • 2
  • 5

1 Answers1

0

I was able to solve this. The error here is that sexp_extensions.rb is used nowhere. Simply copy code from sexp_extensions.rb to sep_parser.treetop, and it works!

Aditya Kotwal
  • 101
  • 2
  • 5