# 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.
class Parser
super TablesCapable
# Associated lexer
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
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
redef class Prod
# Location on the first token after the start of a production
- # So outside the production for epilon production
+ # 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 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)
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]
return l1
end
var goto: Int
- init(g: Int) do _goto = g
end