您的位置:首页 > 产品设计 > UI/UE

How To Build a Yacc?(10)

2005-12-28 01:06 399 查看
将Vocab和Rule功能组合起来作为一个RuleParser类来提供分析rule_file的功能是个不错的主意,因为对这两个类而言并没有太大的重用的意义,只不过是为了将错误的出现尽可能的控制在局部。

class TestCompiler < Test::Unit::TestCase
def test_rule_parser
create_rule_file
p = RuleParser.new("rulefile")
assert(p.rules[0].lt == "nil")
assert(p.rules[0].rt == ["function_decl"])
assert(p.vocabs.identify("function") == Vocab::TERMINAL)
end
end

有了Vocab和Rule,实现RuleParser只是举手之劳。

class RuleParser
def initialize(file_name)
@vocabs = Vocab.new
@rules = Array.new
compile(file_name)
end

@@directive = 0
DIRECTIVE = "%%"

####################################################
# 对于 yacc的输入规则文件进行解析
# 将文件中定义的token和rule分别存入@vocabs, @rules
# 定义文件分两段:
# %%
# {第一段:token definition}
# %%
# {第二段:rule definition}
# %%
####################################################
def compile(file_name)
file = File.open(file_name, "r")
no = 0
begin
file.each do |line|
no = no+1
if line.strip().chomp() == DIRECTIVE
@@directive = @@directive + 1
next
end

# @@directive == 0 not started, continue
# @@directive == 1 start parse terminals
# @@directive == 2 start parse rules
# @@directive == 3 end parse
case @@directive
when 0
next
when 1
if !add_terminal(line)
error(no, line, "parse terminal error")
end
when 2
rule = parse_rule(line)
if !rule
error(no, line, "parse nonterminal error")
end
add_nonterminal(rule)
when 3
break
end # end when
end # end for each

rescue
raise
ensure
file.close()
end # end begin...

end

def add_terminal(line)
@vocabs.add_terminal(line)
end

def add_nonterminal(rule)
@vocabs.add_nonterminals(rule.vocabs())
end

def parse_rule(line)
rule = Rule.parse(line)
@rules.push(rule)
return rule
end

def error(no, line, msg)
raise "Error #{msg} in Line #{no}, #{line}."
end

private :error
attr_reader :rules, :vocabs
end

实际上,对RuleParser的test case的设计,无意中凸显了一个事实,那就是应该将RuleParser设计为一个interface, 对外提供至少两个方法:get_rules(分析rule_file得到的rule集合);get_vocabs(分析rule_file得到的vocab集合)。这样,Yacc类就不必依赖于RuleParser的实现,意味着Yacc不必知晓rule_file的特定格式,这些细节只应该由RuleParser的实现类来关心。

在ruby这种动态语言里。。只要你设计出一个类提供rules,vocabs两个属性就好。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: