K i  UddlmZddlZddlmZddlZddlZddlmZmZm Z m Z m Z m Z m Z mZddlmZmZddlmZddlZddlZddlZddlZddlZddlmZddlZddlZddlmZdd lmZdd l m!Z!dd l"m#Z#d d l$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z,m-Z.m/Z/d dl0d dl1d dl2m3Z3m4Z4d dl5m6Z6ejnZ8e9e:fZ;deGdde'Z?GddeZ@ddZAddZBddZC[' ddZDeDejejjdreCeHeIeJeKeLeMeNeOePeQeRh ZSejZUeMeVefZWe e3e e3fZXe egeYfee3geYfeeVe3geYfee9eVe3geYffZZee9eVde[gdfZ\ee9eVdeYgdfZ]ee9eVeVde3eYgdfZ^ee9eVde[eYgdfZ_ejejzZbd eexZzGd?d@ezZ{GdAdBezZ|ezev_}GdCdDexZ~GdEdFezZGdGdHe~ZGdIdJexZGdKdLexZGdMdNeZGdOdPexZGdQdRexZGdSdTexZGdUdVexZGdWdXexZGdYdZeZGd[d\eZGd]d^eZGd_d`eZGdadbeZGdcddeZGdedfeZGdgdhexZGdidjevZGdkdleZGdmdneZGdodpeZGdqdreZGdsdtevZGdudveZGdwdxeZGdydzeZGd{d|eZGd}d~eZGddeZGddeZGddeZGddeZGddeZGddeZGddZGddeZeZGddeZGddeZGddeZGddeZGddeZGddeZGddeZddZe{j[dZej[dZej[dZej[dZej[dZedjgdZedjgdZedjgdZeezezedd zZeeedzezZezdedjsdzeeeezjsdzezdzZddZddZddZeeddzj[dZeeddzj[dZeeddzj[deddzj[dzj[dZeedejdzj[dedejdzj[dëz edīdzj[dz edūdzj[dz j[dƫZedej+zj[dȫZedɫZedʫZeƫjDcgc]}e|evs |c}Zde _debug_names classmethodrB)r4r5rAs000r6r8r8gsJ05-05-%*"(-%$)!,1)/4,(-%%xBr}}S/A"BJ'1MtT__V5LdMN%/ST4??>3RDSL CMSs"BBBB)BBr8c0eZdZdZdZdZdZdZdZdZ dZ d Z y ) Diagnosticsa Diagnostic configuration (all default to disabled) - ``warn_multiple_tokens_in_named_alternation`` - flag to enable warnings when a results name is defined on a :class:`MatchFirst` or :class:`Or` expression with one or more :class:`And` subexpressions - ``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 when a :class:`Forward` is defined with a results name, but has no contents defined - ``warn_on_parse_using_empty_Forward`` - flag to enable warnings when a :class:`Forward` is defined in a grammar but has never had an expression attached to it - ``warn_on_assignment_to_Forward`` - flag to enable warnings when a :class:`Forward` is defined but is overwritten by assigning using ``'='`` instead of ``'<<='`` or ``'<<'`` - ``warn_on_multiple_string_args_to_oneof`` - flag to enable warnings when :class:`one_of` is incorrectly called with multiple str arguments - ``enable_debug_on_named_expressions`` - flag to auto-enable debug on all subsequent calls to :class:`ParserElement.set_name` Diagnostics are enabled/disabled by calling :class:`enable_diag` and :class:`disable_diag`. All warnings can be enabled by calling :class:`enable_all_warnings`. rrN) r)r*r+r,rGrHrIrJrKrLrMrNrCr6rRrR}s9.12-01-%&"()%$%!,-)/0,()%rCrRcBtj|jy)zO Enable a global pyparsing diagnostic flag (see :class:`Diagnostics`). N)r8r?rA diag_enums r6 enable_diagr]s OOINN#rCcBtj|jy)zP Disable a global pyparsing diagnostic flag (see :class:`Diagnostics`). N)r8disablerAr[s r6 disable_diagr`s Y^^$rCc,tjy)zU Enable all global pyparsing diagnostic warnings (see :class:`Diagnostics`). N)r8rBrYrCr6rBrBs   "rCc t|}|D]s}|dzjddd\}}}}}|jjds|s|s|r|dk(rd}M|jjdsm|dvsrd}u|S) Nz:::::rVi pyparsingT)reF)boolr2lowerr0) cmd_line_warn_options warn_env_varr?warn_optw_action w_message w_categoryw_modulew_lines r6_should_enable_warningsrqs, F) =E=NO2OF  MrCPYPARSINGENABLEALLWARNINGS ParserElementstralphas identcharsidentbodychars 0123456789nums ABCDEFabcdefhexnums alphanumsrf printablesceZdZdZddZy)_ParseActionIndexErrorz Internal wrapper around IndexError so that IndexErrors raised inside parse actions aren't misinterpreted as IndexErrors raised inside ParserElement parseImpl methods. c ||_||_yr=)msgexc)selfrrs r6__init__z_ParseActionIndexError.__init__s"%rCN)rrtr BaseExceptionrErF)r)r*r+r,rrYrCr6rrs  &rCrztraceback.StackSummary_trim_arity_call_linerYc2tvrfdSddd}txstjddatxstdtd|zfafd }t d t d j }||_j|_|S) zAdecorator to trim function calls to match the arity of the targetc|Sr=rY)sltfuncs r6z_trim_arity..s tAwrCrF rSlimitrcFr | dS  | d}d|S#t$rV}r|j}tj|d}|d}|ddgdddtk(}~|r kr dz Yd}~gd}~wt $r }t d|jdd}~wwxYw)NrTrSrrz!IndexError raised in parse action) TypeError __traceback__ traceback extract_tbpa_call_line_synth IndexErrorrwith_traceback) argsrettetbframes frame_summarytrim_arity_type_errorie found_arityrr max_limits r6wrapperz_trim_arity..wrappers ef& & 'DL)"   ))B&11"A>F$*2JM&r*+B/37II*, 9,!QJE$ ',7 .&' 's'  B A A43A44 B BB r) __class__)_single_arg_builtinsrr extract_stackrgetattrr)r,)rr LINE_DIFFr func_namerrs`` @@r6 _trim_arityrs ##&& EK I2YY5L5LST5UVX5Y+o0Ea0HJ_`aJbenJn/o 'Jj'$ *D*M*MNI GllGO NrCct||nd|rtntttfd}|S)ad Function to convert a simple predicate function that returns ``True`` or ``False`` into a parse action. Can be used in places when a parse action is required and :meth:`ParserElement.add_condition` cannot be used (such as when adding a condition to an operator level in :class:`infix_notation`). Optional keyword arguments: :param message: define a custom message to be used in the raised exception :param fatal: if ``True``, will raise :class:`ParseFatalException` to stop parsing immediately; otherwise will raise :class:`ParseException` zfailed user-defined conditionc@t|||s ||yr=)rg)rrrexc_typefnrs r6paz%condition_as_parse_action..paVs'Bq!QK 1a% %!rC)ParseFatalExceptionParseExceptionrr)rmessagefatalrrrs` @@r6condition_as_parse_actionrAsB"('.MC&+"H RB 2Y&& IrCc|rdnd}t|d|d|dt||dt||dt||dd d t||d y) NrrfMatch z at loc (,z) z ^>)printlinenocolline)instringlocexpr cache_hit cache_hit_strs r6_default_start_debug_actionr^s{%C"M oVD6#asH8M7NaPSTWYaPbOcdc8$%&Qs3)* *+ -rCcR|rdnd}t|d|d|jy)NrrfzMatched z -> )ras_list)rstartlocendlocrtoksrrs r6_default_success_debug_actionrks-%C"M ]O8D6dlln-= >?rCc b|rdnd}t|d|dt|jd|y)Nrrfrz failed, z raised: )rtyper))rrrrrrs r6_default_exception_debug_actionrws7%C"M ]O6$yc1C1C0DIcU STrCcy)zG'Do-nothing' debug action, to suppress debugging output during parsing.NrY)rs r6null_debug_actionrrCceZdZUdZdZded<dZded<dZd ed <edd Z edd Z e d Z Gdde ZdddZedZej$dZddZdZddZ ddd ddZdddZdddZddZddZddZddZddZdd Zddd!Zd"Z d dd#Z!ddd$ dd%Z"ddd&Z#e$Z%iZ&d'ed(<Gd)d*e'jPZ)Gd+d,e*Z+e+Z,d*ed-<e$Z-d.d.gZ. d dd/Z/e!Z0edd0Z1dZ2dZ3edd1Z4e ddd2 dd3Z5e ddd2 dd4Z6 ddd5 dd6Z7e8ddfde8d7 dd8Z9dd9dd:Z:e8fde8d7 dd;Z;e8dfdd< dd=Z
Z=dd?Z>dd@Z?ddAZ@ddBZAddCZBddDZCddEZDddFZEddGZFddHZGddIZHddJZIdZJdKZKdddLZLddMZMdddNZNdddOZO d ddPZPddQZQddRZR ddSZSdddTZTeddUZUeVddVZWddWZXeddXZYeYj$ddYZYddZZZdd[Z[dd\Z\dd]Z]d^Z^ddd_Z_ ddd5 dd`Z`daZadbZb ddd5 ddcZc dddddddd ddeZd d ddfZeeefdge Zgeefdhe Zheefdie4Zieefdje5Zjeefdke6Zkeefdle1ZlefdmeZmefdneZnefdoeZoefdpeZpefdqeZqefdreZrefdse"Zsefdte7Ztefdue9Zuefdve:Zvefdwe;ZwefdxeNZxefdyeOZyefdzePZzefd{eQZ{efd|eSZ|efd}eTZ}efd~eXZ~efde`ZefdedZefde#ZeUZy)rsz)Abstract base level parser element class.z rtDEFAULT_WHITE_CHARSFrgverbose_stacktraceNr_literalStringClasscj|t_tD]}|jst ||_!y)a| Overrides the default whitespace chars Example: .. doctest:: # default whitespace chars are space, and newline >>> Word(alphas)[1, ...].parse_string("abc def\nghi jkl") ParseResults(['abc', 'def', 'ghi', 'jkl'], {}) # change to just treat newline as significant >>> ParserElement.set_default_whitespace_chars(" \t") >>> Word(alphas)[1, ...].parse_string("abc def\nghi jkl") ParseResults(['abc', 'def'], {}) # Reset to default >>> ParserElement.set_default_whitespace_chars(" \n\t\r") N)rsr_builtin_exprscopyDefaultWhiteCharsset whiteChars)charsrs r6set_default_whitespace_charsz*ParserElement.set_default_whitespace_charss1*-2 )# -D))"%e* -rCc|t_y)aR Set class to be used for inclusion of string literals into a parser. Example: .. doctest:: :options: +NORMALIZE_WHITESPACE # default literal class used is Literal >>> integer = Word(nums) >>> date_str = ( ... integer("year") + '/' ... + integer("month") + '/' ... + integer("day") ... ) >>> date_str.parse_string("1999/12/31") ParseResults(['1999', '/', '12', '/', '31'], {'year': '1999', 'month': '12', 'day': '31'}) # change to Suppress >>> ParserElement.inline_literals_using(Suppress) >>> date_str = ( ... integer("year") + '/' ... + integer("month") + '/' ... + integer("day") ... ) >>> date_str.parse_string("1999/12/31") ParseResults(['1999', '12', '31'], {'year': '1999', 'month': '12', 'day': '31'}) # Reset >>> ParserElement.inline_literals_using(Literal) N)rsr)r@s r6inline_literals_usingz#ParserElement.inline_literals_usings J-0 )rCc+<Kfd|DEd{y7w)z Yields a sequence of ``class(obj, **class_kwargs)`` for obj in seq. Example: .. testcode:: LPAR, RPAR, LBRACE, RBRACE, SEMI = Suppress.using_each("(){};") .. versionadded:: 3.1.0 c30K|] }|fiywr=rY)r4obj class_kwargsr@s r6 z+ParserElement.using_each..s<C,|,>> label = pp.Word(pp.alphas) # Normally using an empty Forward in a grammar # would print a warning, but we can suppress that >>> base = pp.Forward().suppress_warning( ... pp.Diagnostics.warn_on_parse_using_empty_Forward) >>> grammar = base | label >>> print(grammar.parse_string("x")) ['x'] )rappend)r warning_types r6suppress_warningzParserElement.suppress_warning s& &&|4 rCc#Kt|g}t}|rM|j}||vr|j||j |j ||rLyyw)zGeneral-purpose method to yield all expressions and sub-expressions in a grammar. Typically just for internal use. N)rrpopleftaddextendrecurse)rto_visitseencurs r6 visit_allzParserElement.visit_alls^$=u""$Cd{ HHSM OOCKKM *Is A$A)'A)ctj|}|jdd|_|jdd|_|jrt t j |_|S)a Make a copy of this :class:`ParserElement`. Useful for defining different parse actions for the same parsing pattern, using copies of the original parse element. Example: .. testcode:: integer = Word(nums).set_parse_action( lambda toks: int(toks[0])) integerK = integer.copy().add_parse_action( lambda toks: toks[0] * 1024) + Suppress("K") integerM = integer.copy().add_parse_action( lambda toks: toks[0] * 1024 * 1024) + Suppress("M") print( (integerK | integerM | integer)[1, ...].parse_string( "5K 100 640K 256M") ) prints: .. testoutput:: [5120, 100, 655360, 268435456] Equivalent form of ``expr.copy()`` is just ``expr()``: .. testcode:: integerM = integer().add_parse_action( lambda toks: toks[0] * 1024 * 1024) + Suppress("M") N)copyrrrrrsrr)rcpys r6rzParserElement.copy0sVFiio**1-**1-  % % !B!BCCN rC)listAllMatchesc2|xs|}|j||S)a  Define name for referencing matching tokens as a nested attribute of the returned parse results. Normally, results names are assigned as you would assign keys in a dict: any existing value is overwritten by later values. If it is necessary to keep all values captured for a particular results name, call ``set_results_name`` with ``list_all_matches`` = True. NOTE: ``set_results_name`` returns a *copy* of the original :class:`ParserElement` object; this is so that the client can define a basic element, such as an integer, and reference it in multiple places with different names. You can also set results names using the abbreviated syntax, ``expr("name")`` in place of ``expr.set_results_name("name")`` - see :meth:`__call__`. If ``list_all_matches`` is required, use ``expr("name*")``. Example: .. testcode:: integer = Word(nums) date_str = (integer.set_results_name("year") + '/' + integer.set_results_name("month") + '/' + integer.set_results_name("day")) # equivalent form: date_str = integer("year") + '/' + integer("month") + '/' + integer("day") )_setResultsName)rrAlist_all_matchesrs r6set_results_namezParserElement.set_results_nameZs#B(;+;##D.99rCc|||S|j}|jdr|dd}d}||_| |_|S)NrrT)rendswithrr)rrArnewselfs r6rzParserElement._setResultsName~sL <K))+ == 9D# "#33rCTc|r"|jdfd }|_||_|St|jdr|jj|_|S)z Method to invoke the Python pdb debugger when this element is about to be parsed. Set ``break_flag`` to ``True`` to enable, ``False`` to disable. c.t||||Sr=) breakpoint)rr do_actions callPreParse _parseMethods r6breakerz(ParserElement.set_break..breakers #Hc:|LLrC_originalParseMethodTT)_parser+hasattr)r break_flagr*r)s @r6 set_breakzParserElement.set_breaksV ;;L M ,8G (!DK T[["8 9++::DK rCc:t|dgk(r|jj|Std|Ds t d|Dcgc] }t |c}|jdd|j d|j dd|_|Scc}w)a Define one or more actions to perform when successfully matching parse element definition. Parse actions can be called to perform data conversions, do extra validation, update external data structures, or enhance or replace the parsed tokens. Each parse action ``fn`` is a callable method with 0-3 arguments, called as ``fn(s, loc, toks)`` , ``fn(loc, toks)`` , ``fn(toks)`` , or just ``fn()`` , where: - ``s`` = the original string being parsed (see note below) - ``loc`` = the location of the matching substring - ``toks`` = a list of the matched tokens, packaged as a :class:`ParseResults` object The parsed tokens are passed to the parse action as ParseResults. They can be modified in place using list-style append, extend, and pop operations to update the parsed list elements; and with dictionary-style item set and del operations to add, update, or remove any named results. If the tokens are modified in place, it is not necessary to return them with a return statement. Parse actions can also completely replace the given tokens, with another ``ParseResults`` object, or with some entirely different object (common for parse actions that perform data conversions). A convenient way to build a new parse result is to define the values using a dict, and then create the return value using :class:`ParseResults.from_dict`. If None is passed as the ``fn`` parse action, all previously added parse actions for this expression are cleared. Optional keyword arguments: :param call_during_try: (default= ``False``) indicate if parse action should be run during lookaheads and alternate testing. For parse actions that have side effects, it is important to only call the parse action once it is determined that it is being called as part of a successful parse. For parse actions that perform additional validation, then ``call_during_try`` should be passed as True, so that the validation code is included in the preliminary "try" parses. .. Note:: The default parsing behavior is to expand tabs in the input string before starting the parsing process. See :meth:`parse_string` for more information on parsing strings containing ```` s, and suggested methods to maintain a consistent view of the parsed string, the parse location, and line and column positions within the parsed string. Example: Parse dates in the form ``YYYY/MM/DD`` ----------------------------------------------- Setup code: .. testcode:: def convert_to_int(toks): '''a parse action to convert toks from str to int at parse time''' return int(toks[0]) def is_valid_date(instring, loc, toks): '''a parse action to verify that the date is a valid date''' from datetime import date year, month, day = toks[::2] try: date(year, month, day) except ValueError: raise ParseException(instring, loc, "invalid date given") integer = Word(nums) date_str = integer + '/' + integer + '/' + integer # add parse actions integer.set_parse_action(convert_to_int) date_str.set_parse_action(is_valid_date) Successful parse - note that integer fields are converted to ints: .. testcode:: print(date_str.parse_string("1999/12/31")) prints: .. testoutput:: [1999, '/', 12, '/', 31] Failure - invalid date: .. testcode:: date_str.parse_string("1999/13/31") prints: .. testoutput:: Traceback (most recent call last): ParseException: invalid date given, found '1999' ... Nc32K|]}t|ywr=)callable)r4rs r6rz1ParserElement.set_parse_action..s.B8B<.zparse actions must be callablecall_during_tryrF)rrclearallrrgetrrfnskwargsrs r6set_parse_actionzParserElement.set_parse_actionsJ 9     " " $K.#..<= =9<=2{2=#ZZ vzz/5A  >s Bc|xj|Dcgc] }t|c}z c_|jxs"|jd|jdd|_|Scc}w)z Add one or more parse actions to expression's list of parse actions. See :class:`set_parse_action`. See examples in :class:`copy`. r5rF)rrrr8r9s r6add_parse_actionzParserElement.add_parse_actions^ s;[_;;!// 6:: vzz/5A4  >> integer = Word(nums).set_parse_action(lambda toks: int(toks[0])) >>> year_int = integer.copy().add_condition( ... lambda toks: toks[0] >= 2000, ... message="Only support years 2000 and later") >>> date_str = year_int + '/' + integer + '/' + integer >>> result = date_str.parse_string("1999/12/31") Traceback (most recent call last): ParseException: Only support years 2000 and later... rrF)rrr5r)rr rrtr8rgrr9s r6 add_conditionzParserElement.add_conditions8 B    # #) 9 56vzz'59:  "// 6:: vzz/5A4  rCc||_|S)a Define action to perform if parsing fails at this expression. Fail acton fn is a callable function that takes the arguments ``fn(s, loc, expr, err)`` where: - ``s`` = string being parsed - ``loc`` = location where expression match was attempted and failed - ``expr`` = the parse expression that failed - ``err`` = the exception thrown The function returns no value. It may throw :class:`ParseFatalException` if it is desired to stop parsing immediately.)r)rrs r6set_fail_actionzParserElement.set_fail_actionEs rCc|js|Sd}|jDcgc]}|j}}|}|r&d}|D]} |||\}}d}||k(r |S|}|r&|Scc}w#t$rY4wxYwNTF)rr-r) rrr exprsFoundeignore_expr_fnslast_loc ignore_fndummys r6_skipIgnorableszParserElement._skipIgnorablesUsJ -1-=-=>188>>J,  %.x%= U%)  h H ?&sA A%% A10A1c|jr|j||}|jr5t|}|j}||kr|||vr|dz }||kr|||vr|SNr)rrKrlenr)rrrinstrlen white_charss r6preParsezParserElement.preParsejsn   &&x5C   8}H//K.Xc]k%Aq.Xc]k%A rCc |gfSr=rYrrrr's r6 parseImplzParserElement.parseImplv BwrCc|Sr=rYrrr tokenlists r6 postParsezParserElement.postParseysrCc |j}t|}|s |jr |r|jr|j ||}n|}|}|j j r|j j |||d|js||k\r |j|||\}} n|j|||\}} nd|r|jr|j ||}n|}|}|js||k\r |j|||\}} n|j|||\}} |j||| } t| |j |j"|j$} |j&r|s |j(r|rk |j&D]Z} | ||| } | | | ust| |j |j"xrt+| tt,f|j$} \ni|j&D]Z} | ||| } | | | ust| |j |j"xrt+| tt,f|j$} \|r6|j j.r |j j/||||| d|| fS#t$rt|||j|wxYw#t$r[} |j jr|j j||| d|jr|j||| d} ~ wwxYw#t$rt|||j|wxYw#t$r} td}|| d} ~ wwxYw#t$r;} |j jr|j j|||| dd} ~ wwxYw#t$r} td}|| d} ~ wwxYw)NF)asListmodalz exception raised in parse action)rrNrrrQrrrrTrrr ExceptionrrYr rrrrr isinstancerr)rrrr'r( debugging len_instringpre_loc tokens_starttokenserr ret_tokensrparse_action_excrs r6 _parseNoCachezParserElement._parseNoCache}sJJ 8}  D$5$5"mmHc:G!G& $$..%%//,eT%%L)@X&*nnXw &S V#'..7J"OKC 1 1--#6"L!!W %<T"&..7J"OKC#nnXw K V#v6! D$$T__DDUDU    t/A/A"..<%', %KF "-& 2J)5 & $ 0 0'+(M$.v d7K$L&*&7&7 *J.**B8!#HlJ!G )fJ.F%1" ,,#'??$I *6L$3G H"&"3"3 &    ,,!!--lCz5Ja&X,X|T[[RVWWX $$//%%00 ,c5??OOHlD#F $"T(<dSST *<"01S"TC"%+;;<!((33))44$lD#u &8,-OP!'778sA*J5J(J57LM  MM M #AM ; N'"J22J55 L>ALL"L> M MMM N$)6NN$' O0N>>O) raise_fatalr'c |j|||dS#t$r|rt|||j|wxYw)Nr'r)r-rrr)rrrrhr's r6 try_parsezParserElement.try_parsesN C;;x;DQG G" C 3 TB B Cs%>cX |j|||y#ttf$rYywxYw)NrjTF)rkrrrSs r6can_parse_nextzParserElement.can_parse_nexts7  NN8SZN @ +  s ))zecollections.abc.MutableMapping[tuple[int, Forward, bool], tuple[int, Union[ParseResults, Exception]]]recursion_memosc4eZdZUdZded<ddZd dZd dZy) ParserElement._CacheTypezm Class to be used for packrat and left-recursion cacheing of results and exceptions. rg not_in_cachecyr=rYrrs r6r8zParserElement._CacheType.getrrCcyr=rYrss r6rzParserElement._CacheType.set rrCcyr=rYrs r6r6zParserElement._CacheType.clear rrCNrEz typing.AnyrD)r)r*r+r,rr8rr6rYrCr6 _CacheTyperps /)$rCrwc8eZdZUdZdZded<d dZd dZd dZy) ParserElement.NullCachez A null cache type for initialization of the packrat_cache class variable. If/when enable_packrat() is called, this null cache will be replaced by a proper _CacheType class instance. Trgrqcyr=rYrss r6r8zParserElement.NullCache.getrrCcyr=rYrss r6rzParserElement.NullCache.setrrCcyr=rYrs r6r6zParserElement.NullCache.clearrrCNrvrD) r)r*r+r,rqrr8rr6rYrCr6 NullCachery s " d!/)$rCr} packrat_cacherc d\}}|||||f}tj5tj}|j|} | |jurdtj |xxdz cc< |j ||||} |j|| d| dj|f| cdddStj |xxdz cc<|jr6|jjr |jj|||dt!| t"rG|jr9|jj$r# |jj%|||| d| | t't(t*t,t*f| } | d| dj| d} } } |jr8|jj.r" |jj/|| | || d| | fcdddS#t$r/} |j|| j| jd} ~ wwxYw#t$rY.wxYw#t$rY| wxYw#t$rYswxYw#1swYyxYw)N)rrrrT)rrS)rspackrat_cache_lockr~r8rqpackrat_cache_statsrgrrParseBaseExceptionrrrrrrr^r]rr tupleintr r)rrrr'r(HITMISSlookupcacher peloc_resultrs r6 _parseCachezParserElement._parseCache$sa T#|Z@  - -) $!//EIIf%E***11$71<7! ..xj,WE IIfuQxq#&FG ) $) $11#6!;6::$"3"3"="=))33Hc4SW3XeY/zzd&7&7&B&B! --88 (#tUd9  K%KU3 c#9:EB',Qxq%(ff::$"3"3"?"?))55$dFD&D6 V|S) $) $*IIflbllBGG&<=% )! K!%M) $) $sA I)G5=*I1=I/H02I I!A%I!I(I5 H->*H((H--I0 H=9I<H==I I  I I  I IIIII(c"tj5tjjdgt tj ztj ddtj jdddy#1swYyxYwNr)rsrr~r6rNrrnrYrCr6 reset_cachezParserElement.reset_cacheVsm  - - 2  ' ' - - /45311:4M - -a 0  ) ) / / 1  2 2 2s A+BBctj5tjdt_dt_tj t_dddy#1swYyxYw)a$ Disables active Packrat or Left Recursion parsing and their memoization This method also works if neither Packrat nor Left Recursion are enabled. This makes it safe to call before activating Packrat nor Left Recursion to clear any previous settings. FN)rsrr_left_recursion_enabled_packratEnabledrgr-rYrCr6disable_memoizationz!ParserElement.disable_memoizationcsL - - ?  % % '49M 1,1M )#0#>#>M  ? ? ?s AAA')forcecFtj5|rtjntjr t d|t t_n)|dkDrt|t_ntd|dt_ dddy#1swYyxYw)a Enables "bounded recursion" parsing, which allows for both direct and indirect left-recursion. During parsing, left-recursive :class:`Forward` elements are repeatedly matched with a fixed recursion depth that is gradually increased until finding the longest match. Example: .. testcode:: import pyparsing as pp pp.ParserElement.enable_left_recursion() E = pp.Forward("E") num = pp.Word(pp.nums) # match `num`, or `num '+' num`, or `num '+' num '+' num`, ... E <<= E + '+' - num | num print(E.parse_string("1+2+3+4")) prints: .. testoutput:: ['1', '+', '2', '+', '3', '+', '4'] Recursion search naturally memoizes matches of ``Forward`` elements and may thus skip reevaluation of parse actions during backtracking. This may break programs with parse actions which rely on strict ordering of side-effects. Parameters: - ``cache_size_limit`` - (default=``None``) - memoize at most this many ``Forward`` elements during matching; if ``None`` (the default), memoize all ``Forward`` elements. Bounded Recursion parsing works similar but not identical to Packrat parsing, thus the two cannot be used together. Use ``force=True`` to disable any previous, conflicting settings. 0Packrat and Bounded Recursion are not compatibleNr)capacityz Memo size of T) rsrrr RuntimeError_UnboundedMemorn_LRUMemoNotImplementedErrorrcache_size_limitrs r6enable_left_recursionz#ParserElement.enable_left_recursionrsZ - - 9113.."#UVV'0>0@ -!A%08BR0S -)M:J9K*LMM48M 1 9 9 9s A=BB ctj5|rtjntjr t dtj r dddydt_|t t_nt|t_tjt_ dddy#1swYyxYw)a Enables "packrat" parsing, which adds memoizing to the parsing logic. Repeated parse attempts at the same string location (which happens often in many complex grammars) can immediately return a cached value, instead of re-executing parsing/validating code. Memoizing is done of both valid results and parsing exceptions. Parameters: - ``cache_size_limit`` - (default= ``128``) - if an integer value is provided will limit the size of the packrat cache; if None is passed, then the cache size will be unbounded; if 0 is passed, the cache will be effectively disabled. This speedup may break existing programs that use parse actions that have side-effects. For this reason, packrat parsing is disabled when you first import pyparsing. To activate the packrat feature, your program must call the class method :class:`ParserElement.enable_packrat`. For best results, call ``enable_packrat()`` immediately after importing pyparsing. .. Can't really be doctested, alas Example:: import pyparsing pyparsing.ParserElement.enable_packrat() Packrat parsing works similar but not identical to Bounded Recursion parsing, thus the two cannot be used together. Use ``force=True`` to disable any previous, conflicting settings. rNT) rsrrrrrrr~rrr-rs r6enable_packratzParserElement.enable_packratsH - - =11366"#UVV,, = =-1M )'.=.? +.89I.J +#0#<#)parseAllcB|xs|}tj|js|j|jD]}|j|j s|j } |j|d\}}|rH|j||}ttjdz}|j|||S#t$r}|jd}~wt$r'} tjr| j!dd} ~ wwxYw)aL Parse a string with respect to the parser definition. This function is intended as the primary interface to the client code. :param instring: The input string to be parsed. :param parse_all: If set, the entire input string must match the grammar. :param parseAll: retained for pre-PEP8 compatibility, will be removed in a future release. :raises ParseException: Raised if ``parse_all`` is set and the input string does not match the whole grammar. :returns: the parsed data as a :class:`ParseResults` object, which may be accessed as a `list`, a `dict`, or an object with attributes if the given parser includes results names. If the input string is required to match the entire grammar, ``parse_all`` flag must be set to ``True``. This is also equivalent to ending the grammar with :class:`StringEnd`\ (). To report proper column numbers, ``parse_string`` operates on a copy of the input string where all tabs are converted to spaces (8 spaces per tab, as per the default in ``string.expandtabs``). If the input string contains tabs and the grammar uses parse actions that use the ``loc`` argument to index into the string being parsed, one can ensure a consistent view of the input string by doing one of the following: - calling ``parse_with_tabs`` on your grammar before calling ``parse_string`` (see :class:`parse_with_tabs`), - define your parse action using the full ``(s,loc,toks)`` signature, and reference the input string using the parse action's ``s`` argument, or - explicitly expand the tabs in your input string before calling ``parse_string``. Examples: By default, partial matches are OK. .. doctest:: >>> res = Word('a').parse_string('aaaaabaaa') >>> print(res) ['aaaaa'] The parsing behavior varies by the inheriting class of this abstract class. Please refer to the children directly to see more examples. It raises an exception if parse_all flag is set and instring does not match the whole grammar. .. doctest:: >>> res = Word('a').parse_string('aaaaabaaa', parse_all=True) Traceback (most recent call last): ParseException: Expected end of text, found 'b' ... rFN)rsrr streamlinerr expandtabsr-rQEmpty StringEnd set_debugrrrrr) rr parse_allrrFrrcsepa_excrs r6 parse_stringzParserElement.parse_strings`(!!# OO !! A LLN }}**,H ++h2KCmmHc2Wy{44U;; (C(M& ** ! +//$$T* *  +s%5AC D C++ D7"DD)r maxMatchesc#hKt||}|js|j|jD]}|j|jst |j }t|}d} |r9t} |j| _|j| _ | j} n |j} |j} tjd} | |kr}| |krw | || }| ||d\}}|| kDrG| dz } |rt|j||d|||f|r| || }|| kDr|} n| dz } n |} n|dz} | |kr| |kruyyyy#t $rdz} YwxYw#t"$r'}tj$r|j'dd}~wwxYww)a Scan the input string for expression matches. Each match will return the matching tokens, start location, and end location. May be called with optional ``max_matches`` argument, to clip scanning after 'n' matches are found. If ``overlap`` is specified, then overlapping matches will be reported. Note that the start and end locations are reported relative to the string being parsed. See :class:`parse_string` for more information on parsing strings with embedded tabs. Example: .. testcode:: source = "sldjf123lsdjjkf345sldkjf879lkjsfd987" print(source) for tokens, start, end in Word(alphas).scan_string(source): print(' '*start + '^'*(end-start)) print(' '*start + tokens[0]) prints: .. testoutput:: sldjf123lsdjjkf345sldkjf879lkjsfd987 ^^^^^ sldjf ^^^^^^^ lsdjjkf ^^^^^^ sldkjf ^^^^^^ lkjsfd rFr(r)rcstartendN)minrrrrrtrrNrrrQr-rs resetCacherr[rrrr)rr max_matchesoverlapalways_skip_whitespacerrrFrOr preparser preparseFnparseFnmatchesprelocnextLocrcnextlocrs r6 scan_stringzParserElement.scan_string*sX[1  OO !! A LLN }}8}//1Hx= !I$($4$4I !#'??I "++JJ++  "$ +/g &:)",Xs";F'.hU&SOGV}1  !.4mmo-3+2!"%fg55"&03&?G&}&- #q")C$qj;/g &:/&:/ &% 1*C%0" +//$$T* *  +sOC%F2( E?3E+ AE?'F2+E<9E?;E<<E?? F/"F**F//F2rcg}d}d|_ |j||D]\}}}||kDr|j||||}|s%t|tr||j z }It|t r"t|ts|j|{|j||j||d|Dcgc]}|s| }}djt|Dcgc] }t|c}Scc}wcc}w#t$r'} tjr| jdd} ~ wwxYw)a Extension to :class:`scan_string`, to modify matching text with modified tokens that may be returned from a parse action. To use ``transform_string``, define a grammar and attach a parse action to it that modifies the returned token list. Invoking ``transform_string()`` on a target string will then scan for matches, and replace the matched text patterns according to the logic in the parse action. ``transform_string()`` returns the resulting transformed string. Example: .. testcode:: quote = '''now is the winter of our discontent, made glorious summer by this sun of york.''' wd = Word(alphas) wd.set_parse_action(lambda toks: toks[0].title()) print(wd.transform_string(quote)) prints: .. testoutput:: Now Is The Winter Of Our Discontent, Made Glorious Summer By This Sun Of York. rTrNrf)rrr r^r rrr#rjoinrrtrrsrr) rrroutlastErrrFors r6transform_stringzParserElement.transform_strings,8  +++HE+B "1au9JJxa01a.199;&C8,Z85LJJqMJJqM " JJx' (!'Q1'C'77HSM:qCF:; ;(:! +//$$T* *  +s<B9DDDD,D >D D D?"D::D?c t||} t|j||d|Dcgc]\}}}| c}}}Scc}}}w#t$r'}tj r|j dd}~wwxYw)a Another extension to :class:`scan_string`, simplifying the access to the tokens found to match the given parse expression. May be called with optional ``max_matches`` argument, to clip searching after 'n' matches are found. Example: .. testcode:: quote = '''More than Iron, more than Lead, more than Gold I need Electricity''' # a capitalized word starts with an uppercase letter, # followed by zero or more lowercase letters cap_word = Word(alphas.upper(), alphas.lower()) print(cap_word.search_string(quote)) # the sum() builtin can be used to merge results # into a single ParseResults object print(sum(cap_word.search_string(quote))) prints: .. testoutput:: [['More'], ['Iron'], ['Lead'], ['Gold'], ['I'], ['Electricity']] ['More', 'Iron', 'Lead', 'Gold', 'I', 'Electricity'] F)rrN)rr rrrsrr) rrrrrrrrFrs r6 search_stringzParserElement.search_stringsJ[1  +$(#3#3 *URW$4$1a " +//$$T* *  +s'A A A A A9"A44A9)includeSeparatorsc#K|xs|}d}|j||D]\}}}||||r|d|}||dyw)a Generator method to split a string using the given expression as a separator. May be called with optional ``maxsplit`` argument, to limit the number of splits; and the optional ``include_separators`` argument (default= ``False``), if the separating matching text should be included in the split results. Example: .. testcode:: punc = one_of(list(".,;:/-!?")) print(list(punc.split( "This, this?, this sentence, is badly punctuated!"))) prints: .. testoutput:: ['This', ' this', '', ' this sentence', ' is badly punctuated', ''] r)rN)r) rrmaxsplitinclude_separatorsrlastrrrFs r6r2zParserElement.splitsj8.C1C''h'G GAq!4" " d D   tuos?Ac|tur t|St|tr|j |}t|t st St||gS)a Implementation of ``+`` operator - returns :class:`And`. Adding strings to a :class:`ParserElement` converts them to :class:`Literal`\ s by default. Example: .. testcode:: greet = Word(alphas) + "," + Word(alphas) + "!" hello = "Hello, World!" print(hello, "->", greet.parse_string(hello)) prints: .. testoutput:: Hello, World! -> ['Hello', ',', 'World', '!'] ``...`` may be used as a parse expression as a short form of :class:`SkipTo`: .. testcode:: Literal('start') + ... + Literal('end') is equivalent to: .. testcode:: Literal('start') + SkipTo('end')("_skipped*") + Literal('end') Note that the skipped text is returned with '_skipped' as a results name, and to support having multiple skips in the same parser, the value returned is a list of all skipped text. )Ellipsis _PendingSkipr^r#rrsNotImplementedAndrothers r6__add__zParserElement.__add__&sQF H % % eX &,,U3E%/! !D%=!!rCc|turt|d|zSt|tr|j |}t|t st S||zS)zd Implementation of ``+`` operator when left operand is not a :class:`ParserElement` _skipped*)rSkipTor^r#rrsrrs r6__radd__zParserElement.__radd__RsV H 6$< ,t3 3 eX &,,U3E%/! !t|rCct|tr|j|}t|tstS|t j z|zS)zX Implementation of ``-`` operator, returns :class:`And` with error stop )r^r#rrsrr _ErrorStoprs r6__sub__zParserElement.__sub___sE eX &,,U3E%/! !cnn&&..rCczt|tr|j|}t|tstS||z S)zd Implementation of ``-`` operator when left operand is not a :class:`ParserElement` r^r#rrsrrs r6__rsub__zParserElement.__rsub__i8 eX &,,U3E%/! !t|rCcT|turd}n+t|tr|ddtfk(rd|ddzdzdd}t|ttfstSt|tr|d}}ntd|D}|d zdd}|dd|df}t|dtr?|d:|ddk(r t S|ddk(r t S|dzt zSt|dtrt|dtr |\}}||z}ntS|dkr td |dkr td ||cxk(rdk(r tgS|r>fd |r,|dk(r |z}|Stg|z|z}|S|}|S|dk(r}|Stg|z}|S) a Implementation of ``*`` operator, allows use of ``expr * 3`` in place of ``expr + expr + expr``. Expressions may also be multiplied by a 2-integer tuple, similar to ``{min, max}`` multipliers in regular expressions. Tuples may also include ``None`` as in: - ``expr*(n, None)`` or ``expr*(n, )`` is equivalent to ``expr*n + ZeroOrMore(expr)`` (read as "at least n instances of ``expr``") - ``expr*(None, n)`` is equivalent to ``expr*(0, n)`` (read as "0 to n instances of ``expr``") - ``expr*(None, None)`` is equivalent to ``ZeroOrMore(expr)`` - ``expr*(1, None)`` is equivalent to ``OneOrMore(expr)`` Note that ``expr*(None, n)`` does not raise an exception if more than n exprs exist in the input stream; that is, ``expr*(None, n)`` does not enforce a maximum number of expr occurrences. If this behavior is desired, then write ``expr*(None, n) + ~expr`` )rNNrrr=rSrc34K|]}|tur|ndywr=)r)r4rs r6rz(ParserElement.__mul__..sJqq0!d:J)NNz/cannot multiply ParserElement by negative valuez@second tuple value must be greater or equal to first tuple valuecR|dkDrt|dz zStSrM)Opt)nmakeOptionalListrs r6rz/ParserElement.__mul__..makeOptionalLists.q5t&6q1u&==>>t9$rC) rr^rrr ZeroOrMore OneOrMore ValueErrorr)rr minElements optElementsrrs` @r6__mul__zParserElement.__mul__ss* H E u %%){*BE!"I%/!4E%#u.! ! eS !',aKJEJJE\)2A.EQxE!H %(C(U1X-=8q=%d++8q=$T?*%(?Z-===E!Hc*z%(C/H+0( [{* %% ?NO O ?R  + * *r7N +  % !#!1+!>>C tf{236F{6SSC '{3  a 4&;./ rCc$|j|Sr=)rrs r6__rmul__zParserElement.__rmul__s||E""rCc|tur t|dSt|tr!|dk(r t |S|j |}t|t stSt||gS)z Implementation of ``|`` operator - returns :class:`MatchFirst` .. versionchanged:: 3.1.0 Support ``expr | ""`` as a synonym for ``Optional(expr)``. T) must_skiprf) rrr^r#rrrsr MatchFirstrs r6__or__zParserElement.__or__sc H 5 5 eX &{4y ,,U3E%/! !4-((rCczt|tr|j|}t|tstS||zS)zd Implementation of ``|`` operator when left operand is not a :class:`ParserElement` rrs r6__ror__zParserElement.__ror__rrCct|tr|j|}t|tstSt ||gS)zH Implementation of ``^`` operator - returns :class:`Or` )r^r#rrsrOrrs r6__xor__zParserElement.__xor__s= eX &,,U3E%/! !4-  rCczt|tr|j|}t|tstS||z S)zd Implementation of ``^`` operator when left operand is not a :class:`ParserElement` rrs r6__rxor__zParserElement.__rxor__rrCct|tr|j|}t|tstSt ||gS)zJ Implementation of ``&`` operator - returns :class:`Each` )r^r#rrsrEachrs r6__and__zParserElement.__and__s= eX &,,U3E%/! !T5M""rCczt|tr|j|}t|tstS||zS)zd Implementation of ``&`` operator when left operand is not a :class:`ParserElement` rrs r6__rand__zParserElement.__rand__rrCct|S)zL Implementation of ``~`` operator - returns :class:`NotAny` )NotAnyrs r6 __invert__zParserElement.__invert__ sd|rCcjd}t}t|tr|j|j}}|d}d}nHt|t r8t|dtr%|d|djf|dj}}d}t|t r|f} t|t|dkDr1td |dd t|d kDrd t|d nd d|t |ddz}tjt|}|r|j||S#t$r||f}YwxYw)a use ``[]`` indexing notation as a short form for expression repetition: - ``expr[n]`` is equivalent to ``expr*n`` - ``expr[m, n]`` is equivalent to ``expr*(m, n)`` - ``expr[n, ...]`` or ``expr[n,]`` is equivalent to ``expr*n + ZeroOrMore(expr)`` (read as "at least n instances of ``expr``") - ``expr[..., n]`` is equivalent to ``expr*(0, n)`` (read as "0 to n instances of ``expr``") - ``expr[...]`` and ``expr[0, ...]`` are equivalent to ``ZeroOrMore(expr)`` - ``expr[1, ...]`` is equivalent to ``OneOrMore(expr)`` ``None`` may be used in place of ``...``. Note that ``expr[..., n]`` and ``expr[m, n]`` do not raise an exception if more than ``n`` ``expr``\ s exist in the input stream. If this behavior is desired, then write ``expr[..., n] + ~expr``. For repetition with a stop_on expression, use slice notation: - ``expr[...: end_expr]`` and ``expr[0, ...: end_expr]`` are equivalent to ``ZeroOrMore(expr, stop_on=end_expr)`` - ``expr[1, ...: end_expr]`` is equivalent to ``OneOrMore(expr, stop_on=end_expr)`` .. versionchanged:: 3.1.0 Support for slice notation. FN.TrrrrSz'only 1 or 2 index arguments supported (rVz... []rf))NoMatchr^slicerstoprr#iterrrNtypingr _MultipleMatchstopOn)rkeystop_on_definedstop_onrs r6 __getitem__zParserElement.__getitem__s=: ) c5 !99chhC{"O U # 3r7E(BFCFLL13q6;;C"O c8 $&C  I s8a<9#bq'Z]^aZbefZfU3s8*TUCVlnBoopq  U3r7^#kk.#.  JJw   *C s D"" D21D2cH||j|S|jS)aO Shortcut for :class:`set_results_name`, with ``list_all_matches=False``. If ``name`` is given with a trailing ``'*'`` character, then ``list_all_matches`` will be passed as ``True``. If ``name`` is omitted, same as calling :class:`copy`. Example: .. testcode:: # these are equivalent userdata = ( Word(alphas).set_results_name("name") + Word(nums + "-").set_results_name("socsecno") ) userdata = Word(alphas)("name") + Word(nums + "-")("socsecno") )rrrrAs r6__call__zParserElement.__call__Ss'*  ''- -yy{rCct|S)z Suppresses the output of this :class:`ParserElement`; useful to keep punctuation from cluttering up returned output. )Suppressrs r6suppresszParserElement.suppressms ~rCcd|_|S)z Enables the skipping of whitespace before matching the characters in the :class:`ParserElement`'s defined pattern. :param recursive: If ``True`` (the default), also enable whitespace skipping in child elements (if any) Trr recursives r6ignore_whitespacezParserElement.ignore_whitespacets# rCcd|_|S)a| Disables the skipping of whitespace before matching the characters in the :class:`ParserElement`'s defined pattern. This is normally only used internally by the pyparsing module, but may be needed in some whitespace-sensitive grammars. :param recursive: If true (the default), also disable whitespace skipping in child elements (if any) Frrs r6leave_whitespacezParserElement.leave_whitespace~s$ rCcBd|_t||_||_|S)z8 Overrides the default whitespace chars T)rrrr)rr copy_defaultss r6set_whitespace_charsz"ParserElement.set_whitespace_charss$ #e*%2" rCcd|_|S)z Overrides default behavior to expand ```` s to spaces before parsing the input string. Must be called before ``parse_string`` when the input grammar contains elements that match ```` characters. T)rrs r6parse_with_tabszParserElement.parse_with_tabss   rCct|tr t|}t|tr+||jvr|jj ||S|jj t|j |S)a Define expression to be ignored (e.g., comments) while doing pattern matching; may be called repeatedly, to define multiple comment or other ignorable patterns. Example: .. doctest:: >>> patt = Word(alphas)[...] >>> print(patt.parse_string('ablaj /* comment */ lskjd')) ['ablaj'] >>> patt = Word(alphas)[...].ignore(c_style_comment) >>> print(patt.parse_string('ablaj /* comment */ lskjd')) ['ablaj', 'lskjd'] )r^r#rrr rrs r6ignorezParserElement.ignoresp$ eX &UOE eX &D,,,  ''.     # #HUZZ\$: ; rCct|j|xst|xst|xst|_d|_|S)a Customize display of debugging messages while doing pattern matching: :param start_action: method to be called when an expression is about to be parsed; should have the signature:: fn(input_string: str, location: int, expression: ParserElement, cache_hit: bool) :param success_action: method to be called when an expression has successfully parsed; should have the signature:: fn(input_string: str, start_location: int, end_location: int, expression: ParserELement, parsed_tokens: ParseResults, cache_hit: bool) :param exception_action: method to be called when expression fails to parse; should have the signature:: fn(input_string: str, location: int, expression: ParserElement, exception: Exception, cache_hit: bool) T)rrrrrr)r start_actionsuccess_actionexception_actions r6set_debug_actionszParserElement.set_debug_actionssAH!--  77  ;;  ? ?    rCc|r*|jD]}|j|d|S|r!|jttt |Sd|_|S)a Enable display of debugging messages while doing pattern matching. Set ``flag`` to ``True`` to enable, ``False`` to disable. Set ``recurse`` to ``True`` to set the debug flag on this expression and all sub-expressions. Example: .. testcode:: wd = Word(alphas).set_name("alphaword") integer = Word(nums).set_name("numword") term = wd | integer # turn on debugging for wd wd.set_debug() term[1, ...].parse_string("abc 123 xyz 890") prints: .. testoutput:: :options: +NORMALIZE_WHITESPACE Match alphaword at loc 0(1,1) abc 123 xyz 890 ^ Matched alphaword -> ['abc'] Match alphaword at loc 4(1,5) abc 123 xyz 890 ^ Match alphaword failed, ParseException raised: Expected alphaword, ... Match alphaword at loc 8(1,9) abc 123 xyz 890 ^ Matched alphaword -> ['xyz'] Match alphaword at loc 12(1,13) abc 123 xyz 890 ^ Match alphaword failed, ParseException raised: Expected alphaword, ... abc 123 xyz 890 ^ Match alphaword failed, ParseException raised: Expected alphaword, found end of text ... The output shown is that produced by the default debug actions - custom debug actions can be specified using :meth:`set_debug_actions`. Prior to attempting to match the ``wd`` expression, the debugging message ``"Match at loc (,)"`` is shown. Then if the parse succeeds, a ``"Matched"`` message is shown, or an ``"Exception raised"`` message is shown. Also note the use of :meth:`set_name` to assign a human-readable name to the expression, which makes debugging and exception messages easier to understand - for instance, the default name created for the :class:`Word` expression without calling :meth:`set_name` is ``"W:(A-Za-z)"``. .. versionchanged:: 3.1.0 ``recurse`` argument added. F)r)rrr(rrrr)rflagrrs r6rzParserElement.set_debugsbn ( 4tU3 4K   " "+-/  DJ rCc\|j|j|_|jSr=)r_generateDefaultNamers r6 default_namezParserElement.default_name+s+    $ $ 9 9 ;D    rCcy)zg Child classes must define this method, which defines how the ``default_name`` is set. NrYrs r6r,z"ParserElement._generateDefaultName1rrCc||_dt||_tjr|j |du|S)a Define name for this expression, makes debugging and exception messages clearer. If `__diag__.enable_debug_on_named_expressions` is set to True, setting a name will also enable debug for this expression. If `name` is None, clears any custom name for this expression, and clears the debug flag is it was enabled via `__diag__.enable_debug_on_named_expressions`. Example: .. doctest:: >>> integer = Word(nums) >>> integer.parse_string("ABC") Traceback (most recent call last): ParseException: Expected W:(0-9) (at char 0), (line:1, col:1) >>> integer.set_name("integer") integer >>> integer.parse_string("ABC") Traceback (most recent call last): ParseException: Expected integer (at char 0), (line:1, col:1) .. versionchanged:: 3.1.0 Accept ``None`` as the ``name`` argument. Expected N)rrtrr8rNrrs r6set_namezParserElement.set_name7s<6!#d)-  5 5 NN4t+ , rCcJ|j |jS|jSr=)rr-rs r6rAzParserElement.nameZs"#'//"=tT4CTCTTrCc&|j|yr=)r1)rnew_names r6rAzParserElement.name_s hrCc|jSr=rArs r6__str__zParserElement.__str__cs yyrCct|Sr=rtrs r6__repr__zParserElement.__repr__fs 4yrCc"d|_d|_|SNT)rrrs r6rzParserElement.streamlineis  rCcgSr=rYrs r6rzParserElement.recursen rCcb|dd|gz}|jD]}|j|yr=)r_checkRecursionrparseElementListsubRecCheckListrFs r6r@zParserElement._checkRecursionqs6*1-6 /A  o . /rCc^tjdtd|jgy)z .. deprecated:: 3.0.0 Do not use to check for left recursion. Check defined expressions for valid structure, check for infinite recursive definitions. ZParserElement.validate() is deprecated, and should not be used to check for left recursionrS stacklevelN)warningsr:DeprecationWarningr@)r validateTraces r6validatezParserElement.validatevs)  h  R rCc|xs|} tjt|}|j} |j|S#t$rQtjt |}t |d|5}|j}dddn #1swYnxYwYlwxYw#t$r'}tjr|jdd}~wwxYw)z Execute the parse expression on the given file or filename. If a filename is specified (instead of a file object), the entire file is opened, read, and closed before parsing. rencodingN) r r r readAttributeErrorrtopenrrrsrr)rfile_or_filenamerOrr file_contentsfrs r6 parse_filezParserElement.parse_files(y )%{{63CD ,113M  +$$]H= =  )%{{30@A &h? )1 !  ) ) ) ) " +//$$T* *  +s@*AB"1B6B BB BB" C+"C  Cc||uryt|tr|j|dSt|trt |t |k(Sy)NTrF)r^r#rrsvarsrs r6__eq__zParserElement.__eq__sI 5= x (<<<6 6 } -:e, ,rCct|Sr=)idrs r6__hash__zParserElement.__hash__s $xrCch|xr|} |jt||y#t$rYywxYw)a Method for quick testing of a parser against a test string. Good for simple inline microtests of sub expressions while building up larger parser. :param test_string: to test against this expression for a match :param parse_all: flag to pass to :meth:`parse_string` when running tests Example: .. doctest:: >>> expr = Word(nums) >>> expr.matches("100") True rXTF)rrtr)r test_stringrrs r6rzParserElement.matchess@$)     c+.(  C!  s % 11)rfullDump printResults failureTestsrYc   ddlm}| xr|} | xr|} | xr|} | xs|} |xs|}t|tr`t j t |}t|j}|jjDcgc] }|| }}|du}|r5t|tr%t j t |}t|}t j t|}|tj}|j}g}g}d}tdj!t#dj%t&}d}d}|D]}|r|j)|ds|r'|s%|j+| r|j-|n|A|sD||r|j/|nd | r|j-|n|g}|j1 |j3|j5|}|j7|| }|xr| }|w |||}|Kt|t8r |j+|j;n:|j+t |n|j+|j;n"|j+|j;|  |j+d | r|dj/||j+||f||fScc}w#t<$ra}|j+|j;| |j+|j>d t|j>d |Yd}~d}~wwxYw#t@$r}t|tBrdnd } |j+|jE|j+d| |tjFr.|jItKjL|jN|xr| }|}Yd}~Td}~wt<$r}!d}"|!jN}#tQtKjR|#}$|$D]Q\}%}&|%jTjV|&ftXk(s&t[|$d}'|"d|'jTj\dz }"n|j+|"d t|!j>d |!tjFr.|jItKjL|!jN|xr| }|!}Yd}!~!Zd}!~!wwxYw)a Execute the parse expression on a series of test strings, showing each test, the parsed results or where the parse failed. Quick and easy way to run a parse expression against a list of sample strings. Parameters: - ``tests`` - a list of separate test strings, or a multiline string of test strings - ``parse_all`` - (default= ``True``) - flag to pass to :class:`parse_string` when running tests - ``comment`` - (default= ``'#'``) - expression for indicating embedded comments in the test string; pass None to disable comment filtering - ``full_dump`` - (default= ``True``) - dump results as list followed by results names in nested outline; if False, only dump nested list - ``print_results`` - (default= ``True``) prints test output to stdout - ``failure_tests`` - (default= ``False``) indicates if these tests are expected to fail parsing - ``post_parse`` - (default= ``None``) optional callback for successful parse results; called as `fn(test_string, parse_results)` and returns a string to be added to the test output - ``file`` - (default= ``None``) optional file-like object to which test output will be written; if None, will default to ``sys.stdout`` - ``with_line_numbers`` - default= ``False``) show test strings with line and column numbers Returns: a (success, results) tuple, where success indicates that all tests succeeded (or failed if ``failure_tests`` is True), and the results contain a list of lines of each test's output Passing example: .. testcode:: number_expr = pyparsing_common.number.copy() result = number_expr.run_tests(''' # unsigned integer 100 # negative integer -100 # float with scientific notation 6.02e23 # integer with scientific notation 1e-12 # negative decimal number without leading digit -.100 ''') print("Success" if result[0] else "Failed!") prints: .. testoutput:: :options: +NORMALIZE_WHITESPACE # unsigned integer 100 [100] # negative integer -100 [-100] # float with scientific notation 6.02e23 [6.02e+23] # integer with scientific notation 1e-12 [1e-12] # negative decimal number without leading digit -.100 [-0.1] Success Failure-test example: .. testcode:: result = number_expr.run_tests(''' # stray character 100Z # too many '.' 3.14.159 ''', failure_tests=True) print("Success" if result[0] else "Failed!") prints: .. testoutput:: :options: +NORMALIZE_WHITESPACE # stray character 100Z 100Z ^ ParseException: Expected end of text, found 'Z' ... # too many '.' 3.14.159 3.14.159 ^ ParseException: Expected end of text, found '.' ... FAIL: Expected end of text, found '.' ... Success Each test string must be on a single line. If you want to test a string that spans multiple lines, create a test like this: .. testcode:: expr = Word(alphanums)[1,...] expr.run_tests(r"this is a test\n of strings that spans \n 3 lines") .. testoutput:: :options: +NORMALIZE_WHITESPACE :hide: this is a test\n of strings that spans \n 3 lines ['this', 'is', 'a', 'test', 'of', 'strings', 'that', 'spans', '3', 'lines'] (Note that this is a raw string literal, you must include the leading ``'r'``.) r)pyparsing_testNT\n uFrfrX)fullz failed: : z(FATAL) zFAIL: zFAIL-EXCEPTIONrz (raised in parse action r)/testingrdr^r#r r rtrstriprstrip splitlinesLiteralrssysstdoutwriter> replace_withr# quoted_stringrr with_line_numbersrr6rlstriprr dumpr]r)rrexplainrrr format_tbrrwalk_tbf_code co_filenamernextco_name)(rtestsrcomment full_dump print_results failure_tests post_parsefilersrr`rarbrYrd line_strip test_linecomment_specifiedprint_ allResultscommentssuccessNLBOMnlstrrrrpp_valuerFrrrtagritrUrnext_fs( r6 run_testszParserElement.run_testss|` ,) ) #5 #4} + eX &KKU+Ee**J(ST;LN44Q7RS'(%**X.CD7H003aC NN / ;'' 6**1*A6"6,&6( #,Q#7#/)(LA # 8==? ; # 3x= 9JJv{{}5JJv{{{9: JJrNtyy~&   q&k *EB +H ""mYP% 6;;H;#=> (112)DG