Class: Aurum::Parser
- Inherits:
-
Object
- Object
- Aurum::Parser
- Defined in:
- lib/aurum/engine.rb
Defined Under Namespace
Classes: SemanticActionContext, SemanticAttributes
Instance Method Summary collapse
-
#initialize(productions, parsing_table) ⇒ Parser
constructor
A new instance of Parser.
- #parse(lexer) ⇒ Object
Constructor Details
#initialize(productions, parsing_table) ⇒ Parser
Returns a new instance of Parser.
99 100 101 |
# File 'lib/aurum/engine.rb', line 99 def initialize productions, parsing_table @productions, @parsing_table = productions, parsing_table end |
Instance Method Details
#parse(lexer) ⇒ Object
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/aurum/engine.rb', line 103 def parse lexer lookahead, state_stack, symbol_stack, value_stack = lexer.next_symbol, [0], [], [] lookahead_shift = 0 while (true) state = @parsing_table[state_stack.last] action = state[lookahead] if action.kind_of? ShiftAction state_stack.push action.state symbol_stack.push lookahead unless action.is_lookahead_shift action.is_lookahead_shift ? lookahead_shift += 1 : lookahead = lexer.next_symbol elsif action.kind_of? ReduceAction handle = @productions[action.handle] lookahead_shift.times { state_stack.pop } lookahead_shift = 0 if action.is_read_reduce state_stack.push state symbol_stack.push lookahead lookahead = lexer.next_symbol end state_stack.slice! -handle.symbols.length..-1 symbols = symbol_stack.slice! -handle.symbols.length..-1 handle.nonterminal == Aurum::START and return value_stack.pop if handle.action context = {handle.nonterminal.name => [SemanticAttributes.new]} handle.symbols.reverse.each_with_index do |symbol, index| context[symbol.name] = [] unless context.has_key? symbol.name context[symbol.name] << (symbol.is_terminal ? symbols[-index-1] : value_stack.pop) end SemanticActionContext.new(context).instance_eval &handle.action value_stack.push context[handle.nonterminal.name][0] if context[handle.nonterminal.name] end goto = @parsing_table[state_stack.last][handle.nonterminal] if goto.kind_of? ShiftAction state_stack.push goto.state symbol_stack.push nil else lexer.pushback lookahead lookahead = handle.nonterminal end else error_recover end end end |