return new Start(null, token)
end
+ var state = self.state
var index = token.parser_index
var action_type = parser_action(state, 2)
var action_value = parser_action(state, 3)
(new ComputeProdLocationVisitor).enter_visit(node)
return node
else if action_type == 3 then # ERROR
- var node2 = new PError.init_error("Syntax error: unexpected {token}.", token.location)
+ var node2 = new PParserError.init_parser_error("Syntax error: unexpected {token}.", token.location, token)
var node = new Start(null, node2)
return node
end
# Location on the first token after the start of a production
# So outside the production for epilon production
var _first_location: nullable Location
-
- # Location of the last token before the end of a production
- # So outside the production for epilon production
- var _last_location: nullable Location
end
# Find location of production nodes
# Already visited epsilon productions that waits something after them
var _need_after_epsilons: Array[Prod] = new Array[Prod]
- # Already visited epsilon production that waits something before them
- var _need_before_epsilons: Array[Prod] = new Array[Prod]
-
# Location of the last visited token in the current production
var _last_location: nullable Location = null
- redef fun visit(n: nullable PNode)
+ redef fun visit(n: ANode)
do
- if n == null then
- return
- else if n isa Token then
+ if n isa Token then
var loc = n.location
_last_location = loc
# Add a first token to productions that need one
- for no in _need_first_prods do
- no._first_location = loc
+ if not _need_first_prods.is_empty then
+ for no in _need_first_prods do
+ no._first_location = loc
+ end
+ _need_first_prods.clear
end
- _need_first_prods.clear
# Find location for already visited epsilon production that need one
- for no in _need_after_epsilons do
- # Epsilon production that is in the middle of a non-epsilon production
- # The epsilon production has both a token before and after it
- var endl = loc
- var startl = no._last_location
- no.location = new Location(endl.file, startl.line_end, endl.line_start, startl.column_end, endl.column_start)
+ if not _need_after_epsilons.is_empty then
+ var loco = new Location(loc.file, loc.line_start, loc.line_start, loc.column_start, loc.column_start)
+ for no in _need_after_epsilons do
+ no.location = loco
+ end
+ _need_after_epsilons.clear
end
- _need_after_epsilons.clear
else
assert n isa Prod
_need_first_prods.add(n)
- var old_last = _last_location
- _last_location = null
n.visit_all(self)
- var endl = _last_location
- if endl == null then _last_location = old_last
- n._last_location = endl
var startl = n._first_location
if startl != null then
# Non-epsilon production
+ 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)
- for no in _need_before_epsilons do
- # Epsilon production that starts the current non-epsilon production
- #var startl = n.location
- no.location = new Location(startl.file, startl.line_start, startl.line_start, startl.column_start, startl.column_start)
- end
- _need_before_epsilons.clear
-
- for no in _need_after_epsilons do
- # Epsilon production that finishes the current non-epsilon production
- #var endl = n.location
- no.location = new Location(endl.file, endl.line_end, endl.line_end, endl.column_end, endl.column_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)
+ for no in _need_after_epsilons do
+ # Epsilon production that finishes the current non-epsilon production
+ no.location = loc
+ end
+ _need_after_epsilons.clear
end
- _need_after_epsilons.clear
else
- # No first token means epsilon production (or "throw all my tokens" production)
- # So, it must be located it later
- if endl == null then
- # Epsilon production that starts a parent non-epsilon production
- _need_before_epsilons.add(n)
- else
- # Epsilon production in the middle or that finishes a parent non-epsilon production
- _need_after_epsilons.add(n)
- end
+ # Epsilon production in the middle or that finishes a parent non-epsilon production
+ _need_after_epsilons.add(n)
end
end
end
var ${translate(@result,"ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz")} = new Array[Object]
$ end
$ when {@cmd='MAKENODE'}
+$ if {count(arg)!=0}
var ${translate(@result,"ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz")}: nullable @etype = new @etype.init_${translate(@etype,"ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz")}(
$ foreach {arg}
$ if @null
$ end
$ end foreach
)
+$ else
+ var ${translate(@result,"ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz")}: nullable @etype = new @etype.init_${translate(@etype,"ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz")}
+$ end
$ end
$ when {@cmd='RETURNNODE'}
$ if @null