X-Git-Url: http://nitlanguage.org diff --git a/src/parser/parser_work.nit b/src/parser/parser_work.nit index 5b217da..c2eff11 100644 --- a/src/parser/parser_work.nit +++ b/src/parser/parser_work.nit @@ -20,35 +20,26 @@ intrude import parser_prod # State of the parser automata as stored in the parser stack. private class State # The internal state number - var _state: Int + var state: Int # 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 + var nodes: nullable Object end +# The parser of the Nit language. class Parser super TablesCapable # Associated lexer - var _lexer: Lexer + var lexer: Lexer # Stack of pushed states and productions - var _stack: Array[State] + private var stack = new Array[State] # Position in the stack - 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 @@ -154,42 +145,51 @@ class Parser return node else if action_type == 3 then # ERROR # skip injected tokens - while token._location == null do token = lexer.next - var node2 = new AParserError.init_parser_error("Syntax error: unexpected {token}.", token.location, token) + while not isset token._location do token = lexer.next + 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 - var _reduce_table: Array[ReduceAction] + private var reduce_table: Array[ReduceAction] is noinit private fun build_reduce_table is abstract end redef class Prod # Location on the first token after the start of a production - # So outside the production for epilon production - var _first_location: nullable Location + # So outside the production for epsilon production + var first_location: nullable Location + + # Join the text of all visited tokens + fun collect_text: String + do + var v = new TextCollectorVisitor + v.enter_visit(self) + assert v.text != "" + return v.text + end end # Find location of production nodes # Uses existing token locations to infer location of productions. private class ComputeProdLocationVisitor super Visitor - # Currenlty visited productions that need a first token - var _need_first_prods: Array[Prod] = new Array[Prod] + # Currently visited productions that need a first token + var need_first_prods = new Array[Prod] # Already visited epsilon productions that waits something after them - var _need_after_epsilons: Array[Prod] = new Array[Prod] + var need_after_epsilons = new Array[Prod] # Location of the last visited token in the current production - var _last_location: nullable Location = null + var last_location: nullable Location = null redef fun visit(n: ANode) do if n isa Token then + if not isset n._location then return var loc = n._location - if loc == null then return _last_location = loc # Add a first token to productions that need one @@ -220,7 +220,11 @@ private class ComputeProdLocationVisitor var endl = _last_location assert endl != null - 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) @@ -236,11 +240,20 @@ private class ComputeProdLocationVisitor end end end +end - init do end +private class TextCollectorVisitor + super Visitor + var text: String = "" + redef fun visit(n) + do + if n isa Token then text += n.text + n.visit_all(self) + end end -# Each reduca action has its own class, this one is the root of the hierarchy. + +# Each reduce action has its own class, this one is the root of the hierarchy. private abstract class ReduceAction fun action(p: Parser) is abstract fun concat(l1, l2 : Array[Object]): Array[Object] @@ -249,6 +262,5 @@ private abstract class ReduceAction l1.append(l2) return l1 end - var _goto: Int - init(g: Int) do _goto = g + var goto: Int end