我正在尝试使用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
答案 0 :(得分:0)
我能够解决这个问题。这里的错误是sexp_extensions.rb无处使用。只需将sexp_extensions.rb中的代码复制到sep_parser.treetop,就可以了!