o =?hY2@sdZddlmZddlZddlmZeejejdZ eejdZ dde dDZ d de dDZ Gd d d Zed krNdd lmZeddddSdS)zProvide advanced parsing abilities for ParenMatch and other extensions. HyperParser uses PyParser. PyParser mostly gives information on the proper indentation of code. HyperParser gives additional information on the structure of code. ) iskeywordN)pyparse_cCg|]}t|tvqS)chr_ASCII_ID_CHARS.0xrr:/opt/alt/python310/lib64/python3.10/idlelib/hyperparser.py r cCrr)r_ASCII_ID_FIRST_CHARSr rrr r rc@sZeZdZddZddZddZddZdd d Zehd Z e ddZ dZ ddZ dS) HyperParserc sH|_|j_}t|j|j}dd}|||}|js[|jD]0}t ||d}t |d} d|} | | | | d| || } | dusP|dkrRnq"|| pXdn#|d |} | rh| d} nd } d|} | | | | d|d|jdd _| _|_fd d ttjD_|dS)z;To initialize, analyze the surroundings of the given index.cSs tt|S)N)intfloat)indexrrr index2line"s z(HyperParser.__init__..index2linez.0z%d.endz NrZconsolez1.0cs4g|]}|dkoj|dj|ddkqS)rr) bracketing)r iselfrr r Ks z(HyperParser.__init__..)editwintextrZParserZ indentwidthZtabwidthrZprompt_last_lineZnum_context_linesmaxreprZset_codegetZfind_good_parse_startZ_build_char_in_string_funcZset_loZ tag_prevrangecoderawtext stopatindexZget_last_stmt_bracketingrrangelenisopener set_index) rrrrparserrlnocontextZstartatZ startatindexr#Zbodrrrr __init__s@         zHyperParser.__init__cCst|jt|j||j}|dkrtd|||_d|_|jt|jdkrT|j|jdd|jkrT|jd7_|jt|jdkrT|j|jdd|jks6|jt|jdkr||j|jdd|jkr~|j |jds|jd7_dSdSdSdS)zgSet the index to which the functions relate. The index must be in the same statement. rz(Index %s precedes the analyzed statementrN) r%r"rr r# ValueErrorindexinrawtext indexbracketrr&)rrr.rrr r'Qs*zHyperParser.set_indexcCs&|j|jo|j|j|jddvS)z2Is the index given to the HyperParser in a string?r)"'r&r/r"rrrrr is_in_stringfs zHyperParser.is_in_stringcCs(|j|j p|j|j|jddvS)z5Is the index given to the HyperParser in normal code?r)#r0r1r2rrrr is_in_codens zHyperParser.is_in_code([{FcCs|j|jd}|j}|j|r%|j|j|d|vs%|j|d|krS|d8}|dkr/dSt||j|d}|j|r%|j|j|d|vs%|j|d|ks%|jd}|t|jkr||j|d|kr||d7}|t|jkr||j|d|ksh|jd|jt|j|j|df}|t|jks|j|dt|jkr|rdS|j}||fS|jd|jt|j|j|ddf}||fS)aReturn bracket indexes or None. If the index given to the HyperParser is surrounded by a bracket defined in openers (or at least has one before it), return the indices of the opening bracket and the closing bracket (or the end of line, whichever comes first). If it is not surrounded by brackets, or the end of line comes before the closing bracket and mustclose is True, returns None. rrNz%s-%dc) rr/r&r"minr%rrr#)rZopenersZ mustcloseZbracketinglevelZbeforeZafterZ beforeindexZ afterindexrrr get_surrounding_bracketstsB    z$HyperParser.get_surrounding_brackets>NoneTrueFalsecCst}|}||kr8t||ddkr8|t||dr8|d8}||kr8t||ddkr8|t||ds||krt||ddkr|d|krnd||d|rn|d8}|d|krnd||d|sX|d|krd||d|r|d8}|d|krd||d|r|d8}|||sdSn||krtt||sdS||krt|||r||||jvrdS||S)zGiven a string and pos, return the number of chars in the identifier which ends at pos, or 0 if there is no such one. This ignores non-identifier eywords are not identifiers. rrar)_IS_ASCII_ID_CHARord isidentifier_IS_ASCII_ID_FIRST_CHARr _ID_KEYWORDS)clsstrlimitposZis_ascii_id_charrrrr _eat_identifiers> $$$$zHyperParser._eat_identifierz \c Cs|std|j}|j}|j}||d}|j}|}d} ||kr2||d|jvr2|d8}n=|sG||krG||ddkrG|d8}d}n(||krn|dkrn|||dddkrn|d8}||d}||dd}nnq |ssn||||}|r||}|}d}nr||kr||d} |dkr||dd| kr|d8}|dkr||dd| ks||d|krn@||d}|d8}||d}|}||d vrn&||d vr|dkr||dd vr|d8}|dkr||dd vs|}nnq|||jS) zReturn a string with the Python expression which ends at the given index, which is empty if there is no real one. z?get_expression should only be called if index is inside a code.rTr.r4r>Fz([z'"ZrRbBuU)r5r-r"rr/r._whitespace_charsrH) rr"rZ brck_indexZ brck_limitrGZlast_identifier_posZ postdot_phaseZretlevelrrr get_expressionsj        CzHyperParser.get_expressionN)r6F)__name__ __module__ __qualname__r,r'r3r5r8 frozensetrC classmethodrHrJrLrrrr rs7  , 9 r__main__)mainz"idlelib.idle_test.test_hyperparserr>) verbosity)__doc__keywordrstringZidlelibrrPZ ascii_lettersZdigitsrrr$r?rBrrMZunittestrSrrrr s