Browse Source

Intermediate changes
commit_hash:16645c680befa673cec2481eceae5781024fdb0e

robot-piglet 1 month ago
parent
commit
0395c50870

+ 1 - 1
contrib/python/pyparsing/py3/.dist-info/METADATA

@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: pyparsing
-Version: 3.2.0
+Version: 3.2.1
 Summary: pyparsing module - Classes and methods to define and execute parsing grammars
 Author-email: Paul McGuire <ptmcg.gm+pyparsing@gmail.com>
 Requires-Python: >=3.9

+ 2 - 2
contrib/python/pyparsing/py3/pyparsing/__init__.py

@@ -120,8 +120,8 @@ class version_info(NamedTuple):
         return f"{__name__}.{type(self).__name__}({', '.join('{}={!r}'.format(*nv) for nv in zip(self._fields, self))})"
 
 
-__version_info__ = version_info(3, 2, 0, "final", 1)
-__version_time__ = "13 Oct 2024 09:46 UTC"
+__version_info__ = version_info(3, 2, 1, "final", 1)
+__version_time__ = "31 Dec 2024 20:41 UTC"
 __version__ = __version_info__.__version__
 __versionTime__ = __version_time__
 __author__ = "Paul McGuire <ptmcg.gm+pyparsing@gmail.com>"

+ 27 - 14
contrib/python/pyparsing/py3/pyparsing/actions.py

@@ -1,21 +1,34 @@
 # actions.py
+from __future__ import annotations
+
+from typing import Union, Callable, Any
 
 from .exceptions import ParseException
 from .util import col, replaced_by_pep8
+from .results import ParseResults
+
+
+ParseAction = Union[
+    Callable[[], Any],
+    Callable[[ParseResults], Any],
+    Callable[[int, ParseResults], Any],
+    Callable[[str, int, ParseResults], Any],
+]
 
 
 class OnlyOnce:
     """
     Wrapper for parse actions, to ensure they are only called once.
+    Note: parse action signature must include all 3 arguments.
     """
 
-    def __init__(self, method_call):
+    def __init__(self, method_call: Callable[[str, int, ParseResults], Any]):
         from .core import _trim_arity
 
         self.callable = _trim_arity(method_call)
         self.called = False
 
-    def __call__(self, s, l, t):
+    def __call__(self, s: str, l: int, t: ParseResults) -> ParseResults:
         if not self.called:
             results = self.callable(s, l, t)
             self.called = True
@@ -30,20 +43,20 @@ class OnlyOnce:
         self.called = False
 
 
-def match_only_at_col(n):
+def match_only_at_col(n: int) -> ParseAction:
     """
     Helper method for defining parse actions that require matching at
     a specific column in the input text.
     """
 
-    def verify_col(strg, locn, toks):
+    def verify_col(strg: str, locn: int, toks: ParseResults) -> None:
         if col(locn, strg) != n:
             raise ParseException(strg, locn, f"matched token not at column {n}")
 
     return verify_col
 
 
-def replace_with(repl_str):
+def replace_with(repl_str: str) -> ParseAction:
     """
     Helper method for common parse actions that simply return
     a literal value.  Especially useful when used with
@@ -60,7 +73,7 @@ def replace_with(repl_str):
     return lambda s, l, t: [repl_str]
 
 
-def remove_quotes(s, l, t):
+def remove_quotes(s: str, l: int, t: ParseResults) -> Any:
     """
     Helper parse action for removing quotation marks from parsed
     quoted strings.
@@ -77,7 +90,7 @@ def remove_quotes(s, l, t):
     return t[0][1:-1]
 
 
-def with_attribute(*args, **attr_dict):
+def with_attribute(*args: tuple[str, str], **attr_dict) -> ParseAction:
     """
     Helper to create a validating parse action to be used with start
     tags created with :class:`make_xml_tags` or
@@ -133,17 +146,17 @@ def with_attribute(*args, **attr_dict):
         1 4 0 1 0
         1,3 2,3 1,1
     """
