⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parse::recdescent.3

📁 视频监控网络部分的协议ddns,的模块的实现代码,请大家大胆指正.
💻 3
📖 第 1 页 / 共 5 页
字号:
upon matching \*(L"\s-1AB\s0\*(R" it would look ahead to see if a 'C' is next and, ifso, will match the second production in preference to the first. Inother words, \fIyacc\fR effectively tries all the productions of a rulebreadth-first in parallel, and selects the \*(L"best\*(R" match, where \*(L"best\*(R"means longest (note that this is a gross simplification of the truebehaviour of \fIyacc\fR but it will do for our purposes)..PPIn contrast, \f(CW\*(C`Parse::RecDescent\*(C'\fR tries each production depth-first insequence, and selects the \*(L"best\*(R" match, where \*(L"best\*(R" means first. This isthe fundamental difference between \*(L"bottom-up\*(R" and \*(L"recursive descent\*(R"parsing..PPEach successfully matched item in a production is assigned a value,which can be accessed in subsequent actions within the sameproduction (or, in some cases, as the return value of a successfulsubrule call). Unsuccessful items don't have an associated value,since the failure of an item causes the entire surrounding productionto immediately fail. The following sections describe the various typesof items and their success values..Sh "Subrules".IX Subsection "Subrules"A subrule which appears in a production is an instruction to the parser toattempt to match the named rule at that point in the text beingparsed. If the named subrule is not defined when requested theproduction containing it immediately fails (unless it was \*(L"autostubbed\*(R" \- seeAutostubbing)..PPA rule may (recursively) call itself as a subrule, but \fInot\fR as theleft-most item in any of its productions (since such recursions are usuallynon-terminating)..PPThe value associated with a subrule is the value associated with its\&\f(CW$return\fR variable (see \*(L"Actions\*(R" below), or with the last successfullymatched item in the subrule match..PPSubrules may also be specified with a trailing repetition specifier,indicating that they are to be (greedily) matched the specified numberof times. The available specifiers are:.PP.Vb 7\&                subrule(?)      # Match one\-or\-zero times\&                subrule(s)      # Match one\-or\-more times\&                subrule(s?)     # Match zero\-or\-more times\&                subrule(N)      # Match exactly N times for integer N > 0\&                subrule(N..M)   # Match between N and M times\&                subrule(..M)    # Match between 1 and M times\&                subrule(N..)    # Match at least N times.Ve.PPRepeated subrules keep matching until either the subrule fails tomatch, or it has matched the minimal number of times but fails toconsume any of the parsed text (this second condition prevents thesubrule matching forever in some cases)..PPSince a repeated subrule may match many instances of the subrule itself, thevalue associated with it is not a simple scalar, but rather a reference to alist of scalars, each of which is the value associated with one of theindividual subrule matches. In other words in the rule:.PP.Vb 1\&                program: statement(s).Ve.PPthe value associated with the repeated subrule \*(L"statement(s)\*(R" is a referenceto an array containing the values matched by each call to the individualsubrule \*(L"statement\*(R"..PPRepetition modifieres may include a separator pattern:.PP.Vb 1\&                program: statement(s /;/).Ve.PPspecifying some sequence of characters to be skipped between each repetition.This is really just a shorthand for the <leftop:...> directive(see below)..Sh "Tokens".IX Subsection "Tokens"If a quote-delimited string or a Perl regex appears in a production,the parser attempts to match that string or pattern at that point inthe text. For example:.PP.Vb 1\&                typedef: "typedef" typename identifier \*(Aq;\*(Aq\&\&                identifier: /[A\-Za\-z_][A\-Za\-z0\-9_]*/.Ve.PPAs in regular Perl, a single quoted string is uninterpolated, whilsta double-quoted string or a pattern is interpolated (at the timeof matching, \fInot\fR when the parser is constructed). Hence, it ispossible to define rules in which tokens can be set at run-time:.PP.Vb 1\&                typedef: "$::typedefkeyword" typename identifier \*(Aq;\*(Aq\&\&                identifier: /$::identpat/.Ve.PPNote that, since each rule is implemented inside a special namespacebelonging to its parser, it is necessary to explicitly quantifyvariables from the main package..PPRegex tokens can be specified using just slashes as delimitersor with the explicit \f(CW\*(C`m<delimiter>......<delimiter>\*(C'\fR syntax:.PP.Vb 1\&                typedef: "typedef" typename identifier \*(Aq;\*(Aq\&\&                typename: /[A\-Za\-z_][A\-Za\-z0\-9_]*/\&\&                identifier: m{[A\-Za\-z_][A\-Za\-z0\-9_]*}.Ve.PPA regex of either type can also have any valid trailing parameter(s)(that is, any of [cgimsox]):.PP.Vb 1\&                typedef: "typedef" typename identifier \*(Aq;\*(Aq\&\&                identifier: / [a\-z_]            # LEADING ALPHA OR UNDERSCORE\&                              [a\-z0\-9_]*        # THEN DIGITS ALSO ALLOWED\&                            /ix                 # CASE/SPACE/COMMENT INSENSITIVE.Ve.PPThe value associated with any successfully matched token is a stringcontaining the actual text which was matched by the token..PPIt is important to remember that, since each grammar is specified in aPerl string, all instances of the universal escape character '\e' withina grammar must be \*(L"doubled\*(R", so that they interpolate to single '\e's whenthe string is compiled. For example, to use the grammar:.PP.Vb 3\&                word:       /\eS+/ | backslash\&                line:       prefix word(s) "\en"\&                backslash:  \*(Aq\e\e\*(Aq.Ve.PPthe following code is required:.PP.Vb 1\&                $parser = new Parse::RecDescent (q{\&\&                        word:       /\e\eS+/ | backslash\&                        line:       prefix word(s) "\e\en"\&                        backslash:  \*(Aq\e\e\e\e\*(Aq\&\&                });.Ve.Sh "Terminal Separators".IX Subsection "Terminal Separators"For the purpose of matching, each terminal in a production is consideredto be preceded by a \*(L"prefix\*(R" \- a pattern which must bematched before a token match is attempted. By default, the prefix is optional whitespace (which always matches, atleast trivially), but this default may be reset in any production..PPThe variable \f(CW$Parse::RecDescent::skip\fR stores the universalprefix, which is the default for all terminal matches in all parsersbuilt with \f(CW\*(C`Parse::RecDescent\*(C'\fR..PPThe prefix for an individual production can be alteredby using the \f(CW\*(C`<skip:...>\*(C'\fR directive (see below)..Sh "Actions".IX Subsection "Actions"An action is a block of Perl code which is to be executed (as theblock of a \f(CW\*(C`do\*(C'\fR statement) when the parser reaches that point in aproduction. The action executes within a special namespace belonging tothe active parser, so care must be taken in correctly qualifying variablenames (see also \*(L"Start-up Actions\*(R" below)..PPThe action is considered to succeed if the final value of the blockis defined (that is, if the implied \f(CW\*(C`do\*(C'\fR statement evaluates to adefined value \- \fIeven one which would be treated as \*(L"false\*(R"\fR). Notethat the value associated with a successful action is also the finalvalue in the block..PPAn action will \fIfail\fR if its last evaluated value is \f(CW\*(C`undef\*(C'\fR. This issurprisingly easy to accomplish by accident. For instance, here's aninfuriating case of an action that makes its production fail, but onlywhen debugging \fIisn't\fR activated:.PP.Vb 4\&        description: name rank serial_number\&                        { print "Got $item[2] $item[1] ($item[3])\en"\&                                if $::debugging\&                        }.Ve.PPIf \f(CW$debugging\fR is false, no statement in the block is executed, sothe final value is \f(CW\*(C`undef\*(C'\fR, and the entire production fails. The solution is:.PP.Vb 5\&        description: name rank serial_number\&                        { print "Got $item[2] $item[1] ($item[3])\en"\&                                if $::debugging;\&                          1;\&                        }.Ve.PPWithin an action, a number of useful parse-time variables areavailable in the special parser namespace (there are other variablesalso accessible, but meddling with them will probably just break yourparser. As a general rule, if you avoid referring to unqualifiedvariables \- especially those starting with an underscore \- inside an action,things should be okay):.ie n .IP "@item\fR and \f(CW%item" 4.el .IP "\f(CW@item\fR and \f(CW%item\fR" 4.IX Item "@item and %item"The array slice \f(CW@item[1..$#item]\fR stores the value associated with each item(that is, each subrule, token, or action) in the current production. Theanalogy is to \f(CW$1\fR, \f(CW$2\fR, etc. in a \fIyacc\fR grammar.Note that, for obvious reasons, \f(CW@item\fR only contains thevalues of items \fIbefore\fR the current point in the production..SpThe first element (\f(CW$item[0]\fR) stores the name of the current rulebeing matched..Sp\&\f(CW@item\fR is a standard Perl array, so it can also be indexed with negativenumbers, representing the number of items \fIback\fR from the current position inthe parse:.Sp.Vb 3\&        stuff: /various/ bits \*(Aqand\*(Aq pieces "then" data \*(Aqend\*(Aq\&                        { print $item[\-2] }  # PRINTS data\&                                             # (EASIER THAN: $item[6]).Ve.SpThe \f(CW%item\fR hash complements the <@item> array, providing namedaccess to the same item values:.Sp.Vb 3\&        stuff: /various/ bits \*(Aqand\*(Aq pieces "then" data \*(Aqend\*(Aq\&                        { print $item{data}  # PRINTS data\&                                             # (EVEN EASIER THAN USING @item).Ve.SpThe results of named subrules are stored in the hash under eachsubrule's name (including the repetition specifier, if any),whilst all other items are stored under a \*(L"namedpositional\*(R" key that indictates their ordinal position within their itemtype: _\|_STRING\fIn\fR_\|_, _\|_PATTERN\fIn\fR_\|_, _\|_DIRECTIVE\fIn\fR_\|_, _\|_ACTION\fIn\fR_\|_:.Sp.Vb 6\&        stuff: /various/ bits \*(Aqand\*(Aq pieces "then" data \*(Aqend\*(Aq { save }\&                        { print $item{_\|_PATTERN1_\|_}, # PRINTS \*(Aqvarious\*(Aq\&                                $item{_\|_STRING2_\|_},  # PRINTS \*(Aqthen\*(Aq\&                                $item{_\|_ACTION1_\|_},  # PRINTS RETURN\&                                                     # VALUE OF save\&                        }.Ve.SpIf you want proper \fInamed\fR access to patterns or literals, you need to turn them into separate rules:.Sp.Vb 3\&        stuff: various bits \*(Aqand\*(Aq pieces "then" data \*(Aqend\*(Aq\&                        { print $item{various}  # PRINTS various\&                        }\&\&        various: /various/.Ve.SpThe special entry \f(CW$item{_\|_RULE_\|_}\fR stores the name of the currentrule (i.e. the same value as \f(CW$item[0]\fR..SpThe advantage of using \f(CW%item\fR, instead of \f(CW@items\fR is that itremoves the need to track items positions that may change as a grammarevolves. For example, adding an interim \f(CW\*(C`<skip>\*(C'\fR directiveof action can silently ruin a trailing action, by moving an \f(CW@item\fRelement \*(L"down\*(R" the array one place. In contrast, the named entry of \f(CW%item\fR is unaffected by such an insertion..SpA limitation of the \f(CW%item\fR hash is that it only records the \fIlast\fRvalue of a particular subrule. For example:.Sp.Vb 2\&        range: \*(Aq(\*(Aq number \*(Aq..\*(Aq number )\*(Aq\&                        { $return = $item{number} }.Ve.Spwill return only the value corresponding to the \fIsecond\fR match of the\&\f(CW\*(C`number\*(C'\fR subrule. In other words, successive calls to a subruleoverwrite the corresponding entry in \f(CW%item\fR. Once again, thesolution is to rename each subrule in its own rule:.Sp.Vb 2\&        range: \*(Aq(\*(Aq from_num \*(Aq..\*(Aq to_num )\*(Aq\&                        { $return = $item{from_num} }\&\&        from_num: number\&        to_num:   number.Ve.ie n .IP "@arg\fR and \f(CW%arg" 4.el .IP "\f(CW@arg\fR and \f(CW%arg\fR" 4.IX Item "@arg and %arg"The array \f(CW@arg\fR and the hash \f(CW%arg\fR store any arguments passed tothe rule from some other rule (see "\*(L"Subrule argument lists\*(R"). Changesto the elements of either variable do not propagate back to the callingrule (data can be passed back from a subrule via the \f(CW$return\fRvariable \- see next item)..ie n .IP "$return" 4.el .IP "\f(CW$return\fR" 4.IX Item "$return"If a value is assigned to \f(CW$return\fR within an action, that value isreturned if the production containing the action eventually matchessuccessfully. Note that setting \f(CW$return\fR \fIdoesn't\fR cause the currentproduction to succeed. It merely tells it what to return if it \fIdoes\fR succeed.Hence \f(CW$return\fR is analogous to \f(CW$$\fR in a \fIyacc\fR grammar..SpIf \f(CW$return\fR is not assigned within a production, the value of thelast component of the production (namely: \f(CW$item[$#item]\fR) isreturned if the production succeeds..ie n .IP "$commit" 4.el .IP "\f(CW$commit\fR" 4.IX Item "$commit"The current state of commitment to the current production (see \*(L"Directives\*(R"below)..ie n .IP "$skip" 4.el .IP "\f(CW$skip\fR" 4.IX Item "$skip"The current terminal prefix (see \*(L"Directives\*(R" below)..ie n .IP "$text" 4.el .IP "\f(CW$text\fR" 4.IX Item "$text"The remaining (unparsed) text. Changes to \f(CW$text\fR \fIdo not

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -