How To Build a Yacc?(11)

    技术2022-05-11  117

    分析完rule_file, 最后一个关键的步骤是生成DFA。 这是一个比较复杂的过程,首先我们要建立一个Item结构,这样才能构造状态(states) item 应该是一个rule和一个相关的position(当前识别位置)组成。 class TestCompiler < Test::Unit::TestCase    def test_item     rule = Rule.parse("function_decl := /       function function_name ( argument_list ) ; : decl")     assert(rule)     item = Item.new(rule, 0)     assert(item.current_token == "function_decl")     assert(item.next_token == "function")     item = item.step     assert(item.current_token == "function")     assert(item.next_token == "function_name")     assert(item.is_end? == false)         item.step!(5)        assert(item.is_end? == true)   end end ################################## # 一个Item即NFA中一个状态集合中的成员 ################################## class Item   def initialize(rule, pos)     @rule, @pos = rule, pos   end     def current_token     return token(@pos)   end     def next_token     return token(@pos + 1)   end     def step(distance = 1)     return Item.new(@rule, @pos + distance)   end     def step!(distance = 1)     @pos = @pos + distance   end      def is_end?     return @pos >= @rule.rt.length   end     def token(pos)     return nil if pos < 0 || pos > @rule.rt.length     return @rule.lt if 0 == pos     return @rule.rt.at(pos-1)   end     def to_s     rta = rule.rt.dup     #shift_pos = @pos-1 < 0 ? 0 : @pos - 1     rta.insert(@pos, "#")     "[#{rule.lt} = #{rta.join(" ")}]"   end     def eql?(other)     #p "#{self.to_s} eql? #{other.to_s}, #{@rule.eql?(other.rule) && @pos.eql?(other.pos)}"     return @rule.eql?(other.rule) && @pos.eql?(other.pos)   end     alias :== eql?   attr_reader :rule, :pos end

    最新回复(0)