+    attrs_list: list[tuple[str, str]] = []
     if args:
-        attrs = args[:]
+        attrs_list.extend(args)
     else:
-        attrs = attr_dict.items()
-    attrs = [(k, v) for k, v in attrs]
+        attrs_list.extend(attr_dict.items())
 
-    def pa(s, l, tokens):
-        for attrName, attrValue in attrs:
+    def pa(s: str, l: int, tokens: ParseResults) -> None:
+        for attrName, attrValue in attrs_list:
             if attrName not in tokens:
                 raise ParseException(s, l, "no matching attribute " + attrName)
-            if attrValue != with_attribute.ANY_VALUE and tokens[attrName] != attrValue:
+            if attrValue != with_attribute.ANY_VALUE and tokens[attrName] != attrValue:  # type: ignore [attr-defined]
                 raise ParseException(
                     s,
                     l,
@@ -156,7 +169,7 @@ def with_attribute(*args, **attr_dict):
 with_attribute.ANY_VALUE = object()  # type: ignore [attr-defined]
 
 
-def with_class(classname, namespace=""):
+def with_class(classname: str, namespace: str = "") -> ParseAction:
     """
     Simplified version of :class:`with_attribute` when
     matching on a div class - made difficult because ``class`` is

+ 2 - 2
contrib/python/pyparsing/py3/pyparsing/common.py

@@ -210,14 +210,14 @@ class pyparsing_common:
     """any numeric expression, returns the corresponding Python type"""
 
     fnumber = (
-        Regex(r"[+-]?\d+\.?\d*([eE][+-]?\d+)?")
+        Regex(r"[+-]?\d+\.?\d*(?:[eE][+-]?\d+)?")
         .set_name("fnumber")
         .set_parse_action(convert_to_float)
     )
     """any int or real number, returned as float"""
 
     ieee_float = (
-        Regex(r"(?i)[+-]?((\d+\.?\d*(e[+-]?\d+)?)|nan|inf(inity)?)")
+        Regex(r"(?i:[+-]?(?:(?:\d+\.?\d*(?:e[+-]?\d+)?)|nan|inf(?:inity)?))")
         .set_name("ieee_float")
         .set_parse_action(convert_to_float)
     )

+ 9 - 10
contrib/python/pyparsing/py3/pyparsing/core.py

@@ -215,12 +215,7 @@ _single_arg_builtins = {
 _generatorType = types.GeneratorType
 ParseImplReturnType = tuple[int, Any]
 PostParseReturnType = Union[ParseResults, Sequence[ParseResults]]
-ParseAction = Union[
-    Callable[[], Any],
-    Callable[[ParseResults], Any],
-    Callable[[int, ParseResults], Any],
-    Callable[[str, int, ParseResults], Any],
-]
+
 ParseCondition = Union[
     Callable[[], bool],
     Callable[[ParseResults], bool],
@@ -486,6 +481,7 @@ class ParserElement(ABC):
         self.callPreparse = True
         self.callDuringTry = False
         self.suppress_warnings_: list[Diagnostics] = []
+        self.show_in_diagram = True
 
     def suppress_warning(self, warning_type: Diagnostics) -> ParserElement:
         """
@@ -5558,7 +5554,8 @@ class Forward(ParseElementEnhance):
             not in self.suppress_warnings_
         ):
             warnings.warn(
-                "using '<<' operator with '|' is probably an error, use '<<='",
+                "warn_on_match_first_with_lshift_operator:"
+                " using '<<' operator with '|' is probably an error, use '<<='",
                 stacklevel=2,
             )
         ret = super().__or__(other)
