parser: the parent of EOF is Start
[nit.git] / src / parser / parser_work.nit
index 4d67908..86f44e7 100644 (file)
@@ -24,12 +24,6 @@ private class State
 
        # The node stored with the state in the stack
        var nodes: nullable Object
-
-       init(state: Int, nodes: nullable Object)
-       do
-               _state = state
-               _nodes = nodes
-       end
 end
 
 # The parser of the Nit language.
@@ -39,17 +33,13 @@ class Parser
        var lexer: Lexer
 
        # Stack of pushed states and productions
-       private var stack: Array[State]
+       private var stack = new Array[State]
 
        # Position in the stack
-       private var stack_pos: Int
+       private var stack_pos: Int = -1
 
-       # Create a new parser based on a given lexer
-       init(lexer: Lexer)
+       init
        do
-               _lexer = lexer
-               _stack = new Array[State]
-               _stack_pos = -1
                build_reduce_table
        end
 
@@ -151,19 +141,20 @@ class Parser
                                var node1 = pop
                                assert node1 isa AModule
                                var node = new Start(node1, node2)
+                               node2.parent = node
                                (new ComputeProdLocationVisitor).enter_visit(node)
                                return node
                        else if action_type == 3 then # ERROR
                                # skip injected tokens
                                while not isset token._location do token = lexer.next
-                               var node2 = new AParserError.init_parser_error("Syntax error: unexpected {token}.", token.location, token)
+                               var node2 = new AParserError.init_parser_error("Syntax Error: unexpected {token}.", token.location, token)
                                var node = new Start(null, node2)
                                return node
                        end
                end
        end
 
-       private var reduce_table: Array[ReduceAction]
+       private var reduce_table: Array[ReduceAction] is noinit
        private fun build_reduce_table is abstract
 end
 
@@ -192,15 +183,15 @@ private class ComputeProdLocationVisitor
        # Already visited epsilon productions that waits something after them
        var need_after_epsilons = new Array[Prod]
 
-       # Location of the last visited token in the current production
-       var last_location: nullable Location = null
+       # The last visited token in the current production
+       var last_token: nullable Token = null
 
        redef fun visit(n: ANode)
        do
                if n isa Token then
                        if not isset n._location then return
                        var loc = n._location
-                       _last_location = loc
+                       _last_token = n
 
                        # Add a first token to productions that need one
                        if not _need_first_prods.is_empty then
@@ -227,10 +218,13 @@ private class ComputeProdLocationVisitor
                        var startl = n._first_location
                        if startl != null then
                                # Non-epsilon production
-                               var endl = _last_location
-                               assert endl != null
+                               var endl = _last_token.location
 
-                               n.location = new Location(startl.file, startl.line_start, endl.line_end, startl.column_start, endl.column_end)
+                               if startl == endl then
+                                       n.location = startl
+                               else
+                                       n.location = new Location(startl.file, startl.line_start, endl.line_end, startl.column_start, endl.column_end)
+                               end
 
                                if not _need_after_epsilons.is_empty then
                                        var loc = new Location(endl.file, endl.line_end, endl.line_end, endl.column_end, endl.column_end)
@@ -269,5 +263,4 @@ private abstract class ReduceAction
                return l1
        end
        var goto: Int
-       init(g: Int) do _goto = g
 end