How To Build a Yacc?(7)

代码,还是代码!

要完成一个这样相对复杂的功能,是需要写一些代码,不过我保证,他最终将比你想象的少的多。


我对Lex类还有些不尽满意,实际上,我更希望lex.get_token_string能取得当前符号流中的任何一个符号,而不仅仅是当前的一个符号。。

lex = Lex.new(src)
lex.get_next_token
assert ( lex.get_token_string(0) == current_token_string && lex.get_token_string(-1) == prev_token_string )

设计一个类ExtendLex, 在初始化时将source code文件全部分解成符号流读入,保存在成员里。然后建立一个内部迭代变量。

class ExtendLex
  ERROR = 9
  EOF = 0
 
  def read_file
    while true
      t_id = @lex.get_next_token
      if ERROR == t_id
        raise "lex error: '#{super.get_token_string}' is unknown character"
      end
      @token_ids.push(t_id)
      @token_defs.push(@@token_match[t_id])
      @token_strs.push(@lex.get_token_string)
      break if t_id == EOF
    end
  end
 
  def initialize(file)
    @lex = Lex.new(file)
    @token_ids = Array.new
    @token_defs = Array.new
    @token_strs = Array.new   
    @current_pos = -1  
    read_file
  end
 
 
 
  @@token_match = {
    1 => "(",
    2 => ")",
    3 => "function",
    4 => ";",
    5 => ",",
    6 => "=",
    7 => "id",
    8 => "constant",
    9 => "error",
    0 => "$"
  }
 
  def get_next_token
    @current_pos = @current_pos + 1
    return @token_ids[@current_pos]      
  end
 
  def get_next_token2
    @current_pos = @current_pos + 1
    return @token_defs[@current_pos]
  end
 
  def get_token_string(index)
    return @token_strs[@current_pos+index]
  end
 
  attr_reader :token_ids, :token_defs, :token_strs
end


如上面的代码:read_file调用lex的get_next_token方法
分析整个文件,将所有识别的符号存储在一个数组:
token_ids里面,而将所有的符号字符串存储在一个数组: token_strs里面。
get_token_string方法带了一个参数,如果对象拥有文件中所有的符号,那么可以根据index来取得任何一个位置的符号,符号字符串。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值