JL i@tddlmZddlmZddlmZGddeZGddeZdZe d k(rey y ) ) Nonterminal)ParserI)TreecZeZdZdZddZdZdZdZdZddZ dd Z dd Z d Z d Z d Zy)ShiftReduceParsera A simple bottom-up CFG parser that uses two operations, "shift" and "reduce", to find a single parse for a text. ``ShiftReduceParser`` maintains a stack, which records the structure of a portion of the text. This stack is a list of strings and Trees that collectively cover a portion of the text. For example, while parsing the sentence "the dog saw the man" with a typical grammar, ``ShiftReduceParser`` will produce the following stack, which covers "the dog saw":: [(NP: (Det: 'the') (N: 'dog')), (V: 'saw')] ``ShiftReduceParser`` attempts to extend the stack to cover the entire text, and to combine the stack elements into a single tree, producing a complete parse for the sentence. Initially, the stack is empty. It is extended to cover the text, from left to right, by repeatedly applying two operations: - "shift" moves a token from the beginning of the text to the end of the stack. - "reduce" uses a CFG production to combine the rightmost stack elements into a single Tree. Often, more than one operation can be performed on a given stack. In this case, ``ShiftReduceParser`` uses the following heuristics to decide which operation to perform: - Only shift if no reductions are available. - If multiple reductions are available, then apply the reduction whose CFG production is listed earliest in the grammar. Note that these heuristics are not guaranteed to choose an operation that leads to a parse of the text. Also, if multiple parses exists, ``ShiftReduceParser`` will return at most one of them. :see: ``nltk.grammar`` c@||_||_|jy)a Create a new ``ShiftReduceParser``, that uses ``grammar`` to parse texts. :type grammar: Grammar :param grammar: The grammar used to parse texts. :type trace: int :param trace: The level of tracing that should be used when parsing a text. ``0`` will generate no tracing output; and higher numbers will produce more verbose tracing output. N)_grammar_trace_check_grammar)selfgrammartraces \/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/nltk/parse/shiftreduce.py__init__zShiftReduceParser.__init__;s    c|jSNr r s rr zShiftReduceParser.grammarLs }}rc#&Kt|}|jj|g}|}|jr/t ddj |z|j ||t|dkDrG|j|||j||r |j||rt|dkDrGt|dk(rE|dj|jjjk(r|dyyyw)Nz Parsing %r r) listr check_coverager printjoin _trace_stacklen_shift_reducelabelstartsymbol)r tokensstackremaining_texts rparsezShiftReduceParser.parseOsf $$V, ;; ,&!11 2   e^ 4.!A% KK~ .,,un5,,un5.!A% u:?Qx~~4==#6#6#8#?#?#AAAhB sB+D.D=ADc|j|d|j|d|jr|j||yy)a Move a token from the beginning of ``remaining_text`` to the end of ``stack``. :type stack: list(str and Tree) :param stack: A list of strings and Trees, encoding the structure of the text that has been parsed so far. :type remaining_text: list(str) :param remaining_text: The portion of the text that is not yet covered by ``stack``. :rtype: None rN)appendremover _trace_shiftr r%r&s rrzShiftReduceParser._shiftisD  ^A&'nQ/0 ;;   e^ 4 rcNt|t|k7rytt|D]v}t||tr?t||tsy||j ||j k7sSyt||try||||k7svyy)a7 :rtype: bool :return: true if the right hand side of a CFG production matches the rightmost elements of the stack. ``rhs`` matches ``rightmost_stack`` if they are the same length, and each element of ``rhs`` matches the corresponding element of ``rightmost_stack``. A nonterminal element of ``rhs`` matches any Tree whose node value is equal to the nonterminal's symbol. A terminal element of ``rhs`` matches any string whose type is equal to the terminal. :type rhs: list(terminal and Nonterminal) :param rhs: The right hand side of a CFG production. :type rightmost_stack: list(string and Tree) :param rightmost_stack: The rightmost elements of the parser's stack. FT)rrange isinstancerrr!r#)r rhsrightmost_stackis r _match_rhszShiftReduceParser._match_rhs{s$  3s8 +s?+, !A/!,d3!#a&+6 "1%++-Q@ c!fk2 "1%Q/  !rNcx||jj}n|g}|D]}t|j}|j |j|| dsAt |j j|| d}|g|| d|jr|j||||cSy)a Find a CFG production whose right hand side matches the rightmost stack elements; and combine those stack elements into a single Tree, with the node specified by the production's left-hand side. If more than one CFG production matches the stack, then use the production that is listed earliest in the grammar. The new Tree replaces the elements in the stack. :rtype: Production or None :return: If a reduction is performed, then return the CFG production that the reduction is based on; otherwise, return false. :type stack: list(string and Tree) :param stack: A list of strings and Trees, encoding the structure of the text that has been parsed so far. :type remaining_text: list(str) :param remaining_text: The portion of the text that is not yet covered by ``stack``. N) r productionsrr0r3rlhsr#r _trace_reduce)r r%r& productionr5rhslentrees rr zShiftReduceParser._reduces*  --335K%,K& "J)*Fz~~/wxAJNN,335ufWXG#'&vgh;;&&uj.I!! "rc||_y)aP Set the level of tracing output that should be generated when parsing a text. :type trace: int :param trace: The trace level. A trace level of ``0`` will generate no tracing output; and higher trace levels will produce more verbose tracing output. :rtype: None N)r )r rs rrzShiftReduceParser.traces  rcd|zdz}|D]L}t|tr)|tt|j dzz }<|t|dzz }N|ddj |zdzz }t |y)a' Print trace output displaying the given stack and text. :rtype: None :param marker: A character that is printed to the left of the stack. This is used with trace level 2 to print 'S' before shifted stacks and 'R' before reduced stacks. z z [ rz* ]N)r/rreprrr!rr)r r%r&markerselts rrzShiftReduceParser._trace_stacks 6ME ! %C#t$T+ciik23c99T#Y_$  % TCHH^, ,s 22 arc|jdkDrtd|dz|jdk(r|j||dy|jdkDr|j||yy)zd Print trace output displaying that a token has been shifted. :rtype: None z Shift %r:SrN)r rrr,s rr+zShiftReduceParser._trace_shifts^ ;;? +b ) * ;;!    e^S 9 [[1_   e^ 4rc(|jdkDr>dj|j}td|j d||jdk(r|j ||dy|jdkDr|j ||yy)z Print trace output displaying that ``production`` was used to reduce ``stack``. :rtype: None rCrzReduce z <- RrN)r rr0rr6r)r r%r8r&r0s rr7zShiftReduceParser._trace_reduces ;;?((:>>+,C GJNN,/tC59 : ;;!    e^S 9 [[1_   e^ 4rc6|jj}tt|D]h}t|dzt|D]K}||j }||j }|dt||k(s;t d||zMjy)z Check to make sure that all of the CFG productions are potentially useful. If any productions can never be used, then print a warning. :rtype: None rNzWarning: %r will never be used)r r5r.rr0r)r r5r2jrhs1rhs2s rr z ShiftReduceParser._check_grammarsmm//1 s;'( MA1q5#k"23 M"1~))+"1~))+ #d)$,:[^KL  M Mrrr)rC)r)__name__ __module__ __qualname____doc__rr r'rr3r rrr+r7r rrrrsB'R"45$B*X $ 5 5MrrcheZdZdZdfd ZdZdZdZdZdZ dZ dd Z d Z d Z d Zd ZxZS)SteppingShiftReduceParsera' A ``ShiftReduceParser`` that allows you to setp through the parsing process, performing a single operation at a time. It also allows you to change the parser's grammar midway through parsing a text. The ``initialize`` method is used to start parsing a text. ``shift`` performs a single shift operation, and ``reduce`` performs a single reduce operation. ``step`` will perform a single reduce operation if possible; otherwise, it will perform a single shift operation. ``parses`` returns the set of parses that have been found by the parser. :ivar _history: A list of ``(stack, remaining_text)`` pairs, containing all of the previous states of the parser. This history is used to implement the ``undo`` operation. :see: ``nltk.grammar`` cPt|||d|_d|_g|_yr)superr_stack_remaining_text_history)r r r __class__s rrz"SteppingShiftReduceParser.__init__0s( %( # rct|}|j||jr |jr|jSr)r initializestepparsesr r$s rr'zSteppingShiftReduceParser.parse6s:f iik iik{{}rc|jS)zQ :return: The parser's stack. :rtype: list(str and Tree) )rVrs rr%zSteppingShiftReduceParser.stack=s {{rc|jS)z~ :return: The portion of the text that is not yet covered by the stack. :rtype: list(str) )rWrs rr&z(SteppingShiftReduceParser.remaining_textDs ###rc.g|_||_g|_y)z Start parsing a given text. This sets the parser's stack to ``[]`` and sets its remaining text to ``tokens``. N)rVrWrXr^s rr[z$SteppingShiftReduceParser.initializeLs  % rcF|jxs|jS)a Perform a single parsing operation. If a reduction is possible, then perform that reduction, and return the production that it is based on. Otherwise, if a shift is possible, then perform it, and return True. Otherwise, return False. :return: False if no operation was performed; True if a shift was performed; and the CFG production used to reduce if a reduction was performed. :rtype: Production or bool )reduceshiftrs rr\zSteppingShiftReduceParser.stepUs{{}, ,rct|jdk(ry|jj|jdd|jddf|j |j|jy)a Move a token from the beginning of the remaining text to the end of the stack. If there are no more tokens in the remaining text, then do nothing. :return: True if the shift operation was successful. :rtype: bool rFNT)rrWrXr)rVrrs rrdzSteppingShiftReduceParser.shiftds_ t## $ ) dkk!nd.B.B1.EFG DKK!5!56rc|jj|jdd|jddf|j |j|j|}|s|jj |S)a Use ``production`` to combine the rightmost stack elements into a single Tree. If ``production`` does not match the rightmost stack elements, then do nothing. :return: The production used to reduce the stack, if a reduction was performed. If no reduction was performed, return None. :rtype: Production or None N)rXr)rVrWr pop)r r8 return_vals rrcz SteppingShiftReduceParser.reducessc dkk!nd.B.B1.EFG\\$++t/C/CZP  MM   rct|jdk(ry|jj\|_|_y)a| Return the parser to its state before the most recent shift or reduce operation. Calling ``undo`` repeatedly return the parser to successively earlier states. If no shift or reduce operations have been performed, ``undo`` will make no changes. :return: true if an operation was successfully undone. :rtype: bool rFT)rrXrgrVrWrs rundozSteppingShiftReduceParser.undos7 t}}  ".2mm.?.?.A+d*rcg}|jjD][}t|j}|j |j|j | dsK|j |]|S)z :return: A list of the productions for which reductions are available for the current parser state. :rtype: list(Production) N)r r5rr0r3rVr))r r5r8r9s rreducible_productionsz/SteppingShiftReduceParser.reducible_productionssn  --335 /J)*Fz~~/fWX1FG"":. /rc# Kt|jdk(rrt|jdk(rY|jdj|jj j k(r|jdyyyyw)z :return: An iterator of the parses that have been found by this parser so far. :rtype: iter(Tree) rrN)rrWrVr!r r"r#rs rr]z SteppingShiftReduceParser.parsessy $$ % *DKK A% A$$&$--*=*=*?*F*F*HH++a. I& +sB Bc||_y)z~ Change the grammar used to parse texts. :param grammar: The new grammar. :type grammar: CFG Nr)r r s r set_grammarz%SteppingShiftReduceParser.set_grammars   rrLr)rMrNrOrPrr'r%r&r[r\rdrcrjrlr]ro __classcell__)rYs@rrSrSsD$ $ - &  ! rrScddlm}m}|jd}dj }|j |d}|j|D] }t |y)z5 A demonstration of the shift-reduce parser. r)CFGr'z S -> NP VP NP -> Det N | Det N PP VP -> V NP | V NP PP PP -> P NP NP -> 'I' N -> 'man' | 'park' | 'telescope' | 'dog' Det -> 'the' | 'a' P -> 'in' | 'with' V -> 'saw' zI saw a man in the parkrC)rN)nltkrrr' fromstringsplitrr)rrr'r sentparserps rdemorys^  nn  G % * * ,D  $ $WA $ 6F \\$  ar__main__N) nltk.grammarrnltk.parse.apir nltk.treerrrSryrMrQrrr~sJ%" FMFMX\ 1\ H8 zFr