summaryrefslogtreecommitdiff
path: root/pyparsing.py
diff options
context:
space:
mode:
authorPaul McGuire <ptmcg@austin.rr.com>2019-08-02 23:34:38 -0500
committerPaul McGuire <ptmcg@austin.rr.com>2019-08-02 23:34:38 -0500
commit4c6e4675a7f2aa92c8535741fe8432f3f1656be9 (patch)
treefceb289395102ed0973b53ce824251c14af1b15c /pyparsing.py
parent07d82bb767d75a0a30bd6f806938c1f9fe50d8ee (diff)
downloadpyparsing-git-4c6e4675a7f2aa92c8535741fe8432f3f1656be9.tar.gz
Manually merge 2.4.2 changes from master back to 2.4.x branch
Diffstat (limited to 'pyparsing.py')
-rw-r--r--pyparsing.py67
1 files changed, 42 insertions, 25 deletions
diff --git a/pyparsing.py b/pyparsing.py
index af0cff0..3854210 100644
--- a/pyparsing.py
+++ b/pyparsing.py
@@ -95,8 +95,8 @@ classes inherit from. Use the docstrings for examples of how to:
namespace class
"""
-__version__ = "2.4.1"
-__versionTime__ = "20 Jul 2019 18:17 UTC"
+__version__ = "2.4.2"
+__versionTime__ = "29 Jul 2019 02:58 UTC"
__author__ = "Paul McGuire <ptmcg@users.sourceforge.net>"
import string
@@ -165,24 +165,24 @@ __compat__.collect_all_And_tokens = True
__diag__ = SimpleNamespace()
__diag__.__doc__ = """
-Diagnostic configuration
+Diagnostic configuration (all default to False)
- warn_multiple_tokens_in_named_alternation - flag to enable warnings when a results
name is defined on a MatchFirst or Or expression with one or more And subexpressions
- (default=True) (only warns if __compat__.collect_all_And_tokens is False)
+ (only warns if __compat__.collect_all_And_tokens is False)
- warn_ungrouped_named_tokens_in_collection - flag to enable warnings when a results
name is defined on a containing expression with ungrouped subexpressions that also
- have results names (default=True)
+ have results names
- warn_name_set_on_empty_Forward - flag to enable warnings whan a Forward is defined
- with a results name, but has no contents defined (default=False)
+ with a results name, but has no contents defined
- warn_on_multiple_string_args_to_oneof - flag to enable warnings whan oneOf is
- incorrectly called with multiple str arguments (default=True)
+ incorrectly called with multiple str arguments
- enable_debug_on_named_expressions - flag to auto-enable debug on all subsequent
- calls to ParserElement.setName() (default=False)
+ calls to ParserElement.setName()
"""
-__diag__.warn_multiple_tokens_in_named_alternation = True
-__diag__.warn_ungrouped_named_tokens_in_collection = True
+__diag__.warn_multiple_tokens_in_named_alternation = False
+__diag__.warn_ungrouped_named_tokens_in_collection = False
__diag__.warn_name_set_on_empty_Forward = False
-__diag__.warn_on_multiple_string_args_to_oneof = True
+__diag__.warn_on_multiple_string_args_to_oneof = False
__diag__.enable_debug_on_named_expressions = False
# ~ sys.stderr.write("testing pyparsing module, version %s, %s\n" % (__version__, __versionTime__))
@@ -2210,8 +2210,11 @@ class ParserElement(object):
occurrences. If this behavior is desired, then write
``expr*(None, n) + ~expr``
"""
- if other is Ellipsis or other == (Ellipsis,):
- other = (1, None)
+ if other is Ellipsis:
+ other = (0, None)
+ elif isinstance(other, tuple) and other[:1] == (Ellipsis,):
+ other = ((0, ) + other[1:] + (None,))[:2]
+
if isinstance(other, int):
minElements, optElements = other, 0
elif isinstance(other, tuple):
@@ -2345,6 +2348,11 @@ class ParserElement(object):
"""
return NotAny(self)
+ def __iter__(self):
+ # must implement __iter__ to override legacy use of sequential access to __getitem__ to
+ # iterate over a sequence
+ raise TypeError('%r object is not iterable' % self.__class__.__name__)
+
def __getitem__(self, key):
"""
use ``[]`` indexing notation as a short form for expression repetition:
@@ -2355,9 +2363,8 @@ class ParserElement(object):
(read as "at least n instances of ``expr``")
- ``expr[..., n]`` is equivalent to ``expr*(0, n)``
(read as "0 to n instances of ``expr``")
- - ``expr[0, ...]`` is equivalent to ``ZeroOrMore(expr)``
+ - ``expr[...]`` and ``expr[0, ...]`` are equivalent to ``ZeroOrMore(expr)``
- ``expr[1, ...]`` is equivalent to ``OneOrMore(expr)``
- - ``expr[...]`` is equivalent to ``OneOrMore(expr)``
``None`` may be used in place of ``...``.
Note that ``expr[..., n]`` and ``expr[m, n]``do not raise an exception
@@ -2371,7 +2378,7 @@ class ParserElement(object):
key = (key,)
iter(key)
except TypeError:
- key = (key,)
+ key = (key, key)
if len(key) > 2:
warnings.warn("only 1 or 2 index arguments supported ({0}{1})".format(key[:5],
@@ -3836,6 +3843,8 @@ class ParseExpression(ParserElement):
if isinstance(exprs, basestring):
self.exprs = [self._literalStringClass(exprs)]
+ elif isinstance(exprs, ParserElement):
+ self.exprs = [exprs]
elif isinstance(exprs, Iterable):
exprs = list(exprs)
# if sequence of strings provided, wrap with Literal
@@ -3989,15 +3998,17 @@ class And(ParseExpression):
def streamline(self):
# collapse any _PendingSkip's
- if any(isinstance(e, ParseExpression) and isinstance(e.exprs[-1], _PendingSkip) for e in self.exprs[:-1]):
- for i, e in enumerate(self.exprs[:-1]):
- if e is None:
- continue
- if (isinstance(e, ParseExpression)
- and isinstance(e.exprs[-1], _PendingSkip)):
- e.exprs[-1] = e.exprs[-1] + self.exprs[i + 1]
- self.exprs[i + 1] = None
- self.exprs = [e for e in self.exprs if e is not None]
+ if self.exprs:
+ if any(isinstance(e, ParseExpression) and e.exprs and isinstance(e.exprs[-1], _PendingSkip)
+ for e in self.exprs[:-1]):
+ for i, e in enumerate(self.exprs[:-1]):
+ if e is None:
+ continue
+ if (isinstance(e, ParseExpression)
+ and e.exprs and isinstance(e.exprs[-1], _PendingSkip)):
+ e.exprs[-1] = e.exprs[-1] + self.exprs[i + 1]
+ self.exprs[i + 1] = None
+ self.exprs = [e for e in self.exprs if e is not None]
super(And, self).streamline()
self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs)
@@ -4105,6 +4116,12 @@ class Or(ParseExpression):
# might change whether or how much they match of the input.
matches.sort(key=itemgetter(0), reverse=True)
+ if not doActions:
+ # no further conditions or parse actions to change the selection of
+ # alternative, so the first match will be the best match
+ best_expr = matches[0][1]
+ return best_expr._parse(instring, loc, doActions)
+
longest = -1, None
for loc1, expr1 in matches:
if loc1 <= longest[0]: