How To Build a Yacc?(8)

搞定lex后,很显然,我们要将它加入到Compiler中。

class Compiler
  def initialize(rule_file, src_file)
    @lex = ExtendLex.new(src_file)
  end

   def run
       return true
   end

end

要想在run里面真正的干点事,就需要一个shift-reduction算法来识别src_file中的符号流是否能符合rule_file
中所定义的规则。

我们目前只有@lex, 从它那儿我们只能得到符号流,要进行shift-reduction分析,我们需要从rule_file生成DFA,这一点才是关键。为了达到这个目的,得重新写一个类来完成这个功能。

根据这个类的功能,一个紧迫的工作是定义规则文件的格式,以function_decl文法为例:

##### File: ican.y  ###############

%%
%token function id
%token ; , = ( )
%%
nil := function_decl :
function_decl := function function_name ( argument_list ) ; :
function_name := id : p @lex.get_token_string(-1)
argument_list := argument_list , id : p @lex.get_token_string(-1)
argument_list := id :    p @lex.get_token_string(-1)

以'%%'为分割符,第1个'%%'后面是terminal定义,第2个‘%%’后面定义的是rule, rule的写法就是普通的BNF表达式,后面跟着一个:引出的action表达式,目前我们只执行ruby表达式。这里有几个特定约束:每个NONTERMINAL最终总能推出TERMINAL序列。开始符号由nil := Start_Symbol来定义。

好了,假设我们已经有了一个Yacc类,它所完成的工作就是读入rule_file生成DFA,我们该如何使用(测试)它?

#### test.rb
require 'rubyunit'

class TestCompiler < Test::Unit::TestCase 
    def create_rule_file
        File.open("rulefile","w") do |file|
      file.puts "%%/n%token function id/n%token ; , = ( )/n"
      file.puts "%%/nnil := function_decl : /n"
      file.puts "function_decl := function function_name ( argument_list ) ; : /n"
      file.puts "function_name := id : /n"
      file.puts "argument_list := argument_list , id : /n"
      file.puts "argument_list := id :"
    end   
  end

    def test_yacc
        create_rule_file
        yacc = Yacc.new("rulefile")
        yacc.generate
       assert(yacc.state[0].size == 2)
    end
end

在我们上面所定义的rulefile中,DFA的state[0](开始状态)应该是2个item:
item1:[nil = # function_decl]
item2:[function_decl = # function function_name ( argument_list ) ;]

当然我们可以编写更多的assert, 不过对于一个想象中的类,还是不要对它要求过多。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值