aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/pyparsing/py3/pyparsing
diff options
context:
space:
mode:
authorrobot-piglet <robot-piglet@yandex-team.com>2025-01-16 00:00:43 +0300
committerrobot-piglet <robot-piglet@yandex-team.com>2025-01-16 00:11:40 +0300
commit0395c5087038d4d95d8f64c67e458add6ac040fd (patch)
treead95f078e6e32c8eefaf237b14c5b1a8e0ff25a4 /contrib/python/pyparsing/py3/pyparsing
parentca6fbaf1e911f8348d218b2d7f8448447d641e3e (diff)
downloadydb-0395c5087038d4d95d8f64c67e458add6ac040fd.tar.gz
Intermediate changes
commit_hash:16645c680befa673cec2481eceae5781024fdb0e
Diffstat (limited to 'contrib/python/pyparsing/py3/pyparsing')
-rw-r--r--contrib/python/pyparsing/py3/pyparsing/__init__.py4
-rw-r--r--contrib/python/pyparsing/py3/pyparsing/actions.py41
-rw-r--r--contrib/python/pyparsing/py3/pyparsing/common.py4
-rw-r--r--contrib/python/pyparsing/py3/pyparsing/core.py19
-rw-r--r--contrib/python/pyparsing/py3/pyparsing/diagram/__init__.py96
-rw-r--r--contrib/python/pyparsing/py3/pyparsing/helpers.py78
-rw-r--r--contrib/python/pyparsing/py3/pyparsing/results.py1
-rw-r--r--contrib/python/pyparsing/py3/pyparsing/util.py1
8 files changed, 163 insertions, 81 deletions
diff --git a/contrib/python/pyparsing/py3/pyparsing/__init__.py b/contrib/python/pyparsing/py3/pyparsing/__init__.py
index 543ceb62bd..726c76cb24 100644
--- a/contrib/python/pyparsing/py3/pyparsing/__init__.py
+++ b/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>"
diff --git a/contrib/python/pyparsing/py3/pyparsing/actions.py b/contrib/python/pyparsing/py3/pyparsing/actions.py
index 1d2dce99e1..f491aab986 100644
--- a/contrib/python/pyparsing/py3/pyparsing/actions.py
+++ b/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
diff --git a/contrib/python/pyparsing/py3/pyparsing/common.py b/contrib/python/pyparsing/py3/pyparsing/common.py
index 649aad0096..e46511086d 100644
--- a/contrib/python/pyparsing/py3/pyparsing/common.py
+++ b/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)
)
diff --git a/contrib/python/pyparsing/py3/pyparsing/core.py b/contrib/python/pyparsing/py3/pyparsing/core.py
index 4f43c3bf99..b884e2d4a4 100644
--- a/contrib/python/pyparsing/py3/pyparsing/core.py
+++ b/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)
diff --git a/contrib/python/pyparsing/py3/pyparsing/diagram/__init__.py b/contrib/python/pyparsing/py3/pyparsing/diagram/__init__.py
index 7926f2c355..56526b741b 100644
--- a/contrib/python/pyparsing/py3/pyparsing/diagram/__init__.py
+++ b/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
diff --git a/contrib/python/pyparsing/py3/pyparsing/helpers.py b/contrib/python/pyparsing/py3/pyparsing/helpers.py
index d2bd05f3d3..f781e87132 100644
--- a/contrib/python/pyparsing/py3/pyparsing/helpers.py
+++ b/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`"
diff --git a/contrib/python/pyparsing/py3/pyparsing/results.py b/contrib/python/pyparsing/py3/pyparsing/results.py
index 245847832a..be834b7e60 100644
--- a/contrib/python/pyparsing/py3/pyparsing/results.py
+++ b/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:
diff --git a/contrib/python/pyparsing/py3/pyparsing/util.py b/contrib/python/pyparsing/py3/pyparsing/util.py
index 1487019c27..03a60d4fdd 100644
--- a/contrib/python/pyparsing/py3/pyparsing/util.py
+++ b/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()