@@ -5572,7 +5569,8 @@ class Forward(ParseElementEnhance):
             and Diagnostics.warn_on_assignment_to_Forward not in self.suppress_warnings_
         ):
             warnings.warn_explicit(
-                "Forward defined here but no expression attached later using '<<=' or '<<'",
+                "warn_on_assignment_to_Forward:"
+                " Forward defined here but no expression attached later using '<<=' or '<<'",
                 UserWarning,
                 filename=self.caller_frame.filename,
                 lineno=self.caller_frame.lineno,
@@ -5600,7 +5598,8 @@ class Forward(ParseElementEnhance):
             else:
                 stacklevel = 2
             warnings.warn(
-                "Forward expression was never assigned a value, will not parse any input",
+                "warn_on_parse_using_empty_Forward:"
+                " Forward expression was never assigned a value, will not parse any input",
                 stacklevel=stacklevel,
             )
         if not ParserElement._left_recursion_enabled:
@@ -6157,7 +6156,7 @@ def autoname_elements() -> None:
     Utility to simplify mass-naming of parser elements, for
     generating railroad diagram with named subdiagrams.
     """
-    calling_frame = sys._getframe().f_back
+    calling_frame = sys._getframe(1)
     if calling_frame is None:
         return
     calling_frame = typing.cast(types.FrameType, calling_frame)

+ 74 - 22
contrib/python/pyparsing/py3/pyparsing/diagram/__init__.py

@@ -1,6 +1,7 @@
 # mypy: ignore-errors
 from __future__ import annotations
 
+import itertools
 import railroad
 import pyparsing
 import dataclasses
@@ -40,7 +41,7 @@ jinja2_template_source = """\
 {{ body | safe }}
 {% for diagram in diagrams %}
     <div class="railroad-group">
-        <h1 class="railroad-heading">{{ diagram.title }}</h1>
+        <h1 class="railroad-heading" id="{{ diagram.bookmark }}">{{ diagram.title }}</h1>
         <div class="railroad-description">{{ diagram.text }}</div>
         <div class="railroad-svg">
             {{ diagram.svg }}
@@ -56,8 +57,35 @@ jinja2_template_source = """\
 template = Template(jinja2_template_source)
 
 
+_bookmark_lookup = {}
+_bookmark_ids = itertools.count(start=1)
+
+def _make_bookmark(s: str) -> str:
+    """
+    Converts a string into a valid HTML bookmark (ID or anchor name).
+    """
+    if s in _bookmark_lookup:
+        return _bookmark_lookup[s]
+
+    # Replace invalid characters with hyphens and ensure only valid characters
+    bookmark = re.sub(r'[^a-zA-Z0-9-]+', '-', s)
+
+    # Ensure it starts with a letter by adding 'z' if necessary
+    if not bookmark[:1].isalpha():
+        bookmark = f"z{bookmark}"
+
+    # Convert to lowercase and strip hyphens
+    bookmark = bookmark.lower().strip('-')
+
+    _bookmark_lookup[s] = bookmark = f"{bookmark}-{next(_bookmark_ids):04d}"
+
+    return bookmark
+
+
 def _collapse_verbose_regex(regex_str: str) -> str:
-    collapsed = pyparsing.Regex(r"#.*").suppress().transform_string(regex_str)
+    if "\n" not in regex_str:
+        return regex_str
+    collapsed = pyparsing.Regex(r"#.*$").suppress().transform_string(regex_str)
     collapsed = re.sub(r"\s*\n\s*", "", collapsed)
     return collapsed
 
@@ -72,6 +100,11 @@ class NamedDiagram:
     index: int
     diagram: railroad.DiagramItem = None
 
+    @property
+    def bookmark(self):
+        bookmark = _make_bookmark(self.name)
+        return bookmark
+
 
 T = TypeVar("T")
 
@@ -99,7 +132,7 @@ class AnnotatedItem(railroad.Group):
     """
 
     def __init__(self, label: str, item):
-        super().__init__(item=item, label=f"[{label}]")
+        super().__init__(item=item, label=f"[{label}]" if label else "")
 
 
 class EditablePartial(Generic[T]):
@@ -162,7 +195,11 @@ def railroad_to_html(diagrams: list[NamedDiagram], embed=False, **kwargs) -> str
         title = diagram.name
         if diagram.index == 0:
             title += " (root)"
-        data.append({"title": title, "text": "", "svg": io.getvalue()})
+        data.append(
+            {
+                "title": title, "text": "", "svg": io.getvalue(), "bookmark": diagram.bookmark
+            }
+        )
 
     return template.render(diagrams=data, embed=embed, **kwargs)
 
@@ -336,6 +373,12 @@ class ConverterState:
     def __contains__(self, key: int):
         return key in self._element_diagram_states
 
+    def get(self, key, default=None):
+        try:
+            return self[key]
+        except KeyError:
+            return default
+
     def generate_unnamed(self) -> int:
         """
         Generate a number used in the name of an otherwise unnamed diagram
@@ -360,7 +403,8 @@ class ConverterState:
 
         # Replace the original definition of this element with a regular block
         if position.parent:
-            ret = EditablePartial.from_call(railroad.NonTerminal, text=position.name)
+            href = f"#{_make_bookmark(position.name)}"
+            ret = EditablePartial.from_call(railroad.NonTerminal, text=position.name, href=href)
             if "item" in position.parent.kwargs:
                 position.parent.kwargs["item"] = ret
             elif "items" in position.parent.kwargs:
@@ -447,7 +491,7 @@ def _visible_exprs(exprs: Iterable[pyparsing.ParserElement]):
     return [
         e
         for e in exprs
-        if not (e.customName or e.resultsName or isinstance(e, non_diagramming_exprs))
+        if not isinstance(e, non_diagramming_exprs)
     ]
 
 
@@ -461,6 +505,7 @@ def _to_diagram_element(
     name_hint: str = None,
     show_results_names: bool = False,
     show_groups: bool = False,
+    show_hidden: bool = False,
 ) -> typing.Optional[EditablePartial]:
     """
     Recursively converts a PyParsing Element to a railroad Element
@@ -472,8 +517,9 @@ def _to_diagram_element(
     do so
     :param name_hint: If provided, this will override the generated name
     :param show_results_names: bool flag indicating whether to add annotations for results names
-    :returns: The converted version of the input element, but as a Partial that hasn't yet been constructed
     :param show_groups: bool flag indicating whether to show groups using bounding box
+    :param show_hidden: bool flag indicating whether to show elements that are typically hidden
+    :returns: The converted version of the input element, but as a Partial that hasn't yet been constructed
     """
     exprs = element.recurse()
     name = name_hint or element.customName or type(element).__name__
@@ -489,7 +535,7 @@ def _to_diagram_element(
             element,
             (
                 # pyparsing.TokenConverter,
-                # pyparsing.Forward,
+                pyparsing.Forward,
                 pyparsing.Located,
             ),
         ):
@@ -513,25 +559,33 @@ def _to_diagram_element(
 
     # If the element isn't worth extracting, we always treat it as the first time we say it
     if _worth_extracting(element):
-        if el_id in lookup and lookup[el_id].name is not None:
+        looked_up = lookup.get(el_id)
+        if looked_up and looked_up.name is not None:
             # If we've seen this element exactly once before, we are only just now finding out that it's a duplicate,
             # so we have to extract it into a new diagram.
-            looked_up = lookup[el_id]
             looked_up.mark_for_extraction(el_id, lookup, name=name_hint)
-            ret = EditablePartial.from_call(railroad.NonTerminal, text=looked_up.name)
+            href = f"#{_make_bookmark(looked_up.name)}"
+            ret = EditablePartial.from_call(railroad.NonTerminal, text=looked_up.name, href=href)
             return ret
 
         elif el_id in lookup.diagrams:
             # If we have seen the element at least twice before, and have already extracted it into a subdiagram, we
             # just put in a marker element that refers to the sub-diagram
+            text = lookup.diagrams[el_id].kwargs["name"]
             ret = EditablePartial.from_call(
-                railroad.NonTerminal, text=lookup.diagrams[el_id].kwargs["name"]
+                railroad.NonTerminal, text=text, href=f"#{_make_bookmark(text)}"
             )
             return ret
 
     # Recursively convert child elements
     # Here we find the most relevant Railroad element for matching pyparsing Element
     # We use ``items=[]`` here to hold the place for where the child elements will go once created
+
+    # see if this element is normally hidden, and whether hidden elements are desired
+    # if not, just return None
+    if not element.show_in_diagram and not show_hidden:
+        return None
+
     if isinstance(element, pyparsing.And):
         # detect And's created with ``expr*N`` notation - for these use a OneOrMore with a repeat
         # (all will have the same name, and resultsName)
@@ -566,7 +620,9 @@ def _to_diagram_element(
         if show_groups:
             ret = EditablePartial.from_call(AnnotatedItem, label="", item="")
         else:
-            ret = EditablePartial.from_call(railroad.Sequence, items=[])
+            ret = EditablePartial.from_call(
+                railroad.Group, item=None, label=element_results_name
+            )
     elif isinstance(element, pyparsing.TokenConverter):
         label = type(element).__name__.lower()
         if label == "tokenconverter":
@@ -607,10 +663,6 @@ def _to_diagram_element(
                 *args,
             )
         ret = EditablePartial.from_call(railroad.ZeroOrMore, item="")
-    elif isinstance(element, pyparsing.Group):
-        ret = EditablePartial.from_call(
-            railroad.Group, item=None, label=element_results_name
-        )
     elif isinstance(element, pyparsing.Empty) and not element.customName:
         # Skip unnamed "Empty" elements
         ret = None
@@ -619,10 +671,8 @@ def _to_diagram_element(
     elif len(exprs) > 0 and not element_results_name:
         ret = EditablePartial.from_call(railroad.Group, item="", label=name)
     elif isinstance(element, pyparsing.Regex):
-        patt = _collapse_verbose_regex(element.pattern)
-        element.pattern = patt
-        element._defaultName = None
-        ret = EditablePartial.from_call(railroad.Terminal, element.defaultName)
+        collapsed_patt = _collapse_verbose_regex(element.pattern)
+        ret = EditablePartial.from_call(railroad.Terminal, collapsed_patt)
     elif len(exprs) > 0:
         ret = EditablePartial.from_call(railroad.Sequence, items=[])
     else:
@@ -685,8 +735,10 @@ def _to_diagram_element(
     if el_id in lookup and lookup[el_id].extract and lookup[el_id].complete:
         lookup.extract_into_diagram(el_id)
         if ret is not None:
+            text = lookup.diagrams[el_id].kwargs["name"]
+            href = f"#{_make_bookmark(text)}"
             ret = EditablePartial.from_call(
-                railroad.NonTerminal, text=lookup.diagrams[el_id].kwargs["name"]
+                railroad.NonTerminal, text=text, href=href
             )
 
     return ret

+ 47 - 31
contrib/python/pyparsing/py3/pyparsing/helpers.py

@@ -199,7 +199,8 @@ def one_of(
         and __diag__.warn_on_multiple_string_args_to_oneof
     ):
         warnings.warn(
-            "More than one string argument passed to one_of, pass"
+            "warn_on_multiple_string_args_to_oneof:"
+            " More than one string argument passed to one_of, pass"
             " choices as a list or space-delimited string",
             stacklevel=2,
         )
@@ -779,25 +780,27 @@ def infix_notation(
     _FB.__name__ = "FollowedBy>"
 
     ret = Forward()
+    ret.set_name(f"{base_expr.name}_expression")
     if isinstance(lpar, str):
         lpar = Suppress(lpar)
     if isinstance(rpar, str):
         rpar = Suppress(rpar)
 
+    nested_expr = (lpar + ret + rpar).set_name(f"nested_{base_expr.name}")
+
     # if lpar and rpar are not suppressed, wrap in group
     if not (isinstance(lpar, Suppress) and isinstance(rpar, Suppress)):
-        lastExpr = base_expr | Group(lpar + ret + rpar).set_name(
-            f"nested_{base_expr.name}"
-        )
+        lastExpr = base_expr | Group(nested_expr)
     else:
-        lastExpr = base_expr | (lpar + ret + rpar).set_name(f"nested_{base_expr.name}")
-    root_expr = lastExpr
+        lastExpr = base_expr | nested_expr
 
     arity: int
     rightLeftAssoc: opAssoc
     pa: typing.Optional[ParseAction]
     opExpr1: ParserElement
     opExpr2: ParserElement
+    matchExpr: ParserElement
+    match_lookahead: ParserElement
     for operDef in op_list:
         opExpr, arity, rightLeftAssoc, pa = (operDef + (None,))[:4]  # type: ignore[assignment]
         if isinstance(opExpr, str_type):
@@ -809,9 +812,9 @@ def infix_notation(
                     "if numterms=3, opExpr must be a tuple or list of two expressions"
                 )
             opExpr1, opExpr2 = opExpr
-            term_name = f"{opExpr1}{opExpr2} term"
+            term_name = f"{opExpr1}{opExpr2} operations"
         else:
-            term_name = f"{opExpr} term"
+            term_name = f"{opExpr} operations"
 
         if not 1 <= arity <= 3:
             raise ValueError("operator must be unary (1), binary (2), or ternary (3)")
@@ -821,48 +824,62 @@ def infix_notation(
 
         thisExpr: ParserElement = Forward().set_name(term_name)
         thisExpr = typing.cast(Forward, thisExpr)
+        match_lookahead = And([])
         if rightLeftAssoc is OpAssoc.LEFT:
             if arity == 1:
-                matchExpr = _FB(lastExpr + opExpr) + Group(lastExpr + opExpr[1, ...])
+                match_lookahead = _FB(lastExpr + opExpr)
+                matchExpr = Group(lastExpr + opExpr[1, ...])
             elif arity == 2:
                 if opExpr is not None:
-                    matchExpr = _FB(lastExpr + opExpr + lastExpr) + Group(
-                        lastExpr + (opExpr + lastExpr)[1, ...]
-                    )
+                    match_lookahead = _FB(lastExpr + opExpr + lastExpr)
+                    matchExpr = Group(lastExpr + (opExpr + lastExpr)[1, ...])
                 else:
-                    matchExpr = _FB(lastExpr + lastExpr) + Group(lastExpr[2, ...])
+                    match_lookahead = _FB(lastExpr + lastExpr)
+                    matchExpr = Group(lastExpr[2, ...])
             elif arity == 3:
-                matchExpr = _FB(
+                match_lookahead = _FB(
                     lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr
-                ) + Group(lastExpr + OneOrMore(opExpr1 + lastExpr + opExpr2 + lastExpr))
+                )
+                matchExpr = Group(
+                    lastExpr + (opExpr1 + lastExpr + opExpr2 + lastExpr)[1, ...]
+                )
         elif rightLeftAssoc is OpAssoc.RIGHT:
             if arity == 1:
                 # try to avoid LR with this extra test
                 if not isinstance(opExpr, Opt):
                     opExpr = Opt(opExpr)
-                matchExpr = _FB(opExpr.expr + thisExpr) + Group(opExpr + thisExpr)
+                match_lookahead = _FB(opExpr.expr + thisExpr)
+                matchExpr = Group(opExpr + thisExpr)
             elif arity == 2:
                 if opExpr is not None:
-                    matchExpr = _FB(lastExpr + opExpr + thisExpr) + Group(
-                        lastExpr + (opExpr + thisExpr)[1, ...]
-                    )
+                    match_lookahead = _FB(lastExpr + opExpr + thisExpr)
+                    matchExpr = Group(lastExpr + (opExpr + thisExpr)[1, ...])
                 else:
-                    matchExpr = _FB(lastExpr + thisExpr) + Group(
-                        lastExpr + thisExpr[1, ...]
-                    )
+                    match_lookahead = _FB(lastExpr + thisExpr)
+                    matchExpr = Group(lastExpr + thisExpr[1, ...])
             elif arity == 3:
-                matchExpr = _FB(
+                match_lookahead = _FB(
                     lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr
-                ) + Group(lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr)
+                )
+                matchExpr = Group(lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr)
+
+        # suppress lookahead expr from railroad diagrams
+        match_lookahead.show_in_diagram = False
+
+        # TODO - determine why this statement can't be included in the following
+        #  if pa block
+        matchExpr = match_lookahead + matchExpr
+
         if pa:
             if isinstance(pa, (tuple, list)):
                 matchExpr.set_parse_action(*pa)
             else:
                 matchExpr.set_parse_action(pa)
+
         thisExpr <<= (matchExpr | lastExpr).setName(term_name)
         lastExpr = thisExpr
+
     ret <<= lastExpr
-    root_expr.set_name("base_expr")
     return ret
 
 
@@ -1009,10 +1026,9 @@ def indentedBlock(blockStatementExpr, indentStack, indent=True, backup_stacks=[]
     return smExpr.set_name("indented block")
 
 
-# it's easy to get these comment structures wrong - they're very common, so may as well make them available
-c_style_comment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + "*/").set_name(
-    "C style comment"
-)
+# it's easy to get these comment structures wrong - they're very common,
+# so may as well make them available
+c_style_comment = Regex(r"/\*(?:[^*]|\*(?!/))*\*\/").set_name("C style comment")
 "Comment of the form ``/* ... */``"
 
 html_comment = Regex(r"<!--[\s\S]*?-->").set_name("HTML comment")
@@ -1022,8 +1038,8 @@ rest_of_line = Regex(r".*").leave_whitespace().set_name("rest of line")
 dbl_slash_comment = Regex(r"//(?:\\\n|[^\n])*").set_name("// comment")
 "Comment of the form ``// ... (to end of line)``"
 
-cpp_style_comment = Combine(
-    Regex(r"/\*(?:[^*]|\*(?!/))*") + "*/" | dbl_slash_comment
+cpp_style_comment = Regex(
+    r"(?:/\*(?:[^*]|\*(?!/))*\*\/)|(?://(?:\\\n|[^\n])*)"
 ).set_name("C++ style comment")
 "Comment of either form :class:`c_style_comment` or :class:`dbl_slash_comment`"
 

+ 1 - 0
contrib/python/pyparsing/py3/pyparsing/results.py

@@ -523,6 +523,7 @@ class ParseResults:
             result_list = result.as_list()
             print(type(result_list), result_list) # -> <class 'list'> ['sldkj', 'lsdkj', 'sldkj']
         """
+
         def flattened(pr):
             to_visit = collections.deque([*self])
             while to_visit:

+ 1 - 0
contrib/python/pyparsing/py3/pyparsing/util.py

@@ -192,6 +192,7 @@ class _GroupConsecutive:
             (2, iter(['m']))
             (3, iter(['p', 'q', 'r', 's']))
     """
+
     def __init__(self):
         self.prev = 0
         self.counter = itertools.count()

+ 1 - 1
contrib/python/pyparsing/py3/ya.make

@@ -4,7 +4,7 @@ PY3_LIBRARY()
 
 PROVIDES(pyparsing)
 
-VERSION(3.2.0)
+VERSION(3.2.1)
 
 LICENSE(MIT)