5from collections
import deque
21from abc
import ABC, abstractmethod
31from operator
import itemgetter
32from functools
import wraps
33from threading
import RLock
34from pathlib
import Path
40 _collapse_string_to_ranges,
41 _escape_regex_range_chars,
45 UnboundedMemo
as _UnboundedMemo,
48from .exceptions
import *
50from .results
import ParseResults, _ParseResultsWithOffset
51from .unicode
import pyparsing_unicode
54str_type: Tuple[type, ...] = (str, bytes)
81 from functools
import cached_property
93class __compat__(__config_flags):
95 A cross-version compatibility configuration for pyparsing features that will be
96 released in a future version. By setting values in this configuration to True,
97 those features can be enabled in prior versions for compatibility development
100 - ``collect_all_And_tokens`` - flag to enable fix for Issue #63 that fixes erroneous grouping
101 of results names when an :class:`And` expression is nested within an :class:`Or` or :class:`MatchFirst`;
102 maintained for compatibility, but setting to ``False`` no longer restores pre-2.3.1
106 _type_desc =
"compatibility"
108 collect_all_And_tokens =
True
110 _all_names = [__
for __
in locals()
if not __.startswith(
"_")]
112 collect_all_And_tokens
116class __diag__(__config_flags):
117 _type_desc =
"diagnostic"
119 warn_multiple_tokens_in_named_alternation =
False
120 warn_ungrouped_named_tokens_in_collection =
False
121 warn_name_set_on_empty_Forward =
False
122 warn_on_parse_using_empty_Forward =
False
123 warn_on_assignment_to_Forward =
False
124 warn_on_multiple_string_args_to_oneof =
False
125 warn_on_match_first_with_lshift_operator =
False
126 enable_debug_on_named_expressions =
False
128 _all_names = [__
for __
in locals()
if not __.startswith(
"_")]
129 _warning_names = [name
for name
in _all_names
if name.startswith(
"warn")]
130 _debug_names = [name
for name
in _all_names
if name.startswith(
"enable_debug")]
134 for name
in cls._warning_names:
140 Diagnostic configuration (all default to disabled)
142 - ``warn_multiple_tokens_in_named_alternation`` - flag to enable warnings when a results
143 name is defined on a :class:`MatchFirst` or :class:`Or` expression with one or more :class:`And` subexpressions
144 - ``warn_ungrouped_named_tokens_in_collection`` - flag to enable warnings when a results
145 name is defined on a containing expression with ungrouped subexpressions that also
147 - ``warn_name_set_on_empty_Forward`` - flag to enable warnings when a :class:`Forward` is defined
148 with a results name, but has no contents defined
149 - ``warn_on_parse_using_empty_Forward`` - flag to enable warnings when a :class:`Forward` is
150 defined in a grammar but has never had an expression attached to it
151 - ``warn_on_assignment_to_Forward`` - flag to enable warnings when a :class:`Forward` is defined
152 but is overwritten by assigning using ``'='`` instead of ``'<<='`` or ``'<<'``
153 - ``warn_on_multiple_string_args_to_oneof`` - flag to enable warnings when :class:`one_of` is
154 incorrectly called with multiple str arguments
155 - ``enable_debug_on_named_expressions`` - flag to auto-enable debug on all subsequent
156 calls to :class:`ParserElement.set_name`
158 Diagnostics are enabled/disabled by calling :class:`enable_diag` and :class:`disable_diag`.
159 All warnings can be enabled by calling :class:`enable_all_warnings`.
162 warn_multiple_tokens_in_named_alternation = 0
163 warn_ungrouped_named_tokens_in_collection = 1
164 warn_name_set_on_empty_Forward = 2
165 warn_on_parse_using_empty_Forward = 3
166 warn_on_assignment_to_Forward = 4
167 warn_on_multiple_string_args_to_oneof = 5
168 warn_on_match_first_with_lshift_operator = 6
169 enable_debug_on_named_expressions = 7
174 Enable a global pyparsing diagnostic flag (see :class:`Diagnostics`).
181 Disable a global pyparsing diagnostic flag (see :class:`Diagnostics`).
188 Enable all global pyparsing diagnostic warnings (see :class:`Diagnostics`).
198 cmd_line_warn_options: typing.Iterable[str], warn_env_var:
typing.Optional[str]
200 enable = bool(warn_env_var)
201 for warn_opt
in cmd_line_warn_options:
202 w_action, w_message, w_category, w_module, w_line = (warn_opt +
"::::").split(
206 not (w_message
or w_category
or w_module)
or w_module ==
"pyparsing"
221_single_arg_builtins = {
236ParseImplReturnType = Tuple[int, Any]
237PostParseReturnType = Union[ParseResults, Sequence[ParseResults]]
240 Callable[[ParseResults], Any],
241 Callable[[int, ParseResults], Any],
242 Callable[[str, int, ParseResults], Any],
244ParseCondition = Union[
246 Callable[[ParseResults], bool],
247 Callable[[int, ParseResults], bool],
248 Callable[[str, int, ParseResults], bool],
250ParseFailAction = Callable[[str, int,
"ParserElement", Exception],
None]
251DebugStartAction = Callable[[str, int,
"ParserElement", bool],
None]
252DebugSuccessAction = Callable[
253 [str, int, int,
"ParserElement", ParseResults, bool],
None
255DebugExceptionAction = Callable[[str, int,
"ParserElement", Exception, bool],
None]
262hexnums = nums +
"ABCDEFabcdef"
263alphanums = alphas + nums
270 """decorator to trim function calls to match the arity of the target"""
271 global _trim_arity_call_line
273 if func
in _single_arg_builtins:
274 return lambda s, l, t: func(t)
287 pa_call_line_synth = (_trim_arity_call_line[0], _trim_arity_call_line[1] + LINE_DIFF)
290 nonlocal found_arity, limit
293 ret = func(*args[limit:])
296 except TypeError
as te:
303 frame_summary = frames[-1]
304 trim_arity_type_error = (
305 [frame_summary[:2]][-1][:2] == pa_call_line_synth
309 if trim_arity_type_error:
310 if limit < max_limit:
319 func_name =
getattr(func,
"__name__",
getattr(func,
"__class__").__name__)
327 fn: ParseCondition, message:
typing.Optional[str] =
None, fatal: bool =
False
330 Function to convert a simple predicate function that returns ``True`` or ``False``
331 into a parse action. Can be used in places when a parse action is required
332 and :class:`ParserElement.add_condition` cannot be used (such as when adding a condition
333 to an operator level in :class:`infix_notation`).
335 Optional keyword arguments:
337 - ``message`` - define a custom message to be used in the raised exception
338 - ``fatal`` - if True, will raise :class:`ParseFatalException` to stop parsing immediately;
339 otherwise will raise :class:`ParseException`
342 msg = message
if message
is not None else "failed user-defined condition"
343 exc_type = ParseFatalException
if fatal
else ParseException
348 if not bool(fn(s, l, t)):
349 raise exc_type(s, l, msg)
355 instring: str, loc: int, expr:
"ParserElement", cache_hit: bool =
False
357 cache_hit_str =
"*" if cache_hit
else ""
360 f
"{cache_hit_str}Match {expr} at loc {loc}({lineno(loc, instring)},{col(loc, instring)})\n"
361 f
" {line(loc, instring)}\n"
362 f
" {' ' * (col(loc, instring) - 1)}^"
371 expr:
"ParserElement",
373 cache_hit: bool =
False,
375 cache_hit_str =
"*" if cache_hit
else ""
376 print(f
"{cache_hit_str}Matched {expr} -> {toks.as_list()}")
382 expr:
"ParserElement",
384 cache_hit: bool =
False,
386 cache_hit_str =
"*" if cache_hit
else ""
387 print(f
"{cache_hit_str}Match {expr} failed, {type(exc).__name__} raised: {exc}")
391 """'Do-nothing' debug action, to suppress debugging output during parsing."""
394class ParserElement(ABC):
395 """Abstract base level parser element class."""
397 DEFAULT_WHITE_CHARS: str =
" \n\t\r"
398 verbose_stacktrace: bool =
False
399 _literalStringClass: type =
None
404 Overrides the default whitespace chars
408 # default whitespace chars are space, <TAB> and newline
409 Word(alphas)[1, ...].parse_string("abc def\nghi jkl") # -> ['abc', 'def', 'ghi', 'jkl']
411 # change to just treat newline as significant
412 ParserElement.set_default_whitespace_chars(" \t")
413 Word(alphas)[1, ...].parse_string("abc def\nghi jkl") # -> ['abc', 'def']
418 for expr
in _builtin_exprs:
425 Set class to be used for inclusion of string literals into a parser.
429 # default literal class used is Literal
431 date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
433 date_str.parse_string("1999/12/31") # -> ['1999', '/', '12', '/', '31']
437 ParserElement.inline_literals_using(Suppress)
438 date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
440 date_str.parse_string("1999/12/31") # -> ['1999', '12', '31']
447 Yields a sequence of class(obj, **class_kwargs) for obj in seq.
451 LPAR, RPAR, LBRACE, RBRACE, SEMI = Suppress.using_each("(){};")
454 yield from (
cls(obj, **class_kwargs)
for obj
in seq)
474 self.ignoreExprs: List[
"ParserElement"] = list()
487 self.suppress_warnings_: List[Diagnostics] = []
491 Suppress warnings emitted for a particular diagnostic on this expression.
496 base.suppress_warning(Diagnostics.warn_on_parse_using_empty_Forward)
498 # statement would normally raise a warning, but is now suppressed
499 print(base.parse_string("x"))
502 self.suppress_warnings_.append(warning_type)
506 """General-purpose method to yield all expressions and sub-expressions
507 in a grammar. Typically just for internal use.
509 to_visit = deque([self])
522 def copy(self) -> "ParserElement":
524 Make a copy of this :class:`ParserElement`. Useful for defining
525 different parse actions for the same parsing pattern, using copies of
526 the original parse element.
530 integer = Word(nums).set_parse_action(lambda toks: int(toks[0]))
531 integerK = integer.copy().add_parse_action(lambda toks: toks[0] * 1024) + Suppress("K")
532 integerM = integer.copy().add_parse_action(lambda toks: toks[0] * 1024 * 1024) + Suppress("M")
534 print((integerK | integerM | integer)[1, ...].parse_string("5K 100 640K 256M"))
538 [5120, 100, 655360, 268435456]
540 Equivalent form of ``expr.copy()`` is just ``expr()``::
542 integerM = integer().add_parse_action(lambda toks: toks[0] * 1024 * 1024) + Suppress("M")
552 self, name: str, list_all_matches: bool =
False, *, listAllMatches: bool =
False
553 ) ->
"ParserElement":
555 Define name for referencing matching tokens as a nested attribute
556 of the returned parse results.
558 Normally, results names are assigned as you would assign keys in a dict:
559 any existing value is overwritten by later values. If it is necessary to
560 keep all values captured for a particular results name, call ``set_results_name``
561 with ``list_all_matches`` = True.
563 NOTE: ``set_results_name`` returns a *copy* of the original :class:`ParserElement` object;
564 this is so that the client can define a basic element, such as an
565 integer, and reference it in multiple places with different names.
567 You can also set results names using the abbreviated syntax,
568 ``expr("name")`` in place of ``expr.set_results_name("name")``
569 - see :class:`__call__`. If ``list_all_matches`` is required, use
574 date_str = (integer.set_results_name("year") + '/'
575 + integer.set_results_name("month") + '/'
576 + integer.set_results_name("day"))
579 date_str = integer("year") + '/' + integer("month") + '/' + integer("day")
581 listAllMatches = listAllMatches
or list_all_matches
587 newself = self.
copy()
590 listAllMatches =
True
595 def set_break(self, break_flag: bool =
True) ->
"ParserElement":
597 Method to invoke the Python pdb debugger when this element is
598 about to be parsed. Set ``break_flag`` to ``True`` to enable, ``False`` to
604 def breaker(instring, loc, doActions=True, callPreParse=True):
609 return _parseMethod(instring, loc, doActions, callPreParse)
620 Define one or more actions to perform when successfully matching parse element definition.
622 Parse actions can be called to perform data conversions, do extra validation,
623 update external data structures, or enhance or replace the parsed tokens.
624 Each parse action ``fn`` is a callable method with 0-3 arguments, called as
625 ``fn(s, loc, toks)`` , ``fn(loc, toks)`` , ``fn(toks)`` , or just ``fn()`` , where:
627 - ``s`` = the original string being parsed (see note below)
628 - ``loc`` = the location of the matching substring
629 - ``toks`` = a list of the matched tokens, packaged as a :class:`ParseResults` object
631 The parsed tokens are passed to the parse action as ParseResults. They can be
632 modified in place using list-style append, extend, and pop operations to update
633 the parsed list elements; and with dictionary-style item set and del operations
634 to add, update, or remove any named results. If the tokens are modified in place,
635 it is not necessary to return them with a return statement.
637 Parse actions can also completely replace the given tokens, with another ``ParseResults``
638 object, or with some entirely different object (common for parse actions that perform data
639 conversions). A convenient way to build a new parse result is to define the values
640 using a dict, and then create the return value using :class:`ParseResults.from_dict`.
642 If None is passed as the ``fn`` parse action, all previously added parse actions for this
643 expression are cleared.
645 Optional keyword arguments:
647 - ``call_during_try`` = (default= ``False``) indicate if parse action should be run during
648 lookaheads and alternate testing. For parse actions that have side effects, it is
649 important to only call the parse action once it is determined that it is being
650 called as part of a successful parse. For parse actions that perform additional
651 validation, then call_during_try should be passed as True, so that the validation
652 code is included in the preliminary "try" parses.
654 Note: the default parsing behavior is to expand tabs in the input string
655 before starting the parsing process. See :class:`parse_string` for more
656 information on parsing strings containing ``<TAB>`` s, and suggested
657 methods to maintain a consistent view of the parsed string, the parse
658 location, and line and column positions within the parsed string.
662 # parse dates in the form YYYY/MM/DD
664 # use parse action to convert toks from str to int at parse time
665 def convert_to_int(toks):
668 # use a parse action to verify that the date is a valid date
669 def is_valid_date(instring, loc, toks):
670 from datetime import date
671 year, month, day = toks[::2]
673 date(year, month, day)
675 raise ParseException(instring, loc, "invalid date given")
678 date_str = integer + '/' + integer + '/' + integer
681 integer.set_parse_action(convert_to_int)
682 date_str.set_parse_action(is_valid_date)
684 # note that integer fields are now ints, not strings
685 date_str.run_tests('''
686 # successful parse - note that integer fields were converted to ints
689 # fail - invalid date
693 if list(fns) == [
None]:
696 if not all(callable(fn)
for fn
in fns):
697 raise TypeError(
"parse actions must be callable")
700 "call_during_try",
kwargs.get(
"callDuringTry",
False)
706 Add one or more parse actions to expression's list of parse actions. See :class:`set_parse_action`.
708 See examples in :class:`copy`.
712 "call_during_try",
kwargs.get(
"callDuringTry",
False)
717 """Add a boolean predicate function to expression's list of parse actions. See
718 :class:`set_parse_action` for function call signatures. Unlike ``set_parse_action``,
719 functions passed to ``add_condition`` need to return boolean success/fail of the condition.
721 Optional keyword arguments:
723 - ``message`` = define a custom message to be used in the raised exception
724 - ``fatal`` = if True, will raise ParseFatalException to stop parsing immediately; otherwise will raise
726 - ``call_during_try`` = boolean to indicate if this method should be called during internal tryParse calls,
731 integer = Word(nums).set_parse_action(lambda toks: int(toks[0]))
732 year_int = integer.copy()
733 year_int.add_condition(lambda toks: toks[0] >= 2000, message="Only support years 2000 and later")
734 date_str = year_int + '/' + integer + '/' + integer
736 result = date_str.parse_string("1999/12/31") # -> Exception: Only support years 2000 and later (at char 0),
749 "call_during_try",
kwargs.get(
"callDuringTry",
False)
755 Define action to perform if parsing fails at this expression.
756 Fail acton fn is a callable function that takes the arguments
757 ``fn(s, loc, expr, err)`` where:
759 - ``s`` = string being parsed
760 - ``loc`` = location where expression match was attempted and failed
761 - ``expr`` = the parse expression that failed
762 - ``err`` = the exception thrown
764 The function returns no value. It may throw :class:`ParseFatalException`
765 if it is desired to stop parsing immediately."""
770 if not self.ignoreExprs:
773 ignore_expr_fns = [
e._parse for e
in self.ignoreExprs]
776 for ignore_fn
in ignore_expr_fns:
781 except ParseException:
785 def preParse(self, instring: str, loc: int) -> int:
790 instrlen =
len(instring)
792 while loc < instrlen
and instring[loc]
in white_chars:
805 self, instring, loc, doActions=True, callPreParse=True
806 ) -> Tuple[int, ParseResults]:
807 TRY, MATCH, FAIL = 0, 1, 2
808 debugging = self.
debug
809 len_instring =
len(instring)
815 pre_loc = self.
preParse(instring, loc)
818 tokens_start = pre_loc
820 self.
debugActions.debug_try(instring, tokens_start, self,
False)
823 loc, tokens = self.
parseImpl(instring, pre_loc, doActions)
827 loc, tokens = self.
parseImpl(instring, pre_loc, doActions)
828 except Exception
as err:
832 instring, tokens_start, self, err,
False
835 self.
failAction(instring, tokens_start, self, err)
839 pre_loc = self.
preParse(instring, loc)
842 tokens_start = pre_loc
845 loc, tokens = self.
parseImpl(instring, pre_loc, doActions)
849 loc, tokens = self.
parseImpl(instring, pre_loc, doActions)
851 tokens = self.
postParse(instring, loc, tokens)
861 tokens = fn(instring, tokens_start, ret_tokens)
862 except IndexError
as parse_action_exc:
864 raise exc
from parse_action_exc
866 if tokens
is not None and tokens
is not ret_tokens:
874 except Exception
as err:
878 instring, tokens_start, self, err,
False
884 tokens = fn(instring, tokens_start, ret_tokens)
885 except IndexError
as parse_action_exc:
887 raise exc
from parse_action_exc
889 if tokens
is not None and tokens
is not ret_tokens:
901 instring, tokens_start, loc, self, ret_tokens,
False
904 return loc, ret_tokens
911 raise_fatal: bool =
False,
912 do_actions: bool =
False,
915 return self.
_parse_parse(instring, loc, doActions=do_actions)[0]
916 except ParseFatalException:
921 def can_parse_next(self, instring: str, loc: int, do_actions: bool =
False) -> bool:
923 self.
try_parse(instring, loc, do_actions=do_actions)
924 except (ParseException, IndexError):
930 recursion_lock = RLock()
932 Tuple[int,
"Forward", bool], Tuple[int, Union[ParseResults, Exception]]
937 class to help type checking
942 def get(self, *args):
952 packrat_cache_lock = RLock()
953 packrat_cache_stats = [0, 0]
958 self, instring, loc, doActions=True, callPreParse=True
959 ) -> Tuple[int, ParseResults]:
961 TRY, MATCH, FAIL = 0, 1, 2
962 lookup = (self, instring, loc, callPreParse, doActions)
969 value = self.
_parseNoCache(instring, loc, doActions, callPreParse)
970 except ParseBaseException
as pe:
975 cache.set(lookup, (value[0], value[1].copy(), loc))
981 self.
debugActions.debug_try(instring, loc, self, cache_hit=
True)
988 instring, loc, self, value, cache_hit=
True
994 value = cast(Tuple[int, ParseResults, int], value)
995 loc_, result, endloc = value[0], value[1].copy(), value[2]
999 instring, loc_, endloc, self, result, cache_hit=
True
1006 _parse = _parseNoCache
1016 _packratEnabled =
False
1017 _left_recursion_enabled =
False
1022 Disables active Packrat or Left Recursion parsing and their memoization
1024 This method also works if neither Packrat nor Left Recursion are enabled.
1025 This makes it safe to call before activating Packrat nor Left Recursion
1026 to clear any previous settings.
1035 cache_size_limit: typing.Optional[int] =
None, *, force=
False
1038 Enables "bounded recursion" parsing, which allows for both direct and indirect
1039 left-recursion. During parsing, left-recursive :class:`Forward` elements are
1040 repeatedly matched with a fixed recursion depth that is gradually increased
1041 until finding the longest match.
1045 from pip._vendor import pyparsing as pp
1046 pp.ParserElement.enable_left_recursion()
1049 num = pp.Word(pp.nums)
1050 # match `num`, or `num '+' num`, or `num '+' num '+' num`, ...
1051 E <<= E + '+' - num | num
1053 print(E.parse_string("1+2+3"))
1055 Recursion search naturally memoizes matches of ``Forward`` elements and may
1056 thus skip reevaluation of parse actions during backtracking. This may break
1057 programs with parse actions which rely on strict ordering of side-effects.
1061 - ``cache_size_limit`` - (default=``None``) - memoize at most this many
1062 ``Forward`` elements during matching; if ``None`` (the default),
1063 memoize all ``Forward`` elements.
1065 Bounded Recursion parsing works similar but not identical to Packrat parsing,
1066 thus the two cannot be used together. Use ``force=True`` to disable any
1067 previous, conflicting settings.
1072 raise RuntimeError(
"Packrat and Bounded Recursion are not compatible")
1073 if cache_size_limit
is None:
1075 elif cache_size_limit > 0:
1084 Enables "packrat" parsing, which adds memoizing to the parsing logic.
1085 Repeated parse attempts at the same string location (which happens
1086 often in many complex grammars) can immediately return a cached value,
1087 instead of re-executing parsing/validating code. Memoizing is done of
1088 both valid results and parsing exceptions.
1092 - ``cache_size_limit`` - (default= ``128``) - if an integer value is provided
1093 will limit the size of the packrat cache; if None is passed, then
1094 the cache size will be unbounded; if 0 is passed, the cache will
1095 be effectively disabled.
1097 This speedup may break existing programs that use parse actions that
1098 have side-effects. For this reason, packrat parsing is disabled when
1099 you first import pyparsing. To activate the packrat feature, your
1100 program must call the class method :class:`ParserElement.enable_packrat`.
1101 For best results, call ``enable_packrat()`` immediately after
1102 importing pyparsing.
1106 from pip._vendor import pyparsing
1107 pyparsing.ParserElement.enable_packrat()
1109 Packrat parsing works similar but not identical to Bounded Recursion parsing,
1110 thus the two cannot be used together. Use ``force=True`` to disable any
1111 previous, conflicting settings.
1116 raise RuntimeError(
"Packrat and Bounded Recursion are not compatible")
1119 if cache_size_limit
is None:
1126 self, instring: str, parse_all: bool =
False, *, parseAll: bool =
False
1129 Parse a string with respect to the parser definition. This function is intended as the primary interface to the
1132 :param instring: The input string to be parsed.
1133 :param parse_all: If set, the entire input string must match the grammar.
1134 :param parseAll: retained for pre-PEP8 compatibility, will be removed in a future release.
1135 :raises ParseException: Raised if ``parse_all`` is set and the input string does not match the whole grammar.
1136 :returns: the parsed data as a :class:`ParseResults` object, which may be accessed as a `list`, a `dict`, or
1137 an object with attributes if the given parser includes results names.
1139 If the input string is required to match the entire grammar, ``parse_all`` flag must be set to ``True``. This
1140 is also equivalent to ending the grammar with :class:`StringEnd`\\ ().
1142 To report proper column numbers, ``parse_string`` operates on a copy of the input string where all tabs are
1143 converted to spaces (8 spaces per tab, as per the default in ``string.expandtabs``). If the input string
1144 contains tabs and the grammar uses parse actions that use the ``loc`` argument to index into the string
1145 being parsed, one can ensure a consistent view of the input string by doing one of the following:
1147 - calling ``parse_with_tabs`` on your grammar before calling ``parse_string`` (see :class:`parse_with_tabs`),
1148 - define your parse action using the full ``(s,loc,toks)`` signature, and reference the input string using the
1149 parse action's ``s`` argument, or
1150 - explicitly expand the tabs in your input string before calling ``parse_string``.
1154 By default, partial matches are OK.
1156 >>> res = Word('a').parse_string('aaaaabaaa')
1160 The parsing behavior varies by the inheriting class of this abstract class. Please refer to the children
1161 directly to see more examples.
1163 It raises an exception if parse_all flag is set and instring does not match the whole grammar.
1165 >>> res = Word('a').parse_string('aaaaabaaa', parse_all=True)
1166 Traceback (most recent call last):
1168 pyparsing.ParseException: Expected end of text, found 'b' (at char 5), (line:1, col:6)
1170 parseAll = parse_all
or parseAll
1175 for e
in self.ignoreExprs:
1185 except ParseBaseException
as exc:
1197 max_matches: int = _MAX_INT,
1198 overlap: bool =
False,
1200 debug: bool =
False,
1201 maxMatches: int = _MAX_INT,
1202 ) -> Generator[Tuple[ParseResults, int, int],
None,
None]:
1204 Scan the input string for expression matches. Each match will return the
1205 matching tokens, start location, and end location. May be called with optional
1206 ``max_matches`` argument, to clip scanning after 'n' matches are found. If
1207 ``overlap`` is specified, then overlapping matches will be reported.
1209 Note that the start and end locations are reported relative to the string
1210 being parsed. See :class:`parse_string` for more information on parsing
1211 strings with embedded tabs.
1215 source = "sldjf123lsdjjkf345sldkjf879lkjsfd987"
1217 for tokens, start, end in Word(alphas).scan_string(source):
1218 print(' '*start + '^'*(end-start))
1219 print(' '*start + tokens[0])
1223 sldjf123lsdjjkf345sldkjf879lkjsfd987
1233 maxMatches = min(maxMatches, max_matches)
1236 for e
in self.ignoreExprs:
1241 instrlen =
len(instring)
1248 while loc <= instrlen
and matches < maxMatches:
1252 tokens: ParseResults
1253 nextLoc, tokens =
parseFn(instring, preloc, callPreParse=
False)
1254 except ParseException:
1267 yield tokens, preloc, nextLoc
1278 except ParseBaseException
as exc:
1287 Extension to :class:`scan_string`, to modify matching text with modified tokens that may
1288 be returned from a parse action. To use ``transform_string``, define a grammar and
1289 attach a parse action to it that modifies the returned token list.
1290 Invoking ``transform_string()`` on a target string will then scan for matches,
1291 and replace the matched text patterns according to the logic in the parse
1292 action. ``transform_string()`` returns the resulting transformed string.
1297 wd.set_parse_action(lambda toks: toks[0].title())
1299 print(wd.transform_string("now is the winter of our discontent made glorious summer by this sun of york."))
1303 Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York.
1311 for t, s, e
in self.
scan_string(instring, debug=debug):
1322 out = [o
for o
in out
if o]
1323 return "".join([str(s)
for s
in _flatten(out)])
1324 except ParseBaseException
as exc:
1334 max_matches: int = _MAX_INT,
1336 debug: bool =
False,
1337 maxMatches: int = _MAX_INT,
1340 Another extension to :class:`scan_string`, simplifying the access to the tokens found
1341 to match the given parse expression. May be called with optional
1342 ``max_matches`` argument, to clip searching after 'n' matches are found.
1346 # a capitalized word starts with an uppercase letter, followed by zero or more lowercase letters
1347 cap_word = Word(alphas.upper(), alphas.lower())
1349 print(cap_word.search_string("More than Iron, more than Lead, more than Gold I need Electricity"))
1351 # the sum() builtin can be used to merge results into a single ParseResults object
1352 print(sum(cap_word.search_string("More than Iron, more than Lead, more than Gold I need Electricity")))
1356 [['More'], ['Iron'], ['Lead'], ['Gold'], ['I'], ['Electricity']]
1357 ['More', 'Iron', 'Lead', 'Gold', 'I', 'Electricity']
1359 maxMatches = min(maxMatches, max_matches)
1362 [t
for t, s, e
in self.
scan_string(instring, maxMatches, debug=debug)]
1364 except ParseBaseException
as exc:
1374 maxsplit: int = _MAX_INT,
1375 include_separators: bool =
False,
1377 includeSeparators=
False,
1378 ) -> Generator[str,
None,
None]:
1380 Generator method to split a string using the given expression as a separator.
1381 May be called with optional ``maxsplit`` argument, to limit the number of splits;
1382 and the optional ``include_separators`` argument (default= ``False``), if the separating
1383 matching text should be included in the split results.
1387 punc = one_of(list(".,;:/-!?"))
1388 print(list(punc.split("This, this?, this sentence, is badly punctuated!")))
1392 ['This', ' this', '', ' this sentence', ' is badly punctuated', '']
1394 includeSeparators = includeSeparators
or include_separators
1396 for t, s, e
in self.
scan_string(instring, max_matches=maxsplit):
1397 yield instring[last:s]
1398 if includeSeparators:
1401 yield instring[last:]
1405 Implementation of ``+`` operator - returns :class:`And`. Adding strings to a :class:`ParserElement`
1406 converts them to :class:`Literal`\\ s by default.
1410 greet = Word(alphas) + "," + Word(alphas) + "!"
1411 hello = "Hello, World!"
1412 print(hello, "->", greet.parse_string(hello))
1416 Hello, World! -> ['Hello', ',', 'World', '!']
1418 ``...`` may be used as a parse expression as a short form of :class:`SkipTo`::
1420 Literal('start') + ... + Literal('end')
1424 Literal('start') + SkipTo('end')("_skipped*") + Literal('end')
1426 Note that the skipped text is returned with '_skipped' as a results name,
1427 and to support having multiple skips in the same parser, the value returned is
1428 a list of all skipped text.
1430 if other
is Ellipsis:
1436 return NotImplemented
1437 return And([self, other])
1441 Implementation of ``+`` operator when left operand is not a :class:`ParserElement`
1443 if other
is Ellipsis:
1444 return SkipTo(self)(
"_skipped*") + self
1449 return NotImplemented
1454 Implementation of ``-`` operator, returns :class:`And` with error stop
1459 return NotImplemented
1464 Implementation of ``-`` operator when left operand is not a :class:`ParserElement`
1469 return NotImplemented
1474 Implementation of ``*`` operator, allows use of ``expr * 3`` in place of
1475 ``expr + expr + expr``. Expressions may also be multiplied by a 2-integer
1476 tuple, similar to ``{min, max}`` multipliers in regular expressions. Tuples
1477 may also include ``None`` as in:
1479 - ``expr*(n, None)`` or ``expr*(n, )`` is equivalent
1480 to ``expr*n + ZeroOrMore(expr)``
1481 (read as "at least n instances of ``expr``")
1482 - ``expr*(None, n)`` is equivalent to ``expr*(0, n)``
1483 (read as "0 to n instances of ``expr``")
1484 - ``expr*(None, None)`` is equivalent to ``ZeroOrMore(expr)``
1485 - ``expr*(1, None)`` is equivalent to ``OneOrMore(expr)``
1487 Note that ``expr*(None, n)`` does not raise an exception if
1488 more than n exprs exist in the input stream; that is,
1489 ``expr*(None, n)`` does not enforce a maximum number of expr
1490 occurrences. If this behavior is desired, then write
1491 ``expr*(None, n) + ~expr``
1493 if other
is Ellipsis:
1495 elif isinstance(other, tuple)
and other[:1] == (Ellipsis,):
1496 other = ((0,) + other[1:] + (
None,))[:2]
1499 minElements, optElements = other, 0
1501 other = tuple(o
if o
is not Ellipsis
else None for o
in other)
1502 other = (other + (
None,
None))[:2]
1503 if other[0]
is None:
1504 other = (0, other[1])
1505 if isinstance(other[0], int)
and other[1]
is None:
1513 minElements, optElements = other
1514 optElements -= minElements
1516 return NotImplemented
1518 return NotImplemented
1521 raise ValueError(
"cannot multiply ParserElement by negative value")
1524 "second tuple value must be greater or equal to first tuple value"
1526 if minElements == optElements == 0:
1538 if minElements == 1:
1545 if minElements == 1:
1548 ret =
And([self] * minElements)
1556 Implementation of ``|`` operator - returns :class:`MatchFirst`
1558 if other
is Ellipsis:
1567 return NotImplemented
1572 Implementation of ``|`` operator when left operand is not a :class:`ParserElement`
1577 return NotImplemented
1582 Implementation of ``^`` operator - returns :class:`Or`
1587 return NotImplemented
1588 return Or([self, other])
1592 Implementation of ``^`` operator when left operand is not a :class:`ParserElement`
1597 return NotImplemented
1602 Implementation of ``&`` operator - returns :class:`Each`
1607 return NotImplemented
1608 return Each([self, other])
1612 Implementation of ``&`` operator when left operand is not a :class:`ParserElement`
1617 return NotImplemented
1622 Implementation of ``~`` operator - returns :class:`NotAny`
1632 use ``[]`` indexing notation as a short form for expression repetition:
1634 - ``expr[n]`` is equivalent to ``expr*n``
1635 - ``expr[m, n]`` is equivalent to ``expr*(m, n)``
1636 - ``expr[n, ...]`` or ``expr[n,]`` is equivalent
1637 to ``expr*n + ZeroOrMore(expr)``
1638 (read as "at least n instances of ``expr``")
1639 - ``expr[..., n]`` is equivalent to ``expr*(0, n)``
1640 (read as "0 to n instances of ``expr``")
1641 - ``expr[...]`` and ``expr[0, ...]`` are equivalent to ``ZeroOrMore(expr)``
1642 - ``expr[1, ...]`` is equivalent to ``OneOrMore(expr)``
1644 ``None`` may be used in place of ``...``.
1646 Note that ``expr[..., n]`` and ``expr[m, n]`` do not raise an exception
1647 if more than ``n`` ``expr``\\ s exist in the input stream. If this behavior is
1648 desired, then write ``expr[..., n] + ~expr``.
1650 For repetition with a stop_on expression, use slice notation:
1652 - ``expr[...: end_expr]`` and ``expr[0, ...: end_expr]`` are equivalent to ``ZeroOrMore(expr, stop_on=end_expr)``
1653 - ``expr[1, ...: end_expr]`` is equivalent to ``OneOrMore(expr, stop_on=end_expr)``
1657 stop_on_defined =
False
1663 stop_on_defined =
True
1665 key, stop_on = (key[0], key[1].start), key[1].stop
1666 stop_on_defined =
True
1678 f
"only 1 or 2 index arguments supported ({key[:5]}{f'... [{len(key)}]' if len(key) > 5 else ''})"
1682 ret = self * tuple(key[:2])
1690 def __call__(self, name: typing.Optional[str] =
None) ->
"ParserElement":
1692 Shortcut for :class:`set_results_name`, with ``list_all_matches=False``.
1694 If ``name`` is given with a trailing ``'*'`` character, then ``list_all_matches`` will be
1697 If ``name`` is omitted, same as calling :class:`copy`.
1701 # these are equivalent
1702 userdata = Word(alphas).set_results_name("name") + Word(nums + "-").set_results_name("socsecno")
1703 userdata = Word(alphas)("name") + Word(nums + "-")("socsecno")
1705 if name
is not None:
1710 def suppress(self) -> "ParserElement":
1712 Suppresses the output of this :class:`ParserElement`; useful to keep punctuation from
1713 cluttering up returned output.
1719 Enables the skipping of whitespace before matching the characters in the
1720 :class:`ParserElement`'s defined pattern.
1722 :param recursive: If ``True`` (the default), also enable whitespace skipping in child elements (if any)
1729 Disables the skipping of whitespace before matching the characters in the
1730 :class:`ParserElement`'s defined pattern. This is normally only used internally by
1731 the pyparsing module, but may be needed in some whitespace-sensitive grammars.
1733 :param recursive: If true (the default), also disable whitespace skipping in child elements (if any)
1739 self, chars: Union[Set[str], str], copy_defaults: bool =
False
1740 ) ->
"ParserElement":
1742 Overrides the default whitespace chars
1751 Overrides default behavior to expand ``<TAB>`` s to spaces before parsing the input string.
1752 Must be called before ``parse_string`` when the input grammar contains elements that
1753 match ``<TAB>`` characters.
1758 def ignore(self, other:
"ParserElement") ->
"ParserElement":
1760 Define expression to be ignored (e.g., comments) while doing pattern
1761 matching; may be called repeatedly, to define multiple comment or other
1766 patt = Word(alphas)[1, ...]
1767 patt.parse_string('ablaj /* comment */ lskjd')
1770 patt.ignore(c_style_comment)
1771 patt.parse_string('ablaj /* comment */ lskjd')
1772 # -> ['ablaj', 'lskjd']
1780 if other
not in self.ignoreExprs:
1781 self.ignoreExprs.append(other)
1788 start_action: DebugStartAction,
1789 success_action: DebugSuccessAction,
1790 exception_action: DebugExceptionAction,
1791 ) ->
"ParserElement":
1793 Customize display of debugging messages while doing pattern matching:
1795 - ``start_action`` - method to be called when an expression is about to be parsed;
1796 should have the signature ``fn(input_string: str, location: int, expression: ParserElement, cache_hit: bool)``
1798 - ``success_action`` - method to be called when an expression has successfully parsed;
1799 should have the signature ``fn(input_string: str, start_location: int, end_location: int, expression: ParserELement, parsed_tokens: ParseResults, cache_hit: bool)``
1801 - ``exception_action`` - method to be called when expression fails to parse;
1802 should have the signature ``fn(input_string: str, location: int, expression: ParserElement, exception: Exception, cache_hit: bool)``
1805 start_action
or _default_start_debug_action,
1806 success_action
or _default_success_debug_action,
1807 exception_action
or _default_exception_debug_action,
1812 def set_debug(self, flag: bool =
True, recurse: bool =
False) ->
"ParserElement":
1814 Enable display of debugging messages while doing pattern matching.
1815 Set ``flag`` to ``True`` to enable, ``False`` to disable.
1816 Set ``recurse`` to ``True`` to set the debug flag on this expression and all sub-expressions.
1820 wd = Word(alphas).set_name("alphaword")
1821 integer = Word(nums).set_name("numword")
1824 # turn on debugging for wd
1827 term[1, ...].parse_string("abc 123 xyz 890")
1831 Match alphaword at loc 0(1,1)
1832 Matched alphaword -> ['abc']
1833 Match alphaword at loc 3(1,4)
1834 Exception raised:Expected alphaword (at char 4), (line:1, col:5)
1835 Match alphaword at loc 7(1,8)
1836 Matched alphaword -> ['xyz']
1837 Match alphaword at loc 11(1,12)
1838 Exception raised:Expected alphaword (at char 12), (line:1, col:13)
1839 Match alphaword at loc 15(1,16)
1840 Exception raised:Expected alphaword (at char 15), (line:1, col:16)
1842 The output shown is that produced by the default debug actions - custom debug actions can be
1843 specified using :class:`set_debug_actions`. Prior to attempting
1844 to match the ``wd`` expression, the debugging message ``"Match <exprname> at loc <n>(<line>,<col>)"``
1845 is shown. Then if the parse succeeds, a ``"Matched"`` message is shown, or an ``"Exception raised"``
1846 message is shown. Also note the use of :class:`set_name` to assign a human-readable name to the expression,
1847 which makes debugging and exception messages easier to understand - for instance, the default
1848 name created for the :class:`Word` expression without calling ``set_name`` is ``"W:(A-Za-z)"``.
1857 _default_start_debug_action,
1858 _default_success_debug_action,
1859 _default_exception_debug_action,
1874 Child classes must define this method, which defines how the ``default_name`` is set.
1879 Define name for this expression, makes debugging and exception messages clearer.
1883 Word(nums).parse_string("ABC") # -> Exception: Expected W:(0-9) (at char 0), (line:1, col:1)
1884 Word(nums).set_name("integer").parse_string("ABC") # -> Exception: Expected integer (at char 0), (line:1, col:1)
1893 def name(self) -> str:
1912 subRecCheckList = parseElementList[:] + [self]
1918 Check defined expressions for valid structure, check for infinite recursive definitions.
1921 "ParserElement.validate() is deprecated, and should not be used to check for left recursion",
1929 file_or_filename: Union[str, Path, TextIO],
1930 encoding: str =
"utf-8",
1931 parse_all: bool =
False,
1933 parseAll: bool =
False,
1936 Execute the parse expression on the given file or filename.
1937 If a filename is specified (instead of a file object),
1938 the entire file is opened, read, and closed before parsing.
1940 parseAll = parseAll
or parse_all
1942 file_or_filename =
typing.cast(TextIO, file_or_filename)
1944 except AttributeError:
1945 file_or_filename =
typing.cast(str, file_or_filename)
1946 with open(file_or_filename,
"r", encoding=encoding)
as f:
1950 except ParseBaseException
as exc:
1961 return self.
matches(other, parse_all=
True)
1970 self, test_string: str, parse_all: bool =
True, *, parseAll: bool =
True
1973 Method for quick testing of a parser against a test string. Good for simple
1974 inline microtests of sub expressions while building up larger parser.
1978 - ``test_string`` - to test against this expression for a match
1979 - ``parse_all`` - (default= ``True``) - flag to pass to :class:`parse_string` when running tests
1984 assert expr.matches("100")
1986 parseAll = parseAll
and parse_all
1988 self.
parse_string(str(test_string), parse_all=parseAll)
1990 except ParseBaseException:
1995 tests: Union[str, List[str]],
1996 parse_all: bool =
True,
1998 full_dump: bool =
True,
1999 print_results: bool =
True,
2000 failure_tests: bool =
False,
2001 post_parse:
typing.Optional[Callable[[str, ParseResults], str]] =
None,
2003 with_line_numbers: bool =
False,
2005 parseAll: bool =
True,
2006 fullDump: bool =
True,
2007 printResults: bool =
True,
2008 failureTests: bool =
False,
2009 postParse:
typing.Optional[Callable[[str, ParseResults], str]] =
None,
2010 ) -> Tuple[bool, List[Tuple[str, Union[ParseResults, Exception]]]]:
2012 Execute the parse expression on a series of test strings, showing each
2013 test, the parsed results or where the parse failed. Quick and easy way to
2014 run a parse expression against a list of sample strings.
2018 - ``tests`` - a list of separate test strings, or a multiline string of test strings
2019 - ``parse_all`` - (default= ``True``) - flag to pass to :class:`parse_string` when running tests
2020 - ``comment`` - (default= ``'#'``) - expression for indicating embedded comments in the test
2021 string; pass None to disable comment filtering
2022 - ``full_dump`` - (default= ``True``) - dump results as list followed by results names in nested outline;
2023 if False, only dump nested list
2024 - ``print_results`` - (default= ``True``) prints test output to stdout
2025 - ``failure_tests`` - (default= ``False``) indicates if these tests are expected to fail parsing
2026 - ``post_parse`` - (default= ``None``) optional callback for successful parse results; called as
2027 `fn(test_string, parse_results)` and returns a string to be added to the test output
2028 - ``file`` - (default= ``None``) optional file-like object to which test output will be written;
2029 if None, will default to ``sys.stdout``
2030 - ``with_line_numbers`` - default= ``False``) show test strings with line and column numbers
2032 Returns: a (success, results) tuple, where success indicates that all tests succeeded
2033 (or failed if ``failure_tests`` is True), and the results contain a list of lines of each
2038 number_expr = pyparsing_common.number.copy()
2040 result = number_expr.run_tests('''
2045 # float with scientific notation
2047 # integer with scientific notation
2050 print("Success" if result[0] else "Failed!")
2052 result = number_expr.run_tests('''
2055 # missing leading digit before '.'
2059 ''', failure_tests=True)
2060 print("Success" if result[0] else "Failed!")
2072 # float with scientific notation
2076 # integer with scientific notation
2085 FAIL: Expected end of text (at char 3), (line:1, col:4)
2087 # missing leading digit before '.'
2090 FAIL: Expected {real number with scientific notation | real number | signed integer} (at char 0), (line:1, col:1)
2095 FAIL: Expected end of text (at char 4), (line:1, col:5)
2099 Each test string must be on a single line. If you want to test a string that spans multiple
2100 lines, create a test like this::
2102 expr.run_tests(r"this is a test\\n of strings that spans \\n 3 lines")
2104 (Note that this is a raw string literal, you must include the leading ``'r'``.)
2106 from .testing
import pyparsing_test
2108 parseAll = parseAll
and parse_all
2109 fullDump = fullDump
and full_dump
2110 printResults = printResults
and print_results
2111 failureTests = failureTests
or failure_tests
2112 postParse = postParse
or post_parse
2115 line_strip = type(tests).strip
2117 comment_specified = comment
is not None
2118 if comment_specified:
2127 result: Union[ParseResults, Exception]
2128 allResults: List[Tuple[str, Union[ParseResults, Exception]]] = []
2129 comments: List[str] = []
2134 if comment_specified
and comment.matches(t,
False)
or comments
and not t:
2142 "\n" +
"\n".join(comments)
if comments
else "",
2150 except ParseBaseException
as pe:
2151 fatal =
"(FATAL)" if isinstance(pe, ParseFatalException)
else ""
2156 success = success
and failureTests
2158 except Exception
as exc:
2159 out.append(f
"FAIL-EXCEPTION: {type(exc).__name__}: {exc}")
2162 success = success
and failureTests
2165 success = success
and not failureTests
2166 if postParse
is not None:
2169 if pp_value
is not None:
2176 except Exception
as e:
2179 f
"{postParse.__name__} failed: {type(e).__name__}: {e}"
2186 print_(
"\n".join(out))
2190 return success, allResults
2194 output_html: Union[TextIO, Path, str],
2196 show_results_names: bool =
False,
2197 show_groups: bool =
False,
2198 embed: bool =
False,
2202 Create a railroad diagram for the parser.
2206 - ``output_html`` (str or file-like object) - output target for generated
2208 - ``vertical`` (int) - threshold for formatting multiple alternatives vertically
2209 instead of horizontally (default=3)
2210 - ``show_results_names`` - bool flag whether diagram should show annotations for
2211 defined results names
2212 - ``show_groups`` - bool flag whether groups should be highlighted with an unlabeled surrounding box
2213 - ``embed`` - bool flag whether generated HTML should omit <HEAD>, <BODY>, and <DOCTYPE> tags to embed
2214 the resulting HTML in an enclosing HTML source
2215 - ``head`` - str containing additional HTML to insert into the <HEAD> section of the generated code;
2216 can be used to insert custom CSS styling
2217 - ``body`` - str containing additional HTML to insert at the beginning of the <BODY> section of the
2220 Additional diagram-formatting keyword arguments can also be included;
2221 see railroad.Diagram class.
2225 from .diagram
import to_railroad, railroad_to_html
2226 except ImportError
as ie:
2228 "must ``pip install pyparsing[diagrams]`` to generate parser railroad diagrams"
2233 railroad = to_railroad(
2236 show_results_names=show_results_names,
2237 show_groups=show_groups,
2238 diagram_kwargs=kwargs,
2241 with open(output_html,
"w", encoding=
"utf-8")
as diag_file:
2250 @replaced_by_pep8(inline_literals_using)
2254 @replaced_by_pep8(set_default_whitespace_chars)
2257 @replaced_by_pep8(set_results_name)
2260 @replaced_by_pep8(set_break)
2263 @replaced_by_pep8(set_parse_action)
2266 @replaced_by_pep8(add_parse_action)
2269 @replaced_by_pep8(add_condition)
2272 @replaced_by_pep8(set_fail_action)
2275 @replaced_by_pep8(try_parse)
2279 @replaced_by_pep8(enable_left_recursion)
2283 @replaced_by_pep8(enable_packrat)
2286 @replaced_by_pep8(parse_string)
2289 @replaced_by_pep8(scan_string)
2292 @replaced_by_pep8(transform_string)
2295 @replaced_by_pep8(search_string)
2298 @replaced_by_pep8(ignore_whitespace)
2301 @replaced_by_pep8(leave_whitespace)
2304 @replaced_by_pep8(set_whitespace_chars)
2307 @replaced_by_pep8(parse_with_tabs)
2310 @replaced_by_pep8(set_debug_actions)
2313 @replaced_by_pep8(set_debug)
2316 @replaced_by_pep8(set_name)
2319 @replaced_by_pep8(parse_file)
2322 @replaced_by_pep8(run_tests)
2325 canParseNext = can_parse_next
2326 resetCache = reset_cache
2327 defaultName = default_name
2334 def __init__(self, expr: ParserElement, must_skip: bool =
False):
2340 return str(self.
anchor +
Empty()).replace(
"Empty",
"...")
2349 t.pop(
"_skipped",
None)
2354 t[
"_skipped"] =
"missing <" + repr(self.
anchor) +
">"
2361 return self.
anchor + skipper + other
2368 "use of `...` expression without following SkipTo target expression"
2373 """Abstract :class:`ParserElement` subclass, for defining atomic
2381 return type(self).__name__
2386 A token that will never match.
2401 Token to exactly match a specified string.
2405 Literal('blah').parse_string('blah') # -> ['blah']
2406 Literal('blah').parse_string('blahfooblah') # -> ['blah']
2407 Literal('blah').parse_string('bla') # -> Exception: Expected "blah"
2409 For case-insensitive matching, use :class:`CaselessLiteral`.
2411 For keyword matching (force word break before and after the matched string),
2412 use :class:`Keyword` or :class:`CaselessKeyword`.
2415 def __new__(cls, match_string: str =
"", *, matchString: str =
""):
2418 match_string = matchString
or match_string
2419 if not match_string:
2421 if len(match_string) == 1:
2431 def __init__(self, match_string: str =
"", *, matchString: str =
""):
2433 match_string = matchString
or match_string
2434 self.
match = match_string
2442 return repr(self.
match)
2454 An empty token, will always match.
2457 def __init__(self, match_string="", *, matchString=""):
2472 return loc + 1, self.
match
2481 Token to exactly match a specified string as a keyword, that is,
2482 it must be immediately preceded and followed by whitespace or
2483 non-keyword characters. Compare with :class:`Literal`:
2485 - ``Literal("if")`` will match the leading ``'if'`` in
2487 - ``Keyword("if")`` will not; it will only match the leading
2488 ``'if'`` in ``'if x=1'``, or ``'if(y==2)'``
2490 Accepts two optional constructor arguments in addition to the
2493 - ``ident_chars`` is a string of characters that would be valid
2494 identifier characters, defaulting to all alphanumerics + "_" and
2496 - ``caseless`` allows case-insensitive matching, default is ``False``.
2500 Keyword("start").parse_string("start") # -> ['start']
2501 Keyword("start").parse_string("starting") # -> Exception
2503 For case-insensitive matching, use :class:`CaselessKeyword`.
2506 DEFAULT_KEYWORD_CHARS = alphanums +
"_$"
2510 match_string: str =
"",
2512 caseless: bool =
False,
2514 matchString: str =
"",
2518 identChars = identChars
or ident_chars
2519 if identChars
is None:
2521 match_string = matchString
or match_string
2527 raise ValueError(
"null string passed to Keyword; use Empty() instead")
2538 return repr(self.
match)
2553 errmsg +=
", was immediately followed by keyword character"
2557 errmsg +=
", keyword was immediately preceded by keyword character"
2567 if loc == 0
or instring[loc - 1]
not in self.
identChars:
2576 ", keyword was immediately followed by keyword character"
2581 errmsg +=
", keyword was immediately preceded by keyword character"
2590 Overrides the default characters used by :class:`Keyword` expressions.
2594 setDefaultKeywordChars = set_default_keyword_chars
2599 Token to match a specified string, ignoring case of letters.
2600 Note: the matched results will always be in the case of the given
2601 match string, NOT the case of the input text.
2605 CaselessLiteral("CMD")[1, ...].parse_string("cmd CMD Cmd10")
2606 # -> ['CMD', 'CMD', 'CMD']
2608 (Contrast with example for :class:`CaselessKeyword`.)
2611 def __init__(self, match_string: str =
"", *, matchString: str =
""):
2612 match_string = matchString
or match_string
2626 Caseless version of :class:`Keyword`.
2630 CaselessKeyword("CMD")[1, ...].parse_string("cmd CMD Cmd10")
2633 (Contrast with example for :class:`CaselessLiteral`.)
2638 match_string: str =
"",
2641 matchString: str =
"",
2644 identChars = identChars
or ident_chars
2645 match_string = matchString
or match_string
2650 """A variation on :class:`Literal` which matches "close" matches,
2651 that is, strings with at most 'n' mismatching characters.
2652 :class:`CloseMatch` takes parameters:
2654 - ``match_string`` - string to be matched
2655 - ``caseless`` - a boolean indicating whether to ignore casing when comparing characters
2656 - ``max_mismatches`` - (``default=1``) maximum number of
2657 mismatches allowed to count as a match
2659 The results from a successful parse will contain the matched text
2660 from the input string and the following named results:
2662 - ``mismatches`` - a list of the positions within the
2663 match_string where mismatches were found
2664 - ``original`` - the original match_string used to compare
2665 against the input string
2667 If ``mismatches`` is an empty list, then the match was an exact
2672 patt = CloseMatch("ATCATCGAATGGA")
2673 patt.parse_string("ATCATCGAAXGGA") # -> (['ATCATCGAAXGGA'], {'mismatches': [[9]], 'original': ['ATCATCGAATGGA']})
2674 patt.parse_string("ATCAXCGAAXGGA") # -> Exception: Expected 'ATCATCGAATGGA' (with up to 1 mismatches) (at char 0), (line:1, col:1)
2677 patt.parse_string("ATCATCGAATGGA") # -> (['ATCATCGAATGGA'], {'mismatches': [[]], 'original': ['ATCATCGAATGGA']})
2679 # close match allowing up to 2 mismatches
2680 patt = CloseMatch("ATCATCGAATGGA", max_mismatches=2)
2681 patt.parse_string("ATCAXCGAAXGGA") # -> (['ATCAXCGAAXGGA'], {'mismatches': [[4, 9]], 'original': ['ATCATCGAATGGA']})
2689 maxMismatches: int = 1,
2692 maxMismatches = max_mismatches
if max_mismatches
is not None else maxMismatches
2696 self.
errmsgerrmsg = f
"Expected {self.match_string!r} (with up to {self.maxMismatches} mismatches)"
2702 return f
"{type(self).__name__}:{self.match_string!r}"
2706 instrlen =
len(instring)
2709 if maxloc <= instrlen:
2716 zip(instring[loc:maxloc], match_string)
2724 if len(mismatches) > maxMismatches:
2727 loc = start + match_stringloc + 1
2729 results[
"original"] = match_string
2730 results[
"mismatches"] = mismatches
2737 """Token for matching words composed of allowed character sets.
2741 - ``init_chars`` - string of all characters that should be used to
2742 match as a word; "ABC" will match "AAA", "ABAB", "CBAC", etc.;
2743 if ``body_chars`` is also specified, then this is the string of
2745 - ``body_chars`` - string of characters that
2746 can be used for matching after a matched initial character as
2747 given in ``init_chars``; if omitted, same as the initial characters
2749 - ``min`` - minimum number of characters to match (default=1)
2750 - ``max`` - maximum number of characters to match (default=0)
2751 - ``exact`` - exact number of characters to match (default=0)
2752 - ``as_keyword`` - match as a keyword (default=``False``)
2753 - ``exclude_chars`` - characters that might be
2754 found in the input ``body_chars`` string but which should not be
2755 accepted for matching ;useful to define a word of all
2756 printables except for one or two characters, for instance
2759 :class:`srange` is useful for defining custom character set strings
2760 for defining :class:`Word` expressions, using range notation from
2761 regular expression character sets.
2763 A common mistake is to use :class:`Word` to match a specific literal
2764 string, as in ``Word("Address")``. Remember that :class:`Word`
2765 uses the string argument to define *sets* of matchable characters.
2766 This expression would match "Add", "AAA", "dAred", or any other word
2767 made up of the characters 'A', 'd', 'r', 'e', and 's'. To match an
2768 exact literal string, use :class:`Literal` or :class:`Keyword`.
2770 pyparsing includes helper strings for building Words:
2774 - :class:`alphanums`
2776 - :class:`alphas8bit` (alphabetic characters in ASCII range 128-255
2777 - accented, tilded, umlauted, etc.)
2778 - :class:`punc8bit` (non-alphabetic characters in ASCII range
2779 128-255 - currency, symbols, superscripts, diacriticals, etc.)
2780 - :class:`printables` (any non-whitespace character)
2782 ``alphas``, ``nums``, and ``printables`` are also defined in several
2783 Unicode sets - see :class:`pyparsing_unicode``.
2787 # a word composed of digits
2788 integer = Word(nums) # equivalent to Word("0123456789") or Word(srange("0-9"))
2790 # a word with a leading capital, and zero or more lowercase
2791 capital_word = Word(alphas.upper(), alphas.lower())
2793 # hostnames are alphanumeric, with leading alpha, and '-'
2794 hostname = Word(alphas, alphanums + '-')
2796 # roman numeral (not a strict parser, accepts invalid mix of characters)
2797 roman = Word("IVXLCDM")
2799 # any string of non-whitespace characters, except for ','
2800 csv_value = Word(printables, exclude_chars=",")
2805 init_chars: str =
"",
2810 as_keyword: bool =
False,
2815 asKeyword: bool =
False,
2818 initChars = initChars
or init_chars
2819 bodyChars = bodyChars
or body_chars
2820 asKeyword = asKeyword
or as_keyword
2821 excludeChars = excludeChars
or exclude_chars
2825 f
"invalid {type(self).__name__}, initChars cannot be empty string"
2828 initChars_set = set(initChars)
2830 excludeChars_set = set(excludeChars)
2831 initChars_set -= excludeChars_set
2833 bodyChars =
"".join(set(bodyChars) - excludeChars_set)
2848 "cannot specify a minimum length < 1; use Opt(Word()) if zero-length word is permitted"
2853 f
"invalid args, if min and max both specified min must be <= max (min={min}, max={max})"
2879 re_leading_fragment = f
"[{_collapse_string_to_ranges(self.initChars)}]"
2888 repeat = f
"{{{self.minLen},{'' if self.maxLen == _MAX_INT else self.maxLen}}}"
2890 repeat = f
"{{{self.minLen}}}"
2894 re_body_fragment =
""
2897 re_body_fragment = f
"[{_collapse_string_to_ranges(self.bodyChars)}]"
2901 repeat =
"?" if min <= 1
else ""
2904 repeat = f
"{{{min - 1 if min > 0 else 0},{max - 1}}}"
2906 repeat = f
"{{{min - 1 if min > 0 else 0}}}"
2909 f
"{re_leading_fragment}" f
"{re_body_fragment}" f
"{repeat}"
2913 self.
reString = rf
"\b{self.reString}\b"
2926 s = _collapse_string_to_ranges(s, re_escape=
False)
2927 if len(s) > max_repr_len:
2928 return s[: max_repr_len - 3] +
"..."
2933 base = f
"W:({charsAsStr(self.initChars)}, {charsAsStr(self.bodyChars)})"
2935 base = f
"W:({charsAsStr(self.initChars)})"
2943 return base + f
"{{{self.minLen}}}"
2944 elif self.
maxLen == _MAX_INT:
2945 return base + f
"{{{self.minLen},...}}"
2947 return base + f
"{{{self.minLen},{self.maxLen}}}"
2956 instrlen =
len(instring)
2958 maxloc = start + self.
maxLen
2959 maxloc = min(maxloc, instrlen)
2960 while loc < maxloc
and instring[loc]
in bodychars:
2963 throwException =
False
2964 if loc - start < self.
minLen:
2965 throwException =
True
2966 elif self.
maxSpecified and loc < instrlen
and instring[loc]
in bodychars:
2967 throwException =
True
2971 and instring[start - 1]
in bodychars
2973 and instring[loc]
in bodychars
2975 throwException =
True
2980 return loc, instring[start:loc]
2983 result = self.
re_match(instring, loc)
2992 """A short-cut class for defining :class:`Word` ``(characters, exact=1)``,
2993 when defining a match of any single character in a string of
3000 as_keyword: bool =
False,
3003 asKeyword: bool =
False,
3006 asKeyword = asKeyword
or as_keyword
3007 excludeChars = excludeChars
or exclude_chars
3009 charset, exact=1, as_keyword=asKeyword, exclude_chars=excludeChars
3014 r"""Token for matching strings that match a given regular
3015 expression. Defined with string specifying the regular expression in
3016 a form recognized by the stdlib Python `re module <https://docs.python.org/3/library/re.html>`_.
3017 If the given regex contains named groups (defined using ``(?P<name>...)``),
3018 these will be preserved as named :class:`ParseResults`.
3020 If instead of the Python stdlib ``re`` module you wish to use a different RE module
3021 (such as the ``regex`` module), you can do so by building your ``Regex`` object with
3022 a compiled RE that was compiled using ``regex``.
3026 realnum = Regex(r"[+-]?\d+\.\d*")
3027 # ref: https://stackoverflow.com/questions/267399/how-do-you-match-only-valid-roman-numerals-with-a-regular-expression
3028 roman = Regex(r"M{0,4}(CM|CD|D?{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})")
3030 # named fields in a regex will be returned as named results
3031 date = Regex(r'(?P<year>\d{4})-(?P<month>\d\d?)-(?P<day>\d\d?)')
3033 # the Regex class will accept re's compiled using the regex module
3035 parser = pp.Regex(regex.compile(r'[0-9]'))
3042 as_group_list: bool =
False,
3043 as_match: bool =
False,
3045 asGroupList: bool =
False,
3046 asMatch: bool =
False,
3048 """The parameters ``pattern`` and ``flags`` are passed
3049 to the ``re.compile()`` function as-is. See the Python
3050 `re module <https://docs.python.org/3/library/re.html>`_ module for an
3051 explanation of the acceptable patterns and flags.
3054 asGroupList = asGroupList
or as_group_list
3055 asMatch = asMatch
or as_match
3059 raise ValueError(
"null string passed to Regex; use Empty() instead")
3072 "Regex may only be constructed with a string or a compiled RE object"
3092 raise ValueError(f
"invalid pattern ({self.pattern!r}) passed to Regex")
3096 return self.
re.match
3100 return self.
re_match(
"")
is not None
3103 return "Re:({})".format(repr(self.
pattern).replace(
"\\\\",
"\\"))
3106 result = self.
re_match(instring, loc)
3119 result = self.
re_match(instring, loc)
3128 result = self.
re_match(instring, loc)
3136 def sub(self, repl: str) -> ParserElement:
3138 Return :class:`Regex` with an attached parse action to transform the parsed
3139 result as if called using `re.sub(expr, repl, string) <https://docs.python.org/3/library/re.html#re.sub>`_.
3143 make_html = Regex(r"(\w+):(.*?):").sub(r"<\1>\2</\1>")
3144 print(make_html.transform_string("h1:main title:"))
3145 # prints "<h1>main title</h1>"
3148 raise TypeError(
"cannot use sub() with Regex(as_group_list=True)")
3150 if self.
asMatch and callable(repl):
3152 "cannot use sub() with a callable with Regex(as_match=True)"
3158 return tokens[0].expand(repl)
3163 return self.
re.
sub(repl, tokens[0])
3170 Token for matching strings that are delimited by quoting characters.
3172 Defined with the following parameters:
3174 - ``quote_char`` - string of one or more characters defining the
3175 quote delimiting string
3176 - ``esc_char`` - character to re_escape quotes, typically backslash
3178 - ``esc_quote`` - special quote sequence to re_escape an embedded quote
3179 string (such as SQL's ``""`` to re_escape an embedded ``"``)
3181 - ``multiline`` - boolean indicating whether quotes can span
3182 multiple lines (default= ``False``)
3183 - ``unquote_results`` - boolean indicating whether the matched text
3184 should be unquoted (default= ``True``)
3185 - ``end_quote_char`` - string of one or more characters defining the
3186 end of the quote delimited string (default= ``None`` => same as
3188 - ``convert_whitespace_escapes`` - convert escaped whitespace
3189 (``'\t'``, ``'\n'``, etc.) to actual whitespace
3194 qs = QuotedString('"')
3195 print(qs.search_string('lsjdf "This is the quote" sldjf'))
3196 complex_qs = QuotedString('{{', end_quote_char='}}')
3197 print(complex_qs.search_string('lsjdf {{This is the "quote"}} sldjf'))
3198 sql_qs = QuotedString('"', esc_quote='""')
3199 print(sql_qs.search_string('lsjdf "This is the quote with ""embedded"" quotes" sldjf'))
3203 [['This is the quote']]
3204 [['This is the "quote"']]
3205 [['This is the quote with "embedded" quotes']]
3207 ws_map = dict(((
r"\t",
"\t"), (
r"\n",
"\n"), (
r"\f",
"\f"), (
r"\r",
"\r")))
3211 quote_char: str =
"",
3214 multiline: bool =
False,
3215 unquote_results: bool =
True,
3217 convert_whitespace_escapes: bool =
True,
3219 quoteChar: str =
"",
3222 unquoteResults: bool =
True,
3224 convertWhitespaceEscapes: bool =
True,
3227 escChar = escChar
or esc_char
3228 escQuote = escQuote
or esc_quote
3229 unquoteResults = unquoteResults
and unquote_results
3230 endQuoteChar = endQuoteChar
or end_quote_char
3231 convertWhitespaceEscapes = (
3232 convertWhitespaceEscapes
and convert_whitespace_escapes
3234 quote_char = quoteChar
or quote_char
3239 raise ValueError(
"quote_char cannot be the empty string")
3241 if endQuoteChar
is None:
3242 endQuoteChar = quote_char
3245 if not endQuoteChar:
3246 raise ValueError(
"end_quote_char cannot be the empty string")
3249 self.quoteCharLen: int =
len(quote_char)
3250 self.firstQuoteChar: str = quote_char[0]
3252 self.endQuoteCharLen: int =
len(endQuoteChar)
3253 self.escChar: str = escChar
or ""
3254 self.escQuote: str = escQuote
or ""
3255 self.unquoteResults: bool = unquoteResults
3256 self.convertWhitespaceEscapes: bool = convertWhitespaceEscapes
3263 inner_pattern += rf
"{sep}(?:{re.escape(escQuote)})"
3267 inner_pattern += rf
"{sep}(?:{re.escape(escChar)}.)"
3275 f
"(?:{re.escape(self.endQuoteChar[:i])}(?!{re.escape(self.endQuoteChar[i:])}))"
3287 rf
"{sep}(?:[^{_escape_regex_range_chars(self.endQuoteChar[0])}"
3288 rf
"{(_escape_regex_range_chars(escChar) if escChar is not None else '')}])"
3292 rf
"{sep}(?:[^{_escape_regex_range_chars(self.endQuoteChar[0])}\n\r"
3293 rf
"{(_escape_regex_range_chars(escChar) if escChar is not None else '')}])"
3306 if self.unquoteResults:
3307 if self.convertWhitespaceEscapes:
3309 rf
"({'|'.join(re.escape(k) for k in self.ws_map)})|({re.escape(self.escChar)}.)|(\n|.)",
3314 rf
"({re.escape(self.escChar)}.)|(\n|.)", flags=self.
flags
3322 raise ValueError(f
"invalid pattern {self.pattern!r} passed to Regex")
3330 return f
"string enclosed in {self.quoteChar!r}"
3332 return f
"quoted string, starting with {self.quoteChar} ending with {self.endQuoteChar}"
3336 instring[loc] == self.firstQuoteChar
3346 if self.unquoteResults:
3348 ret = ret[self.quoteCharLen : -self.endQuoteCharLen]
3351 if self.convertWhitespaceEscapes:
3374 """Token for matching words composed of characters *not* in a given
3375 set (will include whitespace in matched characters if not listed in
3376 the provided exclusion set - see example). Defined with string
3377 containing all disallowed characters, and an optional minimum,
3378 maximum, and/or exact length. The default value for ``min`` is
3379 1 (a minimum value < 1 is not valid); the default values for
3380 ``max`` and ``exact`` are 0, meaning no maximum or exact
3385 # define a comma-separated-value as anything that is not a ','
3386 csv_value = CharsNotIn(',')
3387 print(DelimitedList(csv_value).parse_string("dkls,lsdkjf,s12 34,@!#,213"))
3391 ['dkls', 'lsdkjf', 's12 34', '@!#', '213']
3396 not_chars: str =
"",
3410 "cannot specify a minimum length < 1; use "
3411 "Opt(CharsNotIn()) if zero-length char group is permitted"
3430 not_chars_str = _collapse_string_to_ranges(self.
notChars)
3431 if len(not_chars_str) > 16:
3432 return f
"!W:({self.notChars[: 16 - 3]}...)"
3434 return f
"!W:({self.notChars})"
3438 if instring[loc]
in notchars:
3443 maxlen = min(start + self.
maxLen,
len(instring))
3444 while loc < maxlen
and instring[loc]
not in notchars:
3447 if loc - start < self.
minLen:
3450 return loc, instring[start:loc]
3454 """Special matching class for matching whitespace. Normally,
3455 whitespace is ignored by pyparsing grammars. This class is included
3456 when some whitespace structures are significant. Define with
3457 a string containing the whitespace characters to be matched; default
3458 is ``" \\t\\r\\n"``. Also takes optional ``min``,
3459 ``max``, and ``exact`` arguments, as defined for the
3460 :class:`Word` class.
3470 "\u1680":
"<OGHAM_SPACE_MARK>",
3471 "\u180E":
"<MONGOLIAN_VOWEL_SEPARATOR>",
3472 "\u2000":
"<EN_QUAD>",
3473 "\u2001":
"<EM_QUAD>",
3474 "\u2002":
"<EN_SPACE>",
3475 "\u2003":
"<EM_SPACE>",
3476 "\u2004":
"<THREE-PER-EM_SPACE>",
3477 "\u2005":
"<FOUR-PER-EM_SPACE>",
3478 "\u2006":
"<SIX-PER-EM_SPACE>",
3479 "\u2007":
"<FIGURE_SPACE>",
3480 "\u2008":
"<PUNCTUATION_SPACE>",
3481 "\u2009":
"<THIN_SPACE>",
3482 "\u200A":
"<HAIR_SPACE>",
3483 "\u200B":
"<ZERO_WIDTH_SPACE>",
3484 "\u202F":
"<NNBSP>",
3486 "\u3000":
"<IDEOGRAPHIC_SPACE>",
3489 def __init__(self, ws: str =
" \t\r\n", min: int = 1, max: int = 0, exact: int = 0):
3519 maxloc = start + self.
maxLen
3520 maxloc = min(maxloc,
len(instring))
3521 while loc < maxloc
and instring[loc]
in self.
matchWhite:
3524 if loc - start < self.
minLen:
3527 return loc, instring[start:loc]
3538 """Token to advance to a specific column of input text; useful for
3539 tabular report scraping.
3547 if col(loc, instring) != self.
col:
3548 instrlen =
len(instring)
3549 if self.ignoreExprs:
3554 and col(loc, instring) != self.
col
3560 thiscol =
col(loc, instring)
3561 if thiscol > self.
col:
3562 raise ParseException(instring, loc,
"Text not in expected column", self)
3563 newloc = loc + self.
col - thiscol
3564 ret = instring[loc:newloc]
3569 r"""Matches if current position is at the beginning of a line within
3577 AAA but not this one
3578 B AAA and definitely not this one
3581 for t in (LineStart() + 'AAA' + rest_of_line).search_string(test):
3586 ['AAA', ' this line']
3587 ['AAA', ' and this line']
3605 while instring[ret : ret + 1] ==
"\n":
3610 if col(loc, instring) == 1:
3616 """Matches if current position is at the end of a line within the
3627 if loc <
len(instring):
3628 if instring[loc] ==
"\n":
3629 return loc + 1,
"\n"
3632 elif loc ==
len(instring):
3639 """Matches if current position is at the beginning of the parse
3650 if loc != self.
preParse(instring, 0):
3657 Matches if current position is at the end of the parse string
3665 if loc <
len(instring):
3667 elif loc ==
len(instring):
3669 elif loc >
len(instring):
3676 """Matches if the current position is at the beginning of a
3677 :class:`Word`, and is not preceded by any character in a given
3678 set of ``word_chars`` (default= ``printables``). To emulate the
3679 ``\b`` behavior of regular expressions, use
3680 ``WordStart(alphanums)``. ``WordStart`` will also match at
3681 the beginning of the string being parsed, or at the beginning of
3685 def __init__(self, word_chars: str = printables, *, wordChars: str = printables):
3686 wordChars = word_chars
if wordChars == printables
else wordChars
3702 """Matches if the current position is at the end of a :class:`Word`,
3703 and is not followed by any character in a given set of ``word_chars``
3704 (default= ``printables``). To emulate the ``\b`` behavior of
3705 regular expressions, use ``WordEnd(alphanums)``. ``WordEnd``
3706 will also match at the end of the string being parsed, or at the end
3710 def __init__(self, word_chars: str = printables, *, wordChars: str = printables):
3711 wordChars = word_chars
if wordChars == printables
else wordChars
3718 instrlen =
len(instring)
3719 if instrlen > 0
and loc < instrlen:
3722 or instring[loc - 1]
not in self.
wordChars
3729 """Abstract subclass of ParserElement, for combining and
3730 post-processing parsed tokens.
3733 def __init__(self, exprs: typing.Iterable[ParserElement], savelist: bool =
False):
3735 self.
exprs: List[ParserElement]
3742 self.
exprs = [exprs]
3751 self.
exprs = list(exprs)
3754 self.
exprs = list(exprs)
3756 self.
exprs = [exprs]
3760 return self.
exprs[:]
3769 Extends ``leave_whitespace`` defined in base class, and also invokes ``leave_whitespace`` on
3770 all contained expressions.
3776 for e
in self.
exprs:
3782 Extends ``ignore_whitespace`` defined in base class, and also invokes ``leave_whitespace`` on
3783 all contained expressions.
3788 for e
in self.
exprs:
3794 if other
not in self.ignoreExprs:
3796 for e
in self.
exprs:
3800 for e
in self.
exprs:
3805 return f
"{self.__class__.__name__}:({str(self.exprs)})"
3813 for e
in self.
exprs:
3820 other = self.
exprs[0]
3832 other = self.
exprs[-1]
3850 "ParserElement.validate() is deprecated, and should not be used to check for left recursion",
3854 tmp = (validateTrace
if validateTrace
is not None else [])[:] + [self]
3855 for e
in self.
exprs:
3859 def copy(self) -> ParserElement:
3860 ret =
super().copy()
3869 not in self.suppress_warnings_
3871 for e
in self.
exprs:
3879 "{}: setting results name {!r} on {} expression "
3880 "collides with {!r} on contained expression".format(
3881 "warn_ungrouped_named_tokens_in_collection",
3883 type(self).__name__,
3893 @replaced_by_pep8(leave_whitespace)
3896 @replaced_by_pep8(ignore_whitespace)
3903 Requires all given :class:`ParseExpression` s to be found in the given order.
3904 Expressions may be separated by whitespace.
3905 May be constructed using the ``'+'`` operator.
3906 May also be constructed using the ``'-'`` operator, which will
3907 suppress backtracking.
3911 integer = Word(nums)
3912 name_expr = Word(alphas)[1, ...]
3914 expr = And([integer("id"), name_expr("name"), integer("age")])
3915 # more easily written as:
3916 expr = integer("id") + name_expr("name") + integer("age")
3928 self, exprs_arg: typing.Iterable[ParserElement], savelist: bool =
True
3930 exprs: List[ParserElement] = list(exprs_arg)
3931 if exprs
and Ellipsis
in exprs:
3934 if expr
is Ellipsis:
3935 if i <
len(exprs) - 1:
3937 ParseExpression, (
Empty() + exprs[i + 1])
3942 "cannot construct And with sequence ending in ..."
3953 copy_defaults=self.
exprsexprs[0].copyDefaultWhiteChars,
3971 deleted_expr_marker =
NoMatch()
3973 if e
is deleted_expr_marker:
3999 lambda s, l, t, cur_=cur:
setattr(
4000 cur_,
"parent_anchor", col(l, s)
4005 next_first = next(iter(subs),
None)
4006 if next_first
is None:
4017 instring, loc, doActions, callPreParse=
False
4027 loc, exprtokens =
e._parse(instring, loc, doActions)
4028 except ParseSyntaxException:
4030 except ParseBaseException
as pe:
4038 loc, exprtokens =
e._parse(instring, loc, doActions)
4039 resultlist += exprtokens
4040 return loc, resultlist
4046 return NotImplemented
4047 return self.
append(other)
4050 subRecCheckList = parseElementList[:] + [self]
4057 inner =
" ".join(str(e)
for e
in self.
exprsexprs)
4059 while len(inner) > 1
and inner[0 ::
len(inner) - 1] ==
"{}":
4061 return "{" + inner +
"}"
4065 """Requires that at least one :class:`ParseExpression` is found. If
4066 two expressions match, the expression that matches the longest
4067 string will be used. May be constructed using the ``'^'``
4072 # construct Or using '^' operator
4074 number = Word(nums) ^ Combine(Word(nums) + '.' + Word(nums))
4075 print(number.search_string("123 3.1416 789"))
4079 [['123'], ['3.1416'], ['789']]
4082 def __init__(self, exprs: typing.Iterable[ParserElement], savelist: bool =
False):
4111 loc2 =
e.try_parse(instring, loc, raise_fatal=
True)
4112 except ParseFatalException
as pfe:
4118 except ParseException
as err:
4125 if len(instring) > maxExcLoc:
4129 maxExcLoc =
len(instring)
4142 best_expr = matches[0][1]
4146 for loc1, expr1
in matches:
4147 if loc1 <= longest[0]:
4153 except ParseException
as err:
4162 elif loc2 > longest[0]:
4163 longest = loc2, toks
4165 if longest != (-1,
None):
4171 if fatals[0].loc == fatals[1].loc:
4173 max_fatal = fatals[0]
4176 if maxException
is not None:
4179 if maxExcLoc == loc:
4184 instring, loc,
"no defined alternatives to match", self
4191 return NotImplemented
4192 return self.
append(other)
4195 return "{" +
" ^ ".join(str(e)
for e
in self.
exprsexprs) +
"}"
4201 not in self.suppress_warnings_
4210 "{}: setting results name {!r} on {} expression "
4211 "will return a list of all parsed tokens in an And alternative, "
4212 "in prior versions only the first token was returned; enclose "
4213 "contained argument in Group".format(
4214 "warn_multiple_tokens_in_named_alternation",
4216 type(self).__name__,
4225 """Requires that at least one :class:`ParseExpression` is found. If
4226 more than one expression matches, the first one listed is the one that will
4227 match. May be constructed using the ``'|'`` operator.
4231 # construct MatchFirst using '|' operator
4233 # watch the order of expressions to match
4234 number = Word(nums) | Combine(Word(nums) + '.' + Word(nums))
4235 print(number.search_string("123 3.1416 789")) # Fail! -> [['123'], ['3'], ['1416'], ['789']]
4237 # put more selective expression first
4238 number = Combine(Word(nums) + '.' + Word(nums)) | Word(nums)
4239 print(number.search_string("123 3.1416 789")) # Better -> [['123'], ['3.1416'], ['789']]
4242 def __init__(self, exprs: typing.Iterable[ParserElement], savelist: bool =
False):
4277 except ParseFatalException
as pfe:
4281 except ParseException
as err:
4286 if len(instring) > maxExcLoc:
4290 maxExcLoc =
len(instring)
4292 if maxException
is not None:
4295 if maxExcLoc == loc:
4300 instring, loc,
"no defined alternatives to match", self
4307 return NotImplemented
4308 return self.
append(other)
4317 not in self.suppress_warnings_
4326 "{}: setting results name {!r} on {} expression "
4327 "will return a list of all parsed tokens in an And alternative, "
4328 "in prior versions only the first token was returned; enclose "
4329 "contained argument in Group".format(
4330 "warn_multiple_tokens_in_named_alternation",
4332 type(self).__name__,
4341 """Requires all given :class:`ParseExpression` s to be found, but in
4342 any order. Expressions may be separated by whitespace.
4344 May be constructed using the ``'&'`` operator.
4348 color = one_of("RED ORANGE YELLOW GREEN BLUE PURPLE BLACK WHITE BROWN")
4349 shape_type = one_of("SQUARE CIRCLE TRIANGLE STAR HEXAGON OCTAGON")
4350 integer = Word(nums)
4351 shape_attr = "shape:" + shape_type("shape")
4352 posn_attr = "posn:" + Group(integer("x") + ',' + integer("y"))("posn")
4353 color_attr = "color:" + color("color")
4354 size_attr = "size:" + integer("size")
4356 # use Each (using operator '&') to accept attributes in any order
4357 # (shape and posn are required, color and size are optional)
4358 shape_spec = shape_attr & posn_attr & Opt(color_attr) & Opt(size_attr)
4360 shape_spec.run_tests('''
4361 shape: SQUARE color: BLACK posn: 100, 120
4362 shape: CIRCLE size: 50 color: BLUE posn: 50,80
4363 color:GREEN size:20 shape:TRIANGLE posn:20,40
4369 shape: SQUARE color: BLACK posn: 100, 120
4370 ['shape:', 'SQUARE', 'color:', 'BLACK', 'posn:', ['100', ',', '120']]
4372 - posn: ['100', ',', '120']
4378 shape: CIRCLE size: 50 color: BLUE posn: 50,80
4379 ['shape:', 'CIRCLE', 'size:', '50', 'color:', 'BLUE', 'posn:', ['50', ',', '80']]
4381 - posn: ['50', ',', '80']
4388 color: GREEN size: 20 shape: TRIANGLE posn: 20,40
4389 ['color:', 'GREEN', 'size:', '20', 'shape:', 'TRIANGLE', 'posn:', ['20', ',', '40']]
4391 - posn: ['20', ',', '40']
4398 def __init__(self, exprs: typing.Iterable[ParserElement], savelist: bool =
True):
4412 return NotImplemented
4413 return self.
append(other)
4461 tmpExprs = tmpReqd + tmpOpt + multis
4466 tmpLoc =
e.try_parse(instring, tmpLoc, raise_fatal=
True)
4467 except ParseFatalException
as pfe:
4472 except ParseException:
4480 if len(failed) ==
len(tmpExprs):
4481 keepMatching =
False
4487 if fatals[0].loc == fatals[1].loc:
4489 max_fatal = fatals[0]
4493 missing =
", ".join([str(e)
for e
in tmpReqd])
4497 f
"Missing one or more required elements ({missing})",
4504 for e
in matchOrder:
4505 loc, results =
e._parse(instring, loc, doActions)
4506 total_results += results
4508 return loc, total_results
4515 """Abstract subclass of :class:`ParserElement`, for combining and
4516 post-processing parsed tokens.
4519 def __init__(self, expr: Union[ParserElement, str], savelist: bool =
False):
4531 if expr
is not None:
4543 return [self.
expr]
if self.
expr is not None else []
4546 if self.
expr is not None:
4548 return self.
expr.
_parse(instring, loc, doActions, callPreParse=
False)
4549 except ParseBaseException
as pbe:
4553 raise ParseException(instring, loc,
"No expression defined", self)
4559 if self.
expr is not None:
4568 if self.
expr is not None:
4575 if other
not in self.ignoreExprs:
4577 if self.
expr is not None:
4581 if self.
expr is not None:
4587 if self.
expr is not None:
4592 if self
in parseElementList:
4594 subRecCheckList = parseElementList[:] + [self]
4595 if self.
expr is not None:
4600 "ParserElement.validate() is deprecated, and should not be used to check for left recursion",
4604 if validateTrace
is None:
4606 tmp = validateTrace[:] + [self]
4607 if self.
expr is not None:
4612 return f
"{self.__class__.__name__}:({str(self.expr)})"
4616 @replaced_by_pep8(leave_whitespace)
4619 @replaced_by_pep8(ignore_whitespace)
4626 Expression to match one or more expressions at a given indentation level.
4627 Useful for parsing text where structure is implied by indentation (like Python source code).
4643 self, expr: ParserElement, *, recursive: bool =
False, grouped: bool =
True
4661 indent_col = col(anchor_loc, instring)
4662 peer_detect_expr = self.
_Indent(indent_col)
4672 inner_expr +=
Opt(sub_indent + nested_block)
4682 wrapper =
lambda expr: expr
4684 instring, anchor_loc, doActions
4689 """Matches if expression matches at the beginning of the parse
4692 AtStringStart(Word(nums)).parse_string("123")
4695 AtStringStart(Word(nums)).parse_string(" 123")
4696 # raises ParseException
4710 r"""Matches if an expression matches at the beginning of a line within
4718 AAA but not this one
4719 B AAA and definitely not this one
4722 for t in (AtLineStart('AAA') + rest_of_line).search_string(test):
4727 ['AAA', ' this line']
4728 ['AAA', ' and this line']
4737 if col(loc, instring) != 1:
4743 """Lookahead matching of the given parse expression.
4744 ``FollowedBy`` does *not* advance the parsing position within
4745 the input string, it only verifies that the specified parse
4746 expression matches at the current position. ``FollowedBy``
4747 always returns a null token list. If any results names are defined
4748 in the lookahead expression, those *will* be returned for access by
4753 # use FollowedBy to match a label only if it is followed by a ':'
4754 data_word = Word(alphas)
4755 label = data_word + FollowedBy(':')
4756 attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stop_on=label).set_parse_action(' '.join))
4758 attr_expr[1, ...].parse_string("shape: SQUARE color: BLACK posn: upper left").pprint()
4762 [['shape', 'SQUARE'], ['color', 'BLACK'], ['posn', 'upper left']]
4772 _, ret = self.
expr.
_parse(instring, loc, doActions=doActions)
4779 """Lookbehind matching of the given parse expression.
4780 ``PrecededBy`` does not advance the parsing position within the
4781 input string, it only verifies that the specified parse expression
4782 matches prior to the current position. ``PrecededBy`` always
4783 returns a null token list, but if a results name is defined on the
4784 given expression, it is returned.
4788 - ``expr`` - expression that must match prior to the current parse
4790 - ``retreat`` - (default= ``None``) - (int) maximum number of characters
4791 to lookbehind prior to the current parse location
4793 If the lookbehind expression is a string, :class:`Literal`,
4794 :class:`Keyword`, or a :class:`Word` or :class:`CharsNotIn`
4795 with a specified exact or maximum length, then the retreat
4796 parameter is not required. Otherwise, retreat must be specified to
4797 give a maximum number of characters to look back from
4798 the current parse position for a lookbehind match.
4802 # VB-style variable names with type prefixes
4803 int_var = PrecededBy("#") + pyparsing_common.identifier
4804 str_var = PrecededBy("$") + pyparsing_common.identifier
4809 self, expr: Union[ParserElement, str], retreat:
typing.Optional[int] =
None
4843 instring_slice = instring[max(0, loc - self.
retreat) : loc]
4845 for offset
in range(1, min(loc, self.
retreat + 1) + 1):
4849 instring_slice,
len(instring_slice) - offset
4851 except ParseBaseException
as pbe:
4862 Decorates a returned token with its starting and ending
4863 locations in the input string.
4865 This helper adds the following results names:
4867 - ``locn_start`` - location where matched expression begins
4868 - ``locn_end`` - location where matched expression ends
4869 - ``value`` - the actual parsed results
4871 Be careful if the input text contains ``<TAB>`` characters, you
4872 may want to call :class:`ParserElement.parse_with_tabs`
4877 for match in Located(wd).search_string("ljsdf123lksdjjf123lkkjj1222"):
4883 [8, ['lksdjjf'], 15]
4890 loc, tokens = self.
expr.
_parse(instring, start, doActions, callPreParse=
False)
4892 ret_tokens[
"locn_start"] = start
4893 ret_tokens[
"value"] = tokens
4894 ret_tokens[
"locn_end"] = loc
4897 return loc, [ret_tokens]
4899 return loc, ret_tokens
4904 Lookahead to disallow matching with the given parse expression.
4905 ``NotAny`` does *not* advance the parsing position within the
4906 input string, it only verifies that the specified parse expression
4907 does *not* match at the current position. Also, ``NotAny`` does
4908 *not* skip over leading whitespace. ``NotAny`` always returns
4909 a null token list. May be constructed using the ``'~'`` operator.
4913 AND, OR, NOT = map(CaselessKeyword, "AND OR NOT".split())
4915 # take care not to mistake keywords for identifiers
4916 ident = ~(AND | OR | NOT) + Word(alphas)
4917 boolean_term = Opt(NOT) + ident
4919 # very crude boolean expression - to support parenthesis groups and
4920 # operation hierarchy, use infix_notation
4921 boolean_expr = boolean_term + ((AND | OR) + boolean_term)[...]
4923 # integers that are followed by "." are actually floats
4924 integer = Word(nums) + ~Char(".")
4948 expr: Union[str, ParserElement],
4954 stopOn = stopOn
or stop_on
4968 self_expr_parse = self.
expr._parse
4970 check_ender = self.
not_ender is not None
4972 try_not_ender = self.
not_ender.try_parse
4980 hasIgnoreExprs =
not not self.ignoreExprs
4990 except (ParseException, IndexError):
4999 not in self.suppress_warnings_
5009 "{}: setting results name {!r} on {} expression "
5010 "collides with {!r} on contained expression".format(
5011 "warn_ungrouped_named_tokens_in_collection",
5013 type(self).__name__,
5024 Repetition of one or more of the given expression.
5028 - ``expr`` - expression that must match one or more times
5029 - ``stop_on`` - (default= ``None``) - expression for a terminating sentinel
5030 (only required if the sentinel would ordinarily match the repetition
5035 data_word = Word(alphas)
5036 label = data_word + FollowedBy(':')
5037 attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).set_parse_action(' '.join))
5039 text = "shape: SQUARE posn: upper left color: BLACK"
5040 attr_expr[1, ...].parse_string(text).pprint() # Fail! read 'color' as data instead of next label -> [['shape', 'SQUARE color']]
5042 # use stop_on attribute for OneOrMore to avoid reading label string as part of the data
5043 attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stop_on=label).set_parse_action(' '.join))
5044 OneOrMore(attr_expr).parse_string(text).pprint() # Better -> [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'BLACK']]
5046 # could also be written as
5047 (attr_expr * (1,)).parse_string(text).pprint()
5056 Optional repetition of zero or more of the given expression.
5060 - ``expr`` - expression that must match zero or more times
5061 - ``stop_on`` - expression for a terminating sentinel
5062 (only required if the sentinel would ordinarily match the repetition
5063 expression) - (default= ``None``)
5065 Example: similar to :class:`OneOrMore`
5070 expr: Union[str, ParserElement],
5081 except (ParseException, IndexError):
5091 expr: Union[str, ParserElement],
5092 delim: Union[str, ParserElement] =
",",
5093 combine: bool =
False,
5097 allow_trailing_delim: bool =
False,
5099 """Helper to define a delimited list of expressions - the delimiter
5100 defaults to ','. By default, the list elements and delimiters can
5101 have intervening whitespace, and comments, but this can be
5102 overridden by passing ``combine=True`` in the constructor. If
5103 ``combine`` is set to ``True``, the matching tokens are
5104 returned as a single token string, with the delimiters included;
5105 otherwise, the matching tokens are returned as a list of tokens,
5106 with the delimiters suppressed.
5108 If ``allow_trailing_delim`` is set to True, then the list may end with
5113 DelimitedList(Word(alphas)).parse_string("aa,bb,cc") # -> ['aa', 'bb', 'cc']
5114 DelimitedList(Word(hexnums), delim=':', combine=True).parse_string("AA:BB:CC:DD:EE") # -> ['AA:BB:CC:DD:EE']
5122 raise ValueError(
"min must be greater than 0")
5124 if min
is not None and max < min:
5125 raise ValueError(
"max must be greater than, or equal to min")
5139 None if self.
max is None else self.
max - 1,
5145 delim_list_expr =
Combine(delim_list_expr)
5163 Optional matching of the given expression.
5167 - ``expr`` - expression that must match zero or more times
5168 - ``default`` (optional) - value to be returned if the optional expression is not found.
5172 # US postal code can be a 5-digit zip, plus optional 4-digit qualifier
5173 zip = Combine(Word(nums, exact=5) + Opt('-' + Word(nums, exact=4)))
5175 # traditional ZIP code
5187 # traditional ZIP code
5198 FAIL: Expected end of text (at char 5), (line:1, col:6)
5204 self, expr: Union[ParserElement, str], default: Any = __optionalNotMatched
5212 self_expr = self.
expr
5214 loc, tokens =
self_expr._parse(instring, loc, doActions, callPreParse=
False)
5215 except (ParseException, IndexError):
5222 tokens = [default_value]
5228 inner = str(self.
expr)
5230 while len(inner) > 1
and inner[0 ::
len(inner) - 1] ==
"{}":
5232 return "[" + inner +
"]"
5240 Token for skipping over all undefined text until the matched
5241 expression is found.
5245 - ``expr`` - target expression marking the end of the data to be skipped
5246 - ``include`` - if ``True``, the target expression is also parsed
5247 (the skipped text and target expression are returned as a 2-element
5248 list) (default= ``False``).
5249 - ``ignore`` - (default= ``None``) used to define grammars (typically quoted strings and
5250 comments) that might contain false matches to the target expression
5251 - ``fail_on`` - (default= ``None``) define expressions that are not allowed to be
5252 included in the skipped test; if found before the target expression is found,
5253 the :class:`SkipTo` is not a match
5258 Outstanding Issues Report - 1 Jan 2000
5260 # | Severity | Description | Days Open
5261 -----+----------+-------------------------------------------+-----------
5262 101 | Critical | Intermittent system crash | 6
5263 94 | Cosmetic | Spelling error on Login ('log|n') | 14
5264 79 | Minor | System slow when running too many reports | 47
5266 integer = Word(nums)
5268 # use SkipTo to simply match everything up until the next SEP
5269 # - ignore quoted strings, so that a '|' character inside a quoted string does not match
5270 # - parse action will call token.strip() for each matched token, i.e., the description body
5271 string_data = SkipTo(SEP, ignore=quoted_string)
5272 string_data.set_parse_action(token_map(str.strip))
5273 ticket_expr = (integer("issue_num") + SEP
5274 + string_data("sev") + SEP
5275 + string_data("desc") + SEP
5276 + integer("days_open"))
5278 for tkt in ticket_expr.search_string(report):
5283 ['101', 'Critical', 'Intermittent system crash', '6']
5285 - desc: 'Intermittent system crash'
5288 ['94', 'Cosmetic', "Spelling error on Login ('log|n')", '14']
5290 - desc: "Spelling error on Login ('log|n')"
5293 ['79', 'Minor', 'System slow when running too many reports', '47']
5295 - desc: 'System slow when running too many reports'
5302 other: Union[ParserElement, str],
5303 include: bool =
False,
5310 failOn = failOn
or fail_on
5311 if ignore
is not None:
5325 instrlen =
len(instring)
5326 self_expr_parse = self.
expr._parse
5327 self_failOn_canParseNext = (
5328 self.
failOn.canParseNext
if self.
failOn is not None else None
5333 while tmploc <= instrlen:
5334 if self_failOn_canParseNext
is not None:
5339 if self_preParse
is not None:
5344 self_expr_parse(instring, tmploc, doActions=
False, callPreParse=
False)
5345 except (ParseException, IndexError):
5358 skiptext = instring[startloc:loc]
5362 loc, mat =
self_expr_parse(instring, loc, doActions, callPreParse=
False)
5365 return loc, skipresult
5370 Forward declaration of an expression to be defined later -
5371 used for recursive grammars, such as algebraic infix notation.
5372 When the expression is known, it is assigned to the ``Forward``
5373 variable using the ``'<<'`` operator.
5375 Note: take care when assigning to ``Forward`` not to overlook
5376 precedence of operators.
5378 Specifically, ``'|'`` has a lower precedence than ``'<<'``, so that::
5380 fwd_expr << a | b | c
5382 will actually be evaluated as::
5384 (fwd_expr << a) | b | c
5386 thereby leaving b and c out as parseable alternatives. It is recommended that you
5387 explicitly group the values inserted into the ``Forward``::
5389 fwd_expr << (a | b | c)
5391 Converting to use the ``'<<='`` operator instead will avoid this problem.
5393 See :class:`ParseResults.pprint` for an example of a recursive
5394 parser created using ``Forward``.
5397 def __init__(self, other: typing.Optional[Union[ParserElement, str]] =
None):
5403 if hasattr(self,
"caller_frame"):
5409 return NotImplemented
5416 self.
exprexpr.whiteChars, copy_defaults=self.
exprexpr.copyDefaultWhiteChars
5420 self.ignoreExprs.extend(self.
exprexpr.ignoreExprs)
5426 return NotImplemented
5428 return self << other
5436 not in self.suppress_warnings_
5439 "using '<<' operator with '|' is probably an error, use '<<='",
5453 "Forward defined here but no expression attached later using '<<=' or '<<'",
5464 not in self.suppress_warnings_
5481 "Forward expression was never assigned a value, will not parse any input",
5482 stacklevel=stacklevel,
5509 prev_loc, prev_result = memo[loc, self, doActions]
5514 act_key = (loc, self,
True)
5515 peek_key = (loc, self,
False)
5518 prev_loc, prev_peek = memo[peek_key] = (
5521 instring, loc,
"Forward recursion without base case", self
5525 memo[act_key] = memo[peek_key]
5529 except ParseException:
5533 new_loc, new_peek = prev_loc, prev_peek
5535 if new_loc <= prev_loc:
5539 prev_loc, prev_result = memo[peek_key] = memo[act_key]
5540 del memo[peek_key], memo[act_key]
5549 except ParseException
as e:
5550 memo[peek_key] = memo[act_key] = (new_loc, e)
5552 prev_loc, prev_peek = memo[peek_key] = new_loc, new_peek
5571 "ParserElement.validate() is deprecated, and should not be used to check for left recursion",
5575 if validateTrace
is None:
5578 if self
not in validateTrace:
5579 tmp = validateTrace[:] + [self]
5592 retString = str(self.
exprexpr)[:1000]
5596 return self.__class__.__name__ +
": " + retString
5598 def copy(self) -> ParserElement:
5600 return super().copy()
5610 not in self.suppress_warnings_
5614 "{}: setting results name {!r} on {} expression "
5615 "that has no contained expression".format(
5616 "warn_name_set_on_empty_Forward", name, type(self).__name__
5625 @replaced_by_pep8(leave_whitespace)
5628 @replaced_by_pep8(ignore_whitespace)
5635 Abstract subclass of :class:`ParseExpression`, for converting parsed results.
5638 def __init__(self, expr: Union[ParserElement, str], savelist=
False):
5644 """Converter to concatenate all matching tokens to a single string.
5645 By default, the matching patterns must also be contiguous in the
5646 input string; this can be disabled by specifying
5647 ``'adjacent=False'`` in the constructor.
5651 real = Word(nums) + '.' + Word(nums)
5652 print(real.parse_string('3.1416')) # -> ['3', '.', '1416']
5653 # will also erroneously match the following
5654 print(real.parse_string('3. 1416')) # -> ['3', '.', '1416']
5656 real = Combine(Word(nums) + '.' + Word(nums))
5657 print(real.parse_string('3.1416')) # -> ['3.1416']
5658 # no match when there are internal spaces
5659 print(real.parse_string('3. 1416')) # -> Exception: Expected W:(0123...)
5664 expr: ParserElement,
5665 join_string: str =
"",
5666 adjacent: bool =
True,
5671 joinString = joinString
if joinString
is not None else join_string
5701 """Converter to return the matched tokens as a list - useful for
5702 returning tokens of :class:`ZeroOrMore` and :class:`OneOrMore` expressions.
5704 The optional ``aslist`` argument when set to True will return the
5705 parsed tokens as a Python list instead of a pyparsing ParseResults.
5709 ident = Word(alphas)
5712 func = ident + Opt(DelimitedList(term))
5713 print(func.parse_string("fn a, b, 100"))
5714 # -> ['fn', 'a', 'b', '100']
5716 func = ident + Group(Opt(DelimitedList(term)))
5717 print(func.parse_string("fn a, b, 100"))
5718 # -> ['fn', ['a', 'b', '100']]
5721 def __init__(self, expr: ParserElement, aslist: bool =
False):
5731 else list(tokenlist)
5738 """Converter to return a repetitive expression as a list, but also
5739 as a dictionary. Each element can also be referenced using the first
5740 token in the expression as its key. Useful for tabular report
5741 scraping when the first column can be used as a item key.
5743 The optional ``asdict`` argument when set to True will return the
5744 parsed tokens as a Python dict instead of a pyparsing ParseResults.
5748 data_word = Word(alphas)
5749 label = data_word + FollowedBy(':')
5751 text = "shape: SQUARE posn: upper left color: light blue texture: burlap"
5752 attr_expr = (label + Suppress(':') + OneOrMore(data_word, stop_on=label).set_parse_action(' '.join))
5754 # print attributes as plain groups
5755 print(attr_expr[1, ...].parse_string(text).dump())
5757 # instead of OneOrMore(expr), parse using Dict(Group(expr)[1, ...]) - Dict will auto-assign names
5758 result = Dict(Group(attr_expr)[1, ...]).parse_string(text)
5759 print(result.dump())
5761 # access named fields as dict entries, or output as dict
5762 print(result['shape'])
5763 print(result.as_dict())
5767 ['shape', 'SQUARE', 'posn', 'upper left', 'color', 'light blue', 'texture', 'burlap']
5768 [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']]
5769 - color: 'light blue'
5770 - posn: 'upper left'
5774 {'color': 'light blue', 'posn': 'upper left', 'texture': 'burlap', 'shape': 'SQUARE'}
5776 See more examples at :class:`ParseResults` of accessing fields by results name.
5779 def __init__(self, expr: ParserElement, asdict: bool =
False):
5791 ikey = str(ikey).strip()
5796 elif len(tok) == 2
and not isinstance(tok[1], ParseResults):
5804 "could not extract dict values from parsed results"
5805 " - Dict expression must contain Grouped expressions"
5811 if len(dictvalue) != 1
or (
5821 return [tokenlist]
if self.
resultsName else tokenlist
5825 """Converter for ignoring the results of a parsed expression.
5829 source = "a, b, c,d"
5831 wd_list1 = wd + (',' + wd)[...]
5832 print(wd_list1.parse_string(source))
5834 # often, delimiters that are useful during parsing are just in the
5835 # way afterward - use Suppress to keep them out of the parsed output
5836 wd_list2 = wd + (Suppress(',') + wd)[...]
5837 print(wd_list2.parse_string(source))
5839 # Skipped text (using '...') can be suppressed as well
5840 source = "lead in START relevant text END trailing text"
5841 start_marker = Keyword("START")
5842 end_marker = Keyword("END")
5843 find_body = Suppress(...) + start_marker + ... + end_marker
5844 print(find_body.parse_string(source)
5848 ['a', ',', 'b', ',', 'c', ',', 'd']
5849 ['a', 'b', 'c', 'd']
5850 ['START', 'relevant text ', 'END']
5852 (See also :class:`DelimitedList`.)
5855 def __init__(self, expr: Union[ParserElement, str], savelist: bool =
False):
5875 def suppress(self) -> ParserElement:
5880 """Decorator for debugging parse actions.
5882 When the parse action is called, this decorator will print
5883 ``">> entering method-name(line:<current_source_line>, <parse_location>, <matched_tokens>)"``.
5884 When the parse action completes, the decorator will print
5885 ``"<<"`` followed by the returned value, or any exception that the parse action raised.
5892 def remove_duplicate_chars(tokens):
5893 return ''.join(sorted(set(''.join(tokens))))
5895 wds = wd[1, ...].set_parse_action(remove_duplicate_chars)
5896 print(wds.parse_string("slkdjs sld sldd sdlf sdljf"))
5900 >>entering remove_duplicate_chars(line: 'slkdjs sld sldd sdlf sdljf', 0, (['slkdjs', 'sld', 'sldd', 'sdlf', 'sdljf'], {}))
5901 <<leaving remove_duplicate_chars (ret: 'dfjkls')
5908 s, l, t = paArgs[-3:]
5911 sys.stderr.write(f
">>entering {thisFunc}(line: {line(l, s)!r}, {l}, {t!r})\n")
5914 except Exception
as exc:
5931_escapedPunc =
Regex(
r"\\[\\[\]\/\-\*\.\$\+\^\?()~ ]").set_parse_action(
5932 lambda s, l, t: t[0][1]
5934_escapedHexChar =
Regex(
r"\\0?[xX][0-9a-fA-F]+").set_parse_action(
5935 lambda s, l, t:
chr(int(t[0].
lstrip(
r"\0x"), 16))
5937_escapedOctChar =
Regex(
r"\\0[0-7]+").set_parse_action(
5938 lambda s, l, t:
chr(int(t[0][1:], 8))
5941 _escapedPunc | _escapedHexChar | _escapedOctChar |
CharsNotIn(
r"\]", exact=1)
5946 +
Opt(
"^").set_results_name(
"negate")
5947 +
Group(
OneOrMore(_charRange | _singleChar)).set_results_name(
"body")
5953 r"""Helper to easily define string ranges for use in :class:`Word`
5954 construction. Borrows syntax from regexp ``'[]'`` string range
5957 srange("[0-9]") -> "0123456789"
5958 srange("[a-z]") -> "abcdefghijklmnopqrstuvwxyz"
5959 srange("[a-z$_]") -> "abcdefghijklmnopqrstuvwxyz$_"
5961 The input string must be enclosed in []'s, and the returned string
5962 is the expanded character set joined into a single string. The
5963 values enclosed in the []'s may be:
5965 - a single character
5966 - an escaped character with a leading backslash (such as ``\-``
5968 - an escaped hex character with a leading ``'\x'``
5969 (``\x21``, which is a ``'!'`` character) (``\0x##``
5970 is also supported for backwards compatibility)
5971 - an escaped octal character with a leading ``'\0'``
5972 (``\041``, which is a ``'!'`` character)
5973 - a range of any of the above, separated by a dash (``'a-z'``,
5975 - any combination of the above (``'aeiouy'``,
5976 ``'a-zA-Z0-9_$'``, etc.)
5985 except Exception
as e:
5990 """Helper to define a parse action by mapping a function to all
5991 elements of a :class:`ParseResults` list. If any additional args are passed,
5992 they are forwarded to the given function as additional arguments
5993 after the token, as in
5994 ``hex_integer = Word(hexnums).set_parse_action(token_map(int, 16))``,
5995 which will convert the parsed data to an integer using base 16.
5997 Example (compare the last to example in :class:`ParserElement.transform_string`::
5999 hex_ints = Word(hexnums)[1, ...].set_parse_action(token_map(int, 16))
6000 hex_ints.run_tests('''
6001 00 11 22 aa FF 0a 0d 1a
6004 upperword = Word(alphas).set_parse_action(token_map(str.upper))
6005 upperword[1, ...].run_tests('''
6006 my kingdom for a horse
6009 wd = Word(alphas).set_parse_action(token_map(str.title))
6010 wd[1, ...].set_parse_action(' '.join).run_tests('''
6011 now is the winter of our discontent made glorious summer by this sun of york
6016 00 11 22 aa FF 0a 0d 1a
6017 [0, 17, 34, 170, 255, 10, 13, 26]
6019 my kingdom for a horse
6020 ['MY', 'KINGDOM', 'FOR', 'A', 'HORSE']
6022 now is the winter of our discontent made glorious summer by this sun of york
6023 ['Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York']
6027 return [func(tokn, *args)
for tokn
in t]
6029 func_name =
getattr(func,
"__name__",
getattr(func,
"__class__").__name__)
6037 Utility to simplify mass-naming of parser elements, for
6038 generating railroad diagram with named subdiagrams.
6041 if calling_frame
is None:
6050 Regex(
r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*') +
'"'
6051).set_name(
"string enclosed in double quotes")
6054 Regex(
r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*") +
"'"
6055).set_name(
"string enclosed in single quotes")
6058 (
Regex(
r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*') +
'"').set_name(
6059 "double quoted string"
6061 | (
Regex(
r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*") +
"'").set_name(
6062 "single quoted string"
6064).set_name(
"quoted string using single or double quotes")
6067 (
Regex(
r'"""(?:[^"\\]|""(?!")|"(?!"")|\\.)*', flags=
re.MULTILINE) +
'"""').set_name(
6068 "multiline double quoted string"
6072 ).set_name(
"multiline single quoted string")
6073 ^ (
Regex(
r'"(?:[^"\n\r\\]|(?:\\")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*') +
'"').set_name(
6074 "double quoted string"
6076 ^ (
Regex(
r"'(?:[^'\n\r\\]|(?:\\')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*") +
"'").set_name(
6077 "single quoted string"
6079).set_name(
"Python quoted string")
6084alphas8bit =
srange(
r"[\0xc0-\0xd6\0xd8-\0xf6\0xf8-\0xff]")
6089_builtin_exprs: List[ParserElement] = [
6095sglQuotedString = sgl_quoted_string
6096dblQuotedString = dbl_quoted_string
6097quotedString = quoted_string
6098unicodeString = unicode_string
6099lineStart = line_start
6101stringStart = string_start
6102stringEnd = string_end
6104@replaced_by_pep8(null_debug_action)
6107@replaced_by_pep8(trace_parse_action)
6110@replaced_by_pep8(condition_as_parse_action)
6113@replaced_by_pep8(token_map)
str _generateDefaultName(self)
__init__(self, *args, **kwargs)
parseImpl(self, instring, loc, doActions=True)
str _generateDefaultName(self)
ParserElement streamline(self)
_checkRecursion(self, parseElementList)
__init__(self, typing.Iterable[ParserElement] exprs_arg, bool savelist=True)
parseImpl(self, instring, loc, doActions=True)
__init__(self, Union[ParserElement, str] expr)
parseImpl(self, instring, loc, doActions=True)
__init__(self, Union[ParserElement, str] expr)
__init__(self, str match_string="", typing.Optional[str] ident_chars=None, *str matchString="", typing.Optional[str] identChars=None)
parseImpl(self, instring, loc, doActions=True)
__init__(self, str match_string="", *str matchString="")
__init__(self, str charset, bool as_keyword=False, typing.Optional[str] exclude_chars=None, *bool asKeyword=False, typing.Optional[str] excludeChars=None)
parseImpl(self, instring, loc, doActions=True)
str _generateDefaultName(self)
__init__(self, str not_chars="", int min=1, int max=0, int exact=0, *str notChars="")
parseImpl(self, instring, loc, doActions=True)
str _generateDefaultName(self)
__init__(self, str match_string, typing.Optional[int] max_mismatches=None, *int maxMismatches=1, caseless=False)
ParserElement ignore(self, other)
postParse(self, instring, loc, tokenlist)
__init__(self, ParserElement expr, str join_string="", bool adjacent=True, *typing.Optional[str] joinString=None)
str _generateDefaultName(self)
__init__(self, Union[str, ParserElement] expr, Union[str, ParserElement] delim=",", bool combine=False, typing.Optional[int] min=None, typing.Optional[int] max=None, *bool allow_trailing_delim=False)
postParse(self, instring, loc, tokenlist)
__init__(self, ParserElement expr, bool asdict=False)
parseImpl(self, instring, loc, doActions=True)
str _generateDefaultName(self)
ParserElement streamline(self)
__init__(self, typing.Iterable[ParserElement] exprs, bool savelist=True)
parseImpl(self, instring, loc, doActions=True)
str _generateDefaultName(self)
__init__(self, match_string="", *matchString="")
parseImpl(self, instring, loc, doActions=True)
__init__(self, Union[ParserElement, str] expr)
parseImpl(self, instring, loc, doActions=True)
str _generateDefaultName(self)
ParserElement leave_whitespace(self, bool recursive=True)
"Forward" __lshift__(self, other)
ParserElement streamline(self)
__init__(self, typing.Optional[Union[ParserElement, str]] other=None)
"Forward" __ilshift__(self, other)
ParserElement ignore_whitespace(self, bool recursive=True)
_setResultsName(self, name, list_all_matches=False)
"ParserElement" __or__(self, other)
parseImpl(self, instring, loc, doActions=True)
int preParse(self, str instring, int loc)
__init__(self, int colno)
__init__(self, ParserElement expr, bool aslist=False)
postParse(self, instring, loc, tokenlist)
__init__(self, int ref_col)
__init__(self, int ref_col)
parseImpl(self, instring, loc, doActions=True)
__init__(self, ParserElement expr, *bool recursive=False, bool grouped=True)
parseImpl(self, instring, loc, doActions=True)
str _generateDefaultName(self)
__init__(self, str match_string="", typing.Optional[str] ident_chars=None, bool caseless=False, *str matchString="", typing.Optional[str] identChars=None)
None set_default_keyword_chars(chars)
parseImpl(self, instring, loc, doActions=True)
parseImpl(self, instring, loc, doActions=True)
int preParse(self, str instring, int loc)
parseImpl(self, instring, loc, doActions=True)
str _generateDefaultName(self)
__init__(self, str match_string="", *str matchString="")
__new__(cls, str match_string="", *str matchString="")
parseImpl(self, instring, loc, doActions=True)
parseImpl(self, instring, loc, doActions=True)
str _generateDefaultName(self)
ParserElement streamline(self)
_setResultsName(self, name, listAllMatches=False)
__init__(self, typing.Iterable[ParserElement] exprs, bool savelist=False)
parseImpl(self, instring, loc, doActions=True)
parseImpl(self, instring, loc, doActions=True)
str _generateDefaultName(self)
__init__(self, Union[ParserElement, str] expr)
str _generateDefaultName(self)
parseImpl(self, instring, loc, doActions=True)
str _generateDefaultName(self)
__init__(self, Union[ParserElement, str] expr, Any default=__optionalNotMatched)
parseImpl(self, instring, loc, doActions=True)
str _generateDefaultName(self)
ParserElement streamline(self)
_setResultsName(self, name, listAllMatches=False)
__init__(self, typing.Iterable[ParserElement] exprs, bool savelist=False)
parseImpl(self, instring, loc, doActions=True)
str _generateDefaultName(self)
ParserElement ignore(self, other)
ParserElement leave_whitespace(self, bool recursive=True)
ParserElement streamline(self)
__init__(self, Union[ParserElement, str] expr, bool savelist=False)
_checkRecursion(self, parseElementList)
List[ParserElement] recurse(self)
ParserElement ignore_whitespace(self, bool recursive=True)
str _generateDefaultName(self)
ParserElement ignore(self, other)
ParserElement leave_whitespace(self, bool recursive=True)
ParserElement append(self, other)
ParserElement streamline(self)
_setResultsName(self, name, listAllMatches=False)
__init__(self, typing.Iterable[ParserElement] exprs, bool savelist=False)
List[ParserElement] recurse(self)
ParserElement ignore_whitespace(self, bool recursive=True)
parseImpl(self, instring, loc, doActions=True)
None enable_left_recursion(typing.Optional[int] cache_size_limit=None, *force=False)
"ParserElement" __and__(self, other)
using_each(cls, seq, **class_kwargs)
"ParserElement" __add__(self, other)
None disable_memoization()
str _generateDefaultName(self)
Tuple[int, ParseResults] _parse
ParseResults parse_string(self, str instring, bool parse_all=False, *bool parseAll=False)
"ParserElement" leave_whitespace(self, bool recursive=True)
"ParserElement" __rsub__(self, other)
int _skipIgnorables(self, str instring, int loc)
"ParserElement" add_parse_action(self, *ParseAction fns, **kwargs)
"ParserElement" __call__(self, typing.Optional[str] name=None)
"ParserElement" set_debug(self, bool flag=True, bool recurse=False)
"ParserElement" ignore(self, "ParserElement" other)
"ParserElement" __rand__(self, other)
"ParserElement" __invert__(self)
ParseResults search_string(self, str instring, int max_matches=_MAX_INT, *bool debug=False, int maxMatches=_MAX_INT)
Tuple[int, ParseResults] _parseCache(self, instring, loc, doActions=True, callPreParse=True)
"ParserElement" __mul__(self, other)
_setResultsName(self, name, listAllMatches=False)
ParseResults parse_file(self, Union[str, Path, TextIO] file_or_filename, str encoding="utf-8", bool parse_all=False, *bool parseAll=False)
None inline_literals_using(type cls)
postParse(self, instring, loc, tokenlist)
"ParserElement" __sub__(self, other)
"ParserElement" ignore_whitespace(self, bool recursive=True)
None enable_packrat(int cache_size_limit=128, *bool force=False)
"ParserElement" __xor__(self, other)
"ParserElement" add_condition(self, *ParseCondition fns, **kwargs)
"ParserElement" set_results_name(self, str name, bool list_all_matches=False, *bool listAllMatches=False)
"ParserElement" set_break(self, bool break_flag=True)
"ParserElement" __rmul__(self, other)
int preParse(self, str instring, int loc)
setDefaultWhitespaceChars()
"ParserElement" __rxor__(self, other)
Tuple[int, ParseResults] _parseNoCache(self, instring, loc, doActions=True, callPreParse=True)
__init__(self, bool savelist=False)
"ParserElement" set_name(self, str name)
"ParserElement" streamline(self)
Tuple[bool, List[Tuple[str, Union[ParseResults, Exception]]]] run_tests(self, Union[str, List[str]] tests, bool parse_all=True, typing.Optional[Union["ParserElement", str]] comment="#", bool full_dump=True, bool print_results=True, bool failure_tests=False, typing.Optional[Callable[[str, ParseResults], str]] post_parse=None, typing.Optional[TextIO] file=None, bool with_line_numbers=False, *bool parseAll=True, bool fullDump=True, bool printResults=True, bool failureTests=False, typing.Optional[Callable[[str, ParseResults], str]] postParse=None)
"ParserElement" __radd__(self, other)
_checkRecursion(self, parseElementList)
List["ParserElement"] recurse(self)
bool matches(self, str test_string, bool parse_all=True, *bool parseAll=True)
str transform_string(self, str instring, *bool debug=False)
bool can_parse_next(self, str instring, int loc, bool do_actions=False)
None set_default_whitespace_chars(str chars)
"ParserElement" copy(self)
"ParserElement" set_parse_action(self, *ParseAction fns, **kwargs)
int try_parse(self, str instring, int loc, *bool raise_fatal=False, bool do_actions=False)
"ParserElement" parse_with_tabs(self)
Generator[Tuple[ParseResults, int, int], None, None] scan_string(self, str instring, int max_matches=_MAX_INT, bool overlap=False, *bool debug=False, int maxMatches=_MAX_INT)
"ParserElement" suppress_warning(self, Diagnostics warning_type)
"ParserElement" __ror__(self, other)
None create_diagram(self, Union[TextIO, Path, str] output_html, int vertical=3, bool show_results_names=False, bool show_groups=False, bool embed=False, **kwargs)
"ParserElement" set_whitespace_chars(self, Union[Set[str], str] chars, bool copy_defaults=False)
"ParserElement" set_fail_action(self, ParseFailAction fn)
"ParserElement" set_debug_actions(self, DebugStartAction start_action, DebugSuccessAction success_action, DebugExceptionAction exception_action)
"ParserElement" __or__(self, other)
__init__(self, Union[ParserElement, str] expr, typing.Optional[int] retreat=None)
parseImpl(self, instring, loc=0, doActions=True)
parseImpl(self, instring, loc, doActions=True)
str _generateDefaultName(self)
__init__(self, str quote_char="", typing.Optional[str] esc_char=None, typing.Optional[str] esc_quote=None, bool multiline=False, bool unquote_results=True, typing.Optional[str] end_quote_char=None, bool convert_whitespace_escapes=True, *str quoteChar="", typing.Optional[str] escChar=None, typing.Optional[str] escQuote=None, bool unquoteResults=True, typing.Optional[str] endQuoteChar=None, bool convertWhitespaceEscapes=True)
parseImpl(self, instring, loc, doActions=True)
str _generateDefaultName(self)
parseImplAsMatch(self, instring, loc, doActions=True)
parseImplAsGroupList(self, instring, loc, doActions=True)
__init__(self, Any pattern, Union[re.RegexFlag, int] flags=0, bool as_group_list=False, bool as_match=False, *bool asGroupList=False, bool asMatch=False)
ParserElement sub(self, str repl)
parseImpl(self, instring, loc, doActions=True)
__init__(self, Union[ParserElement, str] other, bool include=False, typing.Optional[Union[ParserElement, str]] ignore=None, typing.Optional[Union[ParserElement, str]] fail_on=None, *typing.Optional[Union[ParserElement, str]] failOn=None)
parseImpl(self, instring, loc, doActions=True)
parseImpl(self, instring, loc, doActions=True)
"ParserElement" __add__(self, other)
postParse(self, instring, loc, tokenlist)
"ParserElement" __sub__(self, other)
__init__(self, Union[ParserElement, str] expr, bool savelist=False)
__init__(self, Union[ParserElement, str] expr, savelist=False)
str _generateDefaultName(self)
parseImpl(self, instring, loc, doActions=True)
str _generateDefaultName(self)
__init__(self, str ws=" \t\r\n", int min=1, int max=0, int exact=0)
parseImpl(self, instring, loc, doActions=True)
__init__(self, str word_chars=printables, *str wordChars=printables)
parseImpl(self, instring, loc, doActions=True)
__init__(self, str word_chars=printables, *str wordChars=printables)
parseImpl(self, instring, loc, doActions=True)
str _generateDefaultName(self)
parseImpl_regex(self, instring, loc, doActions=True)
__init__(self, str init_chars="", typing.Optional[str] body_chars=None, int min=1, int max=0, int exact=0, bool as_keyword=False, typing.Optional[str] exclude_chars=None, *typing.Optional[str] initChars=None, typing.Optional[str] bodyChars=None, bool asKeyword=False, typing.Optional[str] excludeChars=None)
parseImpl(self, instring, loc, doActions=True)
__init__(self, Union[str, ParserElement] expr, typing.Optional[Union[ParserElement, str]] stop_on=None, *typing.Optional[Union[ParserElement, str]] stopOn=None)
str _generateDefaultName(self)
parseImpl(self, instring, loc, doActions=True)
__init__(self, Union[str, ParserElement] expr, typing.Optional[Union[ParserElement, str]] stop_on=None, *typing.Optional[Union[ParserElement, str]] stopOn=None)
_setResultsName(self, name, listAllMatches=False)
ParserElement stopOn(self, ender)
"ParserElement" __add__(self, other)
str _generateDefaultName(self)
__init__(self, ParserElement expr, bool must_skip=False)
parseImpl(self, instring, loc, doActions=True)
__get__(self, instance, owner=None)
_default_exception_debug_action(str instring, int loc, "ParserElement" expr, Exception exc, bool cache_hit=False)
_trim_arity(func, max_limit=3)
_default_success_debug_action(str instring, int startloc, int endloc, "ParserElement" expr, ParseResults toks, bool cache_hit=False)
None enable_all_warnings()
None enable_diag(Diagnostics diag_enum)
ParseAction trace_parse_action(ParseAction f)
None disable_diag(Diagnostics diag_enum)
_default_start_debug_action(str instring, int loc, "ParserElement" expr, bool cache_hit=False)
ParseAction token_map(func, *args)
ParseAction condition_as_parse_action(ParseCondition fn, typing.Optional[str] message=None, bool fatal=False)
bool _should_enable_warnings(typing.Iterable[str] cmd_line_warn_options, typing.Optional[str] warn_env_var)