# -*- coding: utf-8 -*- # module pyparsing.py # # Copyright (c) 2003-2019 Paul T. McGuire # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # __doc__ = \ """ pyparsing module - Classes and methods to define and execute parsing grammars ============================================================================= The pyparsing module is an alternative approach to creating and executing simple grammars, vs. the traditional lex/yacc approach, or the use of regular expressions. With pyparsing, you don't need to learn a new syntax for defining grammars or matching expressions - the parsing module provides a library of classes that you use to construct the grammar directly in Python. Here is a program to parse "Hello, World!" (or any greeting of the form ``"<salutation>, <addressee>!"``), built up using :class:`Word`, :class:`Literal`, and :class:`And` elements (the :class:`'+'<ParserElement.__add__>` operators create :class:`And` expressions, and the strings are auto-converted to :class:`Literal` expressions):: from pip._vendor.pyparsing import Word, alphas # define grammar of a greeting greet = Word(alphas) + "," + Word(alphas) + "!" hello = "Hello, World!" print (hello, "->", greet.parseString(hello)) The program outputs the following:: Hello, World! -> ['Hello', ',', 'World', '!'] The Python representation of the grammar is quite readable, owing to the self-explanatory class names, and the use of '+', '|' and '^' operators. The :class:`ParseResults` object returned from :class:`ParserElement.parseString` can be accessed as a nested list, a dictionary, or an object with named attributes. The pyparsing module handles some of the problems that are typically vexing when writing text parsers: - extra or missing whitespace (the above program will also handle "Hello,World!", "Hello , World !", etc.) - quoted strings - embedded comments Getting Started - ----------------- Visit the classes :class:`ParserElement` and :class:`ParseResults` to see the base classes that most other pyparsing classes inherit from. Use the docstrings for examples of how to: - construct literal match expressions from :class:`Literal` and :class:`CaselessLiteral` classes - construct character word-group expressions using the :class:`Word` class - see how to create repetitive expressions using :class:`ZeroOrMore` and :class:`OneOrMore` classes - use :class:`'+'<And>`, :class:`'|'<MatchFirst>`, :class:`'^'<Or>`, and :class:`'&'<Each>` operators to combine simple expressions into more complex ones - associate names with your parsed results using :class:`ParserElement.setResultsName` - access the parsed data, which is returned as a :class:`ParseResults` object - find some helpful expression short-cuts like :class:`delimitedList` and :class:`oneOf` - find more useful common expressions in the :class:`pyparsing_common` namespace class """ __version__ = "2.4.7" __versionTime__ = "30 Mar 2020 00:43 UTC" __author__ = "Paul McGuire <ptmcg@users.sourceforge.net>" import string from weakref import ref as wkref import copy import sys import warnings import re import sre_constants import collections import pprint import traceback import types from datetime import datetime from operator import itemgetter import itertools from functools import wraps from contextlib import contextmanager try: # Python 3 from itertools import filterfalse except ImportError: from itertools import ifilterfalse as filterfalse try: from _thread import RLock except ImportError: from threading import RLock try: # Python 3 from collections.abc import Iterable from collections.abc import MutableMapping, Mapping except ImportError: # Python 2.7 from collections import Iterable from collections import MutableMapping, Mapping try: from collections import OrderedDict as _OrderedDict except ImportError: try: from ordereddict import OrderedDict as _OrderedDict except ImportError: _OrderedDict = None try: from types import SimpleNamespace except ImportError: class SimpleNamespace: pass # version compatibility configuration __compat__ = SimpleNamespace() __compat__.__doc__ = """ A cross-version compatibility configuration for pyparsing features that will be released in a future version. By setting values in this configuration to True, those features can be enabled in prior versions for compatibility development and testing. - collect_all_And_tokens - flag to enable fix for Issue #63 that fixes erroneous grouping of results names when an And expression is nested within an Or or MatchFirst; set to True to enable bugfix released in pyparsing 2.3.0, or False to preserve pre-2.3.0 handling of named results """ __compat__.collect_all_And_tokens = True __diag__ = SimpleNamespace() __diag__.__doc__ = """ Diagnostic configuration (all default to False) - warn_multiple_tokens_in_named_alternation - flag to enable warnings when a results name is defined on a MatchFirst or Or expression with one or more And subexpressions (only warns if __compat__.collect_all_And_tokens is False) - warn_ungrouped_named_tokens_in_collection - flag to enable warnings when a results name is defined on a containing expression with ungrouped subexpressions that also have results names - warn_name_set_on_empty_Forward - flag to enable warnings whan a Forward is defined with a results name, but has no contents defined - warn_on_multiple_string_args_to_oneof - flag to enable warnings whan oneOf is incorrectly called with multiple str arguments - enable_debug_on_named_expressions - flag to auto-enable debug on all subsequent calls to ParserElement.setName() """ __diag__.warn_multiple_tokens_in_named_alternation = False __diag__.warn_ungrouped_named_tokens_in_collection = False __diag__.warn_name_set_on_empty_Forward = False __diag__.warn_on_multiple_string_args_to_oneof = False __diag__.enable_debug_on_named_expressions = False __diag__._all_names = [nm for nm in vars(__diag__) if nm.startswith("enable_") or nm.startswith("warn_")] def _enable_all_warnings(): __diag__.warn_multiple_tokens_in_named_alternation = True __diag__.warn_ungrouped_named_tokens_in_collection = True __diag__.warn_name_set_on_empty_Forward = True __diag__.warn_on_multiple_string_args_to_oneof = True __diag__.enable_all_warnings = _enable_all_warnings __all__ = ['__version__', '__versionTime__', '__author__', '__compat__', '__diag__', 'And', 'CaselessKeyword', 'CaselessLiteral', 'CharsNotIn', 'Combine', 'Dict', 'Each', 'Empty', 'FollowedBy', 'Forward', 'GoToColumn', 'Group', 'Keyword', 'LineEnd', 'LineStart', 'Literal', 'PrecededBy', 'MatchFirst', 'NoMatch', 'NotAny', 'OneOrMore', 'OnlyOnce', 'Optional', 'Or', 'ParseBaseException', 'ParseElementEnhance', 'Pars