summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES26
-rw-r--r--pyparsing/__init__.py2
-rw-r--r--pyparsing/helpers.py30
-rw-r--r--tests/test_unit.py22
4 files changed, 66 insertions, 14 deletions
diff --git a/CHANGES b/CHANGES
index 105a644..8e5450b 100644
--- a/CHANGES
+++ b/CHANGES
@@ -28,17 +28,6 @@ help from Devin J. Pohly in structuring the code to enable this peaceful transit
Suggested by Antony Lee (issue #412), PR (#413) by Devin J. Pohly.
-- Added new builtin `python_quoted_string`, which will match any form
- of single-line or multiline quoted strings defined in Python. (Inspired
- by discussion with Andreas Schörgenhumer in Issue #421.)
-
-- Fixed bug in `Word` when `max=2`. Also added performance enhancement
- when specifying `exact` argument. Reported in issue #409 by
- panda-34, nice catch!
-
-- `Word` arguments are now validated if `min` and `max` are both
- given, that `min` <= `max`; raises `ValueError` if values are invalid.
-
- Extended `expr[]` notation for repetition of `expr` to accept a
slice, where the slice's stop value indicates a `stop_on`
expression:
@@ -57,12 +46,27 @@ help from Devin J. Pohly in structuring the code to enable this peaceful transit
['BEGIN', ['aaa', 'bbb', 'ccc'], 'END']
+- Added new builtin `python_quoted_string`, which will match any form
+ of single-line or multiline quoted strings defined in Python. (Inspired
+ by discussion with Andreas Schörgenhumer in Issue #421.)
+
- Added bool `embed` argument to `ParserElement.create_diagram()`.
When passed as True, the resulting diagram will omit the `<DOCTYPE>`,
`<HEAD>`, and `<BODY>` tags so that it can be embedded in other
HTML source. (Useful when embedding a call to `create_diagram()` in
a PyScript HTML page.)
+- Fixed bug in `Word` when `max=2`. Also added performance enhancement
+ when specifying `exact` argument. Reported in issue #409 by
+ panda-34, nice catch!
+
+- `Word` arguments are now validated if `min` and `max` are both
+ given, that `min` <= `max`; raises `ValueError` if values are invalid.
+
+- Fixed bug in `delimited_list`, where sub-expressions within the given
+ expr might not get assigned names or parse actions. Raised in Issue
+ #408 by Mostafa Razi, nice catch, thanks!
+
- Fixed bug in srange, when parsing escaped '/' and '\' inside a
range set.
diff --git a/pyparsing/__init__.py b/pyparsing/__init__.py
index ffe89d0..e502ba3 100644
--- a/pyparsing/__init__.py
+++ b/pyparsing/__init__.py
@@ -121,7 +121,7 @@ class version_info(NamedTuple):
__version_info__ = version_info(3, 0, 10, "final", 0)
-__version_time__ = "05 Jul 2022 01:03 UTC"
+__version_time__ = "09 Jul 2022 13:41 UTC"
__version__ = __version_info__.__version__
__versionTime__ = __version_time__
__author__ = "Paul McGuire <ptmcg.gm+pyparsing@gmail.com>"
diff --git a/pyparsing/helpers.py b/pyparsing/helpers.py
index 802389c..ecb382b 100644
--- a/pyparsing/helpers.py
+++ b/pyparsing/helpers.py
@@ -1,6 +1,7 @@
# helpers.py
import html.entities
import re
+import sys
import typing
from . import __diag__
@@ -46,7 +47,34 @@ def delimited_list(
expr = ParserElement._literalStringClass(expr)
expr = typing.cast(ParserElement, expr)
- expr_copy = expr.copy().streamline()
+ def make_deep_name_copy(expr):
+ from collections import deque
+ MAX_EXPRS = sys.getrecursionlimit()
+ seen = set()
+ to_visit = deque([(None, expr)])
+ cpy = None
+ num_exprs = 0
+ while to_visit and num_exprs < MAX_EXPRS:
+ parent, cur = to_visit.pop()
+ num_exprs += 1
+ if cur in seen:
+ continue
+ seen.add(cur)
+ cur = cur.copy()
+ if parent is None:
+ cpy = cur
+ else:
+ if hasattr(parent, "expr"):
+ parent.expr = cur
+ elif hasattr(parent, "exprs"):
+ parent.exprs.append(cur)
+
+ to_visit.extend((cur, sub) for sub in cur.recurse()[::-1])
+ getattr(cur, "exprs", []).clear()
+
+ return cpy
+
+ expr_copy = make_deep_name_copy(expr).streamline()
dlName = f"{expr_copy} [{delim} {expr_copy}]...{f' [{delim}]' if allow_trailing_delim else ''}"
if not combine:
diff --git a/tests/test_unit.py b/tests/test_unit.py
index 59e549a..0687f1c 100644
--- a/tests/test_unit.py
+++ b/tests/test_unit.py
@@ -8262,7 +8262,27 @@ class Test02_WithoutPackrat(ppt.TestParseResultsAsserts, TestCase):
print(bool_constant)
print(bool_constant.streamline())
print(bool_list2)
- self.assertEqual("bool [, bool]...", str(bool_list2))
+ with self.subTest():
+ self.assertEqual("bool [, bool]...", str(bool_list2))
+
+ with self.subTest():
+ street_address = pp.common.integer.set_name("integer") + pp.Word(pp.alphas)[1, ...].set_name("street_name")
+ self.assertEqual(
+ "{integer street_name} [, {integer street_name}]...",
+ str(pp.delimitedList(street_address))
+ )
+
+ with self.subTest():
+ operand = pp.Char(pp.alphas).set_name("var")
+ math = pp.infixNotation(operand,
+ [
+ (pp.one_of("+ -"), 2, pp.opAssoc.LEFT),
+ ])
+ self.assertEqual(
+ "Forward: + | - term [, Forward: + | - term]...",
+ str(pp.delimitedList(math))
+ )
+
def testDelimitedListOfStrLiterals(self):
expr = pp.delimitedList("ABC")