From 03d5fb1244268fff521df5c2e7d89c6d1361d5a7 Mon Sep 17 00:00:00 2001
From: Renata Hodovan
Date: Thu, 11 Aug 2016 00:49:45 +0200
Subject: [PATCH] Make Python targets more pythonic.
The Python implementations are completely synchronous
with the Java version even if some of the constructs
can be expressed with simpler Python solutions. These are
typically the all, any, count, next builtins or the list
comprehensions, etc. Beside using them makes the code
clearer, they are also prefered by the standard and can
result in performance speedup. The patch contains such
equivalent transformations in the Python targets.
---
runtime/Python2/src/antlr4/IntervalSet.py | 12 ++---
runtime/Python2/src/antlr4/ListTokenSource.py | 4 +-
.../Python2/src/antlr4/PredictionContext.py | 5 +-
.../Python2/src/antlr4/atn/ATNConfigSet.py | 23 +++------
runtime/Python2/src/antlr4/atn/ATNState.py | 5 +-
.../src/antlr4/atn/LexerATNSimulator.py | 6 +--
.../Python2/src/antlr4/atn/PredictionMode.py | 47 +++++-------------
.../Python2/src/antlr4/atn/SemanticContext.py | 37 ++++----------
runtime/Python2/src/antlr4/dfa/DFAState.py | 9 +---
runtime/Python2/src/antlr4/tree/Trees.py | 3 +-
runtime/Python2/src/antlr4/xpath/XPath.py | 17 ++-----
runtime/Python3/src/antlr4/IntervalSet.py | 12 ++---
runtime/Python3/src/antlr4/ListTokenSource.py | 4 +-
.../Python3/src/antlr4/PredictionContext.py | 5 +-
.../Python3/src/antlr4/atn/ATNConfigSet.py | 23 +++------
runtime/Python3/src/antlr4/atn/ATNState.py | 5 +-
.../src/antlr4/atn/LexerATNSimulator.py | 6 +--
.../Python3/src/antlr4/atn/PredictionMode.py | 48 +++++--------------
.../Python3/src/antlr4/atn/SemanticContext.py | 38 +++++----------
runtime/Python3/src/antlr4/dfa/DFAState.py | 9 +---
runtime/Python3/src/antlr4/tree/Trees.py | 3 +-
runtime/Python3/src/antlr4/xpath/XPath.py | 16 ++-----
22 files changed, 88 insertions(+), 249 deletions(-)
diff --git a/runtime/Python2/src/antlr4/IntervalSet.py b/runtime/Python2/src/antlr4/IntervalSet.py
index e28a556d4..3a55a2631 100644
--- a/runtime/Python2/src/antlr4/IntervalSet.py
+++ b/runtime/Python2/src/antlr4/IntervalSet.py
@@ -97,16 +97,10 @@ class IntervalSet(object):
if self.intervals is None:
return False
else:
- for i in self.intervals:
- if item in i:
- return True
- return False
+ return any(item in i for i in self.intervals)
def __len__(self):
- xlen = 0
- for i in self.intervals:
- xlen += len(i)
- return xlen
+ return sum(len(i) for i in self.intervals)
def removeRange(self, v):
if v.start==v.stop-1:
@@ -126,7 +120,7 @@ class IntervalSet(object):
# check for included range, remove it
elif v.start<=i.start and v.stop>=i.stop:
self.intervals.pop(k)
- k = k - 1 # need another pass
+ k -= 1 # need another pass
# check for lower boundary
elif v.start1:
- return True
- return False
+ return any(len(alts) > 1 for alts in altsets)
#
# Determines if every alternative subset in {@code altsets} is equivalent.
@@ -448,13 +436,9 @@ class PredictionMode(object):
#
@classmethod
def allSubsetsEqual(cls, altsets):
- first = None
- for alts in altsets:
- if first is None:
- first = alts
- elif not alts==first:
- return False
- return True
+ if not altsets:
+ return True
+ return all(alts == altsets[0] for alts in altsets[1:])
#
# Returns the unique alternative predicted by all alternative subsets in
@@ -467,10 +451,8 @@ class PredictionMode(object):
def getUniqueAlt(cls, altsets):
all = cls.getAlts(altsets)
if len(all)==1:
- for one in all:
- return one
- else:
- return ATN.INVALID_ALT_NUMBER
+ return all.pop()
+ return ATN.INVALID_ALT_NUMBER
# Gets the complete set of represented alternatives for a collection of
# alternative subsets. This method returns the union of each {@link BitSet}
@@ -481,10 +463,7 @@ class PredictionMode(object):
#
@classmethod
def getAlts(cls, altsets):
- all = set()
- for alts in altsets:
- all = all | alts
- return all
+ return set.union(*altsets)
#
# This function gets the conflicting alt subsets from a configuration set.
@@ -528,11 +507,7 @@ class PredictionMode(object):
@classmethod
def hasStateAssociatedWithOneAlt(cls, configs):
- x = cls.getStateToAltMap(configs)
- for alts in x.values():
- if len(alts)==1:
- return True
- return False
+ return any(len(alts) == 1 for alts in cls.getStateToAltMap(configs).values())
@classmethod
def getSingleViableAlt(cls, altsets):
diff --git a/runtime/Python2/src/antlr4/atn/SemanticContext.py b/runtime/Python2/src/antlr4/atn/SemanticContext.py
index 021d4770c..b8fe7b1a0 100644
--- a/runtime/Python2/src/antlr4/atn/SemanticContext.py
+++ b/runtime/Python2/src/antlr4/atn/SemanticContext.py
@@ -115,14 +115,7 @@ def orContext(a, b):
return result
def filterPrecedencePredicates(collection):
- result = []
- for context in collection:
- if isinstance(context, PrecedencePredicate):
- if result is None:
- result = []
- result.append(context)
- return result
-
+ return [context for context in collection if isinstance(context, PrecedencePredicate)]
class Predicate(SemanticContext):
@@ -187,13 +180,11 @@ class AND(SemanticContext):
def __init__(self, a, b):
operands = set()
if isinstance( a, AND):
- for o in a.opnds:
- operands.add(o)
+ operands.update(a.opnds)
else:
operands.add(a)
if isinstance( b, AND):
- for o in b.opnds:
- operands.add(o)
+ operands.update(b.opnds)
else:
operands.add(b)
@@ -203,7 +194,7 @@ class AND(SemanticContext):
reduced = min(precedencePredicates)
operands.add(reduced)
- self.opnds = [ o for o in operands ]
+ self.opnds = list(operands)
def __eq__(self, other):
if self is other:
@@ -227,10 +218,7 @@ class AND(SemanticContext):
# unordered.
#
def eval(self, parser, outerContext):
- for opnd in self.opnds:
- if not opnd.eval(parser, outerContext):
- return False
- return True
+ return all(opnd.eval(parser, outerContext) for opnd in self.opnds)
def evalPrecedence(self, parser, outerContext):
differs = False
@@ -277,13 +265,11 @@ class OR (SemanticContext):
def __init__(self, a, b):
operands = set()
if isinstance( a, OR):
- for o in a.opnds:
- operands.add(o)
+ operands.update(a.opnds)
else:
operands.add(a)
if isinstance( b, OR):
- for o in b.opnds:
- operands.add(o)
+ operands.update(b.opnds)
else:
operands.add(b)
@@ -291,10 +277,10 @@ class OR (SemanticContext):
if len(precedencePredicates)>0:
# interested in the transition with the highest precedence
s = sorted(precedencePredicates)
- reduced = s[len(s)-1]
+ reduced = s[-1]
operands.add(reduced)
- self.opnds = [ o for o in operands ]
+ self.opnds = list(operands)
def __eq__(self, other):
if self is other:
@@ -315,10 +301,7 @@ class OR (SemanticContext):
# unordered.
#
def eval(self, parser, outerContext):
- for opnd in self.opnds:
- if opnd.eval(parser, outerContext):
- return True
- return False
+ return any(opnd.eval(parser, outerContext) for opnd in self.opnds)
def evalPrecedence(self, parser, outerContext):
differs = False
diff --git a/runtime/Python2/src/antlr4/dfa/DFAState.py b/runtime/Python2/src/antlr4/dfa/DFAState.py
index 85ccac106..7045f7c22 100644
--- a/runtime/Python2/src/antlr4/dfa/DFAState.py
+++ b/runtime/Python2/src/antlr4/dfa/DFAState.py
@@ -105,14 +105,9 @@ class DFAState(object):
# Get the set of all alts mentioned by all ATN configurations in this
# DFA state.
def getAltSet(self):
- alts = set()
if self.configs is not None:
- for c in self.configs:
- alts.add(c.alt)
- if len(alts)==0:
- return None
- else:
- return alts
+ return set(cfg.alt for cfg in self.configs) or None
+ return None
def __hash__(self):
return hash(self.configs)
diff --git a/runtime/Python2/src/antlr4/tree/Trees.py b/runtime/Python2/src/antlr4/tree/Trees.py
index d48f4a904..00a322b45 100644
--- a/runtime/Python2/src/antlr4/tree/Trees.py
+++ b/runtime/Python2/src/antlr4/tree/Trees.py
@@ -129,8 +129,7 @@ class Trees(object):
@classmethod
def descendants(cls, t):
- nodes = []
- nodes.append(t)
+ nodes = [t]
for i in range(0, t.getChildCount()):
nodes.extend(cls.descendants(t.getChild(i)))
return nodes
diff --git a/runtime/Python2/src/antlr4/xpath/XPath.py b/runtime/Python2/src/antlr4/xpath/XPath.py
index eee87da6f..e138d3cdf 100644
--- a/runtime/Python2/src/antlr4/xpath/XPath.py
+++ b/runtime/Python2/src/antlr4/xpath/XPath.py
@@ -289,12 +289,7 @@ class XPathRuleElement(XPathElement):
def evaluate(self, t):
# return all children of t that match nodeName
- nodes = []
- for c in Trees.getChildren(t):
- if isinstance(c, ParserRuleContext ):
- if (c.ruleIndex == self.ruleIndex ) == (not self.invert):
- nodes.append(c)
- return nodes
+ return [c for c in Trees.getChildren(t) if isinstance(c, ParserRuleContext) and (c.ruleIndex == self.ruleIndex) == (not self.invert)]
class XPathTokenAnywhereElement(XPathElement):
@@ -314,12 +309,8 @@ class XPathTokenElement(XPathElement):
def evaluate(self, t):
# return all children of t that match nodeName
- nodes = []
- for c in Trees.getChildren(t):
- if isinstance(c, TerminalNode):
- if (c.symbol.type == self.tokenType ) == (not self.invert):
- nodes.append(c)
- return nodes
+ return [c for c in Trees.getChildren(t) if isinstance(c, TerminalNode) and (c.symbol.type == self.tokenType) == (not self.invert)]
+
class XPathWildcardAnywhereElement(XPathElement):
@@ -343,4 +334,4 @@ class XPathWildcardElement(XPathElement):
if self.invert:
return list() # !* is weird but valid (empty)
else:
- return Trees.getChildren(t)
\ No newline at end of file
+ return Trees.getChildren(t)
diff --git a/runtime/Python3/src/antlr4/IntervalSet.py b/runtime/Python3/src/antlr4/IntervalSet.py
index e5f535f45..980509821 100644
--- a/runtime/Python3/src/antlr4/IntervalSet.py
+++ b/runtime/Python3/src/antlr4/IntervalSet.py
@@ -84,16 +84,10 @@ class IntervalSet(object):
if self.intervals is None:
return False
else:
- for i in self.intervals:
- if item in i:
- return True
- return False
+ return any(item in i for i in self.intervals)
def __len__(self):
- xlen = 0
- for i in self.intervals:
- xlen += len(i)
- return xlen
+ return sum(len(i) for i in self.intervals)
def removeRange(self, v):
if v.start==v.stop-1:
@@ -113,7 +107,7 @@ class IntervalSet(object):
# check for included range, remove it
elif v.start<=i.start and v.stop>=i.stop:
self.intervals.pop(k)
- k = k - 1 # need another pass
+ k -= 1 # need another pass
# check for lower boundary
elif v.start DFAState:
proposed = DFAState(configs=configs)
- firstConfigWithRuleStopState = None
- for c in configs:
- if isinstance(c.state, RuleStopState):
- firstConfigWithRuleStopState = c
- break
+ firstConfigWithRuleStopState = next((cfg for cfg in configs if isinstance(cfg.state, RuleStopState)), None)
if firstConfigWithRuleStopState is not None:
proposed.isAcceptState = True
diff --git a/runtime/Python3/src/antlr4/atn/PredictionMode.py b/runtime/Python3/src/antlr4/atn/PredictionMode.py
index 03ca896c7..67039c728 100644
--- a/runtime/Python3/src/antlr4/atn/PredictionMode.py
+++ b/runtime/Python3/src/antlr4/atn/PredictionMode.py
@@ -235,10 +235,7 @@ class PredictionMode(Enum):
# {@link RuleStopState}, otherwise {@code false}
@classmethod
def hasConfigInRuleStopState(cls, configs:ATNConfigSet):
- for c in configs:
- if isinstance(c.state, RuleStopState):
- return True
- return False
+ return any(isinstance(cfg.state, RuleStopState) for cfg in configs)
# Checks if all configurations in {@code configs} are in a
# {@link RuleStopState}. Configurations meeting this condition have reached
@@ -250,10 +247,7 @@ class PredictionMode(Enum):
# {@link RuleStopState}, otherwise {@code false}
@classmethod
def allConfigsInRuleStopStates(cls, configs:ATNConfigSet):
- for config in configs:
- if not isinstance(config.state, RuleStopState):
- return False
- return True
+ return all(isinstance(cfg.state, RuleStopState) for cfg in configs)
#
# Full LL prediction termination.
@@ -422,10 +416,7 @@ class PredictionMode(Enum):
#
@classmethod
def hasNonConflictingAltSet(cls, altsets:list):
- for alts in altsets:
- if len(alts)==1:
- return True
- return False
+ return any(len(alts) == 1 for alts in altsets)
#
# Determines if any single alternative subset in {@code altsets} contains
@@ -437,10 +428,7 @@ class PredictionMode(Enum):
#
@classmethod
def hasConflictingAltSet(cls, altsets:list):
- for alts in altsets:
- if len(alts)>1:
- return True
- return False
+ return any(len(alts) > 1 for alts in altsets)
#
# Determines if every alternative subset in {@code altsets} is equivalent.
@@ -451,13 +439,10 @@ class PredictionMode(Enum):
#
@classmethod
def allSubsetsEqual(cls, altsets:list):
- first = None
- for alts in altsets:
- if first is None:
- first = alts
- elif not alts==first:
- return False
- return True
+ if not altsets:
+ return True
+ first = next(iter(altsets))
+ return all(alts == first for alts in iter(altsets))
#
# Returns the unique alternative predicted by all alternative subsets in
@@ -470,10 +455,8 @@ class PredictionMode(Enum):
def getUniqueAlt(cls, altsets:list):
all = cls.getAlts(altsets)
if len(all)==1:
- for one in all:
- return one
- else:
- return ATN.INVALID_ALT_NUMBER
+ return next(iter(all))
+ return ATN.INVALID_ALT_NUMBER
# Gets the complete set of represented alternatives for a collection of
# alternative subsets. This method returns the union of each {@link BitSet}
@@ -484,10 +467,7 @@ class PredictionMode(Enum):
#
@classmethod
def getAlts(cls, altsets:list):
- all = set()
- for alts in altsets:
- all = all | alts
- return all
+ return set.union(*altsets)
#
# This function gets the conflicting alt subsets from a configuration set.
@@ -531,11 +511,7 @@ class PredictionMode(Enum):
@classmethod
def hasStateAssociatedWithOneAlt(cls, configs:ATNConfigSet):
- x = cls.getStateToAltMap(configs)
- for alts in x.values():
- if len(alts)==1:
- return True
- return False
+ return any(len(alts) == 1 for alts in cls.getStateToAltMap(configs).values())
@classmethod
def getSingleViableAlt(cls, altsets:list):
diff --git a/runtime/Python3/src/antlr4/atn/SemanticContext.py b/runtime/Python3/src/antlr4/atn/SemanticContext.py
index c012e35c2..d69165e4d 100644
--- a/runtime/Python3/src/antlr4/atn/SemanticContext.py
+++ b/runtime/Python3/src/antlr4/atn/SemanticContext.py
@@ -116,13 +116,7 @@ def orContext(a:SemanticContext, b:SemanticContext):
return result
def filterPrecedencePredicates(collection:list):
- result = []
- for context in collection:
- if isinstance(context, PrecedencePredicate):
- if result is None:
- result = []
- result.append(context)
- return result
+ return [context for context in collection if isinstance(context, PrecedencePredicate)]
class Predicate(SemanticContext):
@@ -188,13 +182,11 @@ class AND(SemanticContext):
def __init__(self, a:SemanticContext, b:SemanticContext):
operands = set()
if isinstance( a, AND ):
- for o in a.opnds:
- operands.add(o)
+ operands.update(a.opnds)
else:
operands.add(a)
if isinstance( b, AND ):
- for o in b.opnds:
- operands.add(o)
+ operands.update(b.opnds)
else:
operands.add(b)
@@ -204,7 +196,7 @@ class AND(SemanticContext):
reduced = min(precedencePredicates)
operands.add(reduced)
- self.opnds = [ o for o in operands ]
+ self.opnds = list(operands)
def __eq__(self, other):
if self is other:
@@ -227,11 +219,8 @@ class AND(SemanticContext):
# The evaluation of predicates by this context is short-circuiting, but
# unordered.
#
- def eval(self, parser:Recognizer , outerContext:RuleContext ):
- for opnd in self.opnds:
- if not opnd.eval(parser, outerContext):
- return False
- return True
+ def eval(self, parser:Recognizer, outerContext:RuleContext):
+ return all(opnd.eval(parser, outerContext) for opnd in self.opnds)
def evalPrecedence(self, parser:Recognizer, outerContext:RuleContext):
differs = False
@@ -278,13 +267,11 @@ class OR (SemanticContext):
def __init__(self, a:SemanticContext, b:SemanticContext):
operands = set()
if isinstance( a, OR ):
- for o in a.opnds:
- operands.add(o)
+ operands.update(a.opnds)
else:
operands.add(a)
if isinstance( b, OR ):
- for o in b.opnds:
- operands.add(o)
+ operands.update(b.opnds)
else:
operands.add(b)
@@ -292,10 +279,10 @@ class OR (SemanticContext):
if len(precedencePredicates)>0:
# interested in the transition with the highest precedence
s = sorted(precedencePredicates)
- reduced = s[len(s)-1]
+ reduced = s[-1]
operands.add(reduced)
- self.opnds = [ o for o in operands ]
+ self.opnds = list(operands)
def __eq__(self, other):
if self is other:
@@ -316,10 +303,7 @@ class OR (SemanticContext):
# unordered.
#
def eval(self, parser:Recognizer, outerContext:RuleContext):
- for opnd in self.opnds:
- if opnd.eval(parser, outerContext):
- return True
- return False
+ return any(opnd.eval(parser, outerContext) for opnd in self.opnds)
def evalPrecedence(self, parser:Recognizer, outerContext:RuleContext):
differs = False
diff --git a/runtime/Python3/src/antlr4/dfa/DFAState.py b/runtime/Python3/src/antlr4/dfa/DFAState.py
index 1ab5a0e77..9ad996384 100644
--- a/runtime/Python3/src/antlr4/dfa/DFAState.py
+++ b/runtime/Python3/src/antlr4/dfa/DFAState.py
@@ -104,14 +104,9 @@ class DFAState(object):
# Get the set of all alts mentioned by all ATN configurations in this
# DFA state.
def getAltSet(self):
- alts = set()
if self.configs is not None:
- for c in self.configs:
- alts.add(c.alt)
- if len(alts)==0:
- return None
- else:
- return alts
+ return set(cfg.alt for cfg in self.configs) or None
+ return None
def __hash__(self):
return hash(self.configs)
diff --git a/runtime/Python3/src/antlr4/tree/Trees.py b/runtime/Python3/src/antlr4/tree/Trees.py
index 101df6d9a..42fde282b 100644
--- a/runtime/Python3/src/antlr4/tree/Trees.py
+++ b/runtime/Python3/src/antlr4/tree/Trees.py
@@ -130,8 +130,7 @@ class Trees(object):
@classmethod
def descendants(cls, t:ParseTree):
- nodes = []
- nodes.append(t)
+ nodes = [t]
for i in range(0, t.getChildCount()):
nodes.extend(cls.descendants(t.getChild(i)))
return nodes
diff --git a/runtime/Python3/src/antlr4/xpath/XPath.py b/runtime/Python3/src/antlr4/xpath/XPath.py
index 6b41a943a..6d3d825a5 100644
--- a/runtime/Python3/src/antlr4/xpath/XPath.py
+++ b/runtime/Python3/src/antlr4/xpath/XPath.py
@@ -290,12 +290,8 @@ class XPathRuleElement(XPathElement):
def evaluate(self, t:ParseTree):
# return all children of t that match nodeName
- nodes = []
- for c in Trees.getChildren(t):
- if isinstance(c, ParserRuleContext ):
- if (c.ruleIndex == self.ruleIndex ) == (not self.invert):
- nodes.append(c)
- return nodes
+ return [c for c in Trees.getChildren(t) if isinstance(c, ParserRuleContext) and (c.ruleIndex == self.ruleIndex) == (not self.invert)]
+
class XPathTokenAnywhereElement(XPathElement):
@@ -315,12 +311,8 @@ class XPathTokenElement(XPathElement):
def evaluate(self, t:ParseTree):
# return all children of t that match nodeName
- nodes = []
- for c in Trees.getChildren(t):
- if isinstance(c, TerminalNode):
- if (c.symbol.type == self.tokenType ) == (not self.invert):
- nodes.append(c)
- return nodes
+ return [c for c in Trees.getChildren(t) if isinstance(c, TerminalNode) and (c.symbol.type == self.tokenType) == (not self.invert)]
+
class XPathWildcardAnywhereElement(XPathElement):