我已经简化了用 Treetop 表达的语法,并且我正在尝试使用自定义节点将解析器的输出过滤到 AST 中。
grammar Elem
rule top
lpar 'top' space
args_:(lpar 'args' space ((ident / number) space?)* rpar) space?
rpar <Top>
end
rule ident
[a-zA-Z] [a-zA-Z0-9_]* <Ident>
end
rule number
[0-9]+ <Number>
end
rule space
[\s]+
end
rule lpar
space? '(' space?
end
rule rpar
space? ')' space?
end
end
基本上,它可以解析以下示例:
(top (args foo bar 42))
自定义节点全部继承Treetop::Runtime::SyntaxNode
现在,我需要将 Treetop 生成的解析树过滤成 AST。
我遵循这里解释的策略,但没有成功:我的 AST 只是空的......
我的编译器驱动程序如下:
require 'treetop'
require 'pp'
require_relative 'elem'
require_relative 'node_extension'
class ElemCompiler
def initialize
@parser=ElemParser.new
end
def compile filename
puts "==> compiling #{filename}"
@ast=parse(filename)
puts "==> AST in memory. Good."
end
def parse filename
pp tree=@parser.parse(IO.read(filename))
pp clean(tree)
end
private
def clean(root_node)
return if(root_node.elements.nil?)
pp root_node.elements.collect {|node| node.class.name =="Treetop::Runtime::SyntaxNode" }
pp root_node.elements.delete_if{|node| node.class.name == "Treetop::Runtime::SyntaxNode" }
root_node.elements.each {|node| clean(node) }
end
end
compiler=ElemCompiler.new.parse ARGV[0]
我错过了什么?