How To Build a Yacc?(14)

既然已经生成了DFA,按照之前的描述写出shift_reduction算法就不是什么了不起的工作了。

class Compiler
  def initialize(rule_file, src_file)
    @yacc = Yacc.new(rule_file)
    @lex = ExtendLex.new(src_file)
    @parse_stack = Array.new
  end
 
  def run
    @yacc.generate
    shift_reduction
  end

 
  def shift_reduction
    @parse_stack.push(0)
    token = @lex.get_next_token2
    while true          
      action = @yacc.dfa.action(@parse_stack.last, token)     
      return false until action
      action_id = action[0]
      new_state = action[1]
      case action_id
        when DFA::SHIFT
          @parse_stack.push(token)
          @parse_stack.push(new_state)
          token = @lex.get_next_token2
        when DFA::REDUCE
          rule = new_state[0].rule
          eval(rule.action)
          # pop 2 * rt.length
          rindex = 0 - 2 * rule.rt.length
          @parse_stack[rindex..-1] = nil
          goto = @yacc.dfa.action(@parse_stack.last, rule.lt)
          if goto
            if goto[0] == DFA::SHIFT            
              @parse_stack.push(rule.lt)
              @parse_stack.push(goto[1])
            elsif goto[0] == DFA::ACCEPT
              return true
            end
          else
            return false
          end
        when DFA::ACCEPT
          return true       
      end
    end
  end
 
end
阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页