From 7eedebf6bde12bed517ee4d1b041fb69bc76ddc2 Mon Sep 17 00:00:00 2001 From: Jean Privat Date: Sun, 24 Jun 2012 13:15:22 -0400 Subject: [PATCH] parser: guard loops in ComputeProdLocationVisitor Most of the time, _need arrays are empty. So, add 'if' to do the work only if there is work to do. Signed-off-by: Jean Privat --- src/parser/parser.nit | 48 ++++++++++++++++++++++++++------------------- src/parser/xss/parser.xss | 48 ++++++++++++++++++++++++++------------------- 2 files changed, 56 insertions(+), 40 deletions(-) diff --git a/src/parser/parser.nit b/src/parser/parser.nit index 7e931d7..c2ede2b 100644 --- a/src/parser/parser.nit +++ b/src/parser/parser.nit @@ -947,20 +947,24 @@ private class ComputeProdLocationVisitor _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 + 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) + end + _need_after_epsilons.clear end - _need_after_epsilons.clear else assert n isa Prod _need_first_prods.add(n) @@ -979,19 +983,23 @@ private class ComputeProdLocationVisitor 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) + if not _need_before_epsilons.is_empty then + var loc = new Location(startl.file, startl.line_start, startl.line_start, startl.column_start, startl.column_start) + for no in _need_before_epsilons do + # Epsilon production that starts the current non-epsilon production + no.location = loc + end + _need_before_epsilons.clear 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 diff --git a/src/parser/xss/parser.xss b/src/parser/xss/parser.xss index 3a8cc06..45d4590 100644 --- a/src/parser/xss/parser.xss +++ b/src/parser/xss/parser.xss @@ -206,20 +206,24 @@ private class ComputeProdLocationVisitor _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 + 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) + end + _need_after_epsilons.clear end - _need_after_epsilons.clear else assert n isa Prod _need_first_prods.add(n) @@ -238,19 +242,23 @@ private class ComputeProdLocationVisitor 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) + if not _need_before_epsilons.is_empty then + var loc = new Location(startl.file, startl.line_start, startl.line_start, startl.column_start, startl.column_start) + for no in _need_before_epsilons do + # Epsilon production that starts the current non-epsilon production + no.location = loc + end + _need_before_epsilons.clear 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 -- 1.7.9.5