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

📄 parse::recdescent.3

📁 视频监控网络部分的协议ddns,的模块的实现代码,请大家大胆指正.
💻 3
📖 第 1 页 / 共 5 页
字号:
.Spresults in an error when a parser is built from this grammar (since thegrammar parser has no way of knowing whether the first > is a \*(L"less than\*(R"or the end of the \f(CW\*(C`<reject:...>\*(C'\fR..SpTo overcome this problem, put the condition inside a do{} block:.Sp.Vb 1\&        line: cmd <reject: do{$thiscolumn > max}> data.Ve.SpNote that the same problem may occur in other directives that takearguments. The same solution will work in all cases..IP "Skipping between terminals" 4.IX Item "Skipping between terminals"The \f(CW\*(C`<skip>\*(C'\fR directive enables the terminal prefix used ina production to be changed. For example:.Sp.Vb 1\&        OneLiner: Command <skip:\*(Aq[ \et]*\*(Aq> Arg(s) /;/.Ve.Spcauses only blanks and tabs to be skipped before terminals in the \f(CW\*(C`Arg\*(C'\fRsubrule (and any of \fIits\fR subrules>, and also before the final \f(CW\*(C`/;/\*(C'\fR terminal.Once the production is complete, the previous terminal prefix isreinstated. Note that this implies that distinct productions of a rulemust reset their terminal prefixes individually..SpThe \f(CW\*(C`<skip>\*(C'\fR directive evaluates to the \fIprevious\fR terminal prefix,so it's easy to reinstate a prefix later in a production:.Sp.Vb 1\&        Command: <skip:","> CSV(s) <skip:$item[1]> Modifier.Ve.SpThe value specified after the colon is interpolated into a pattern, so all ofthe following are equivalent (though their efficiency increases down the list):.Sp.Vb 1\&        <skip: "$colon|$comma">   # ASSUMING THE VARS HOLD THE OBVIOUS VALUES\&\&        <skip: \*(Aq:|,\*(Aq>\&\&        <skip: q{[:,]}>\&\&        <skip: qr/[:,]/>.Ve.SpThere is no way of directly setting the prefix foran entire rule, except as follows:.Sp.Vb 3\&        Rule: <skip: \*(Aq[ \et]*\*(Aq> Prod1\&            | <skip: \*(Aq[ \et]*\*(Aq> Prod2a Prod2b\&            | <skip: \*(Aq[ \et]*\*(Aq> Prod3.Ve.Spor, better:.Sp.Vb 6\&        Rule: <skip: \*(Aq[ \et]*\*(Aq>\&            (\&                Prod1\&              | Prod2a Prod2b\&              | Prod3\&            ).Ve.Sp\&\fBNote: Up to release 1.51 of Parse::RecDescent, an entirely differentmechanism was used for specifying terminal prefixes. The current methodis not backwards-compatible with that early approach. The current approachis stable and will not to change again.\fR.IP "Resynchronization" 4.IX Item "Resynchronization"The \f(CW\*(C`<resync>\*(C'\fR directive provides a visually distinctivemeans of consuming some of the text being parsed, usually to skip anerroneous input. In its simplest form \f(CW\*(C`<resync>\*(C'\fR simplyconsumes text up to and including the next newline (\f(CW"\en"\fR)character, succeeding only if the newline is found, in which case itcauses its surrounding rule to return zero on success..SpIn other words, a \f(CW\*(C`<resync>\*(C'\fR is exactly equivalent to the token\&\f(CW\*(C`/[^\en]*\en/\*(C'\fR followed by the action \f(CW\*(C`{\ $return\ =\ 0\ }\*(C'\fR (except thatproductions beginning with a \f(CW\*(C`<resync>\*(C'\fR are ignored when generatingerror messages). A typical use might be:.Sp.Vb 1\&        script : command(s)\&\&        command: save_command\&               | restore_command\&               | <resync> # TRY NEXT LINE, IF POSSIBLE.Ve.SpIt is also possible to explicitly specify a resynchronizationpattern, using the \f(CW\*(C`<resync:\f(CIpattern\f(CW>\*(C'\fR variant. This versionsucceeds only if the specified pattern matches (and consumes) theparsed text. In other words, \f(CW\*(C`<resync:\f(CIpattern\f(CW>\*(C'\fR is exactlyequivalent to the token \f(CW\*(C`/\f(CIpattern\f(CW/\*(C'\fR (followed by a \f(CW\*(C`{\ $return\ =\ 0\ }\*(C'\fRaction). For example, if commands were terminated by newlines or semi-colons:.Sp.Vb 3\&        command: save_command\&               | restore_command\&               | <resync:[^;\en]*[;\en]>.Ve.SpThe value of a successfully matched \f(CW\*(C`<resync>\*(C'\fR directive (of eithertype) is the text that it consumed. Note, however, that since thedirective also sets \f(CW$return\fR, a production consisting of a lone\&\f(CW\*(C`<resync>\*(C'\fR succeeds but returns the value zero (which a calling rulemay find useful to distinguish between \*(L"true\*(R" matches and \*(L"tolerant\*(R" matches).Remember that returning a zero value indicates that the rule \fIsucceeded\fR (sinceonly an \f(CW\*(C`undef\*(C'\fR denotes failure within \f(CW\*(C`Parse::RecDescent\*(C'\fR parsers..IP "Error handling" 4.IX Item "Error handling"The \f(CW\*(C`<error>\*(C'\fR directive provides automatic or user-definedgeneration of error messages during a parse. In its simplest form\&\f(CW\*(C`<error>\*(C'\fR prepares an error message based onthe mismatch between the last item expected and the text which causeit to fail. For example, given the rule:.Sp.Vb 3\&        McCoy: curse \*(Aq,\*(Aq name \*(Aq, I\*(Aqm a doctor, not a\*(Aq a_profession \*(Aq!\*(Aq\&             | pronoun \*(Aqdead,\*(Aq name \*(Aq!\*(Aq\&             | <error>.Ve.Spthe following strings would produce the following messages:.RS 4.ie n .IP """Amen, Jim!""" 4.el .IP "``Amen, Jim!''" 4.IX Item "Amen, Jim!".Vb 2\&       ERROR (line 1): Invalid McCoy: Expected curse or pronoun\&                       not found.Ve.ie n .IP """Dammit, Jim, I'm a doctor!""" 4.el .IP "``Dammit, Jim, I'm a doctor!''" 4.IX Item "Dammit, Jim, I'm a doctor!".Vb 2\&       ERROR (line 1): Invalid McCoy: Expected ", I\*(Aqm a doctor, not a"\&                       but found ", I\*(Aqm a doctor!" instead.Ve.ie n .IP """He's dead,\en""" 4.el .IP "``He's dead,\en''" 4.IX Item "He's dead,n".Vb 1\&       ERROR (line 2): Invalid McCoy: Expected name not found.Ve.ie n .IP """He's alive!""" 4.el .IP "``He's alive!''" 4.IX Item "He's alive!".Vb 2\&       ERROR (line 1): Invalid McCoy: Expected \*(Aqdead,\*(Aq but found\&                       "alive!" instead.Ve.ie n .IP """Dammit, Jim, I'm a doctor, not a pointy-eared Vulcan!""" 4.el .IP "``Dammit, Jim, I'm a doctor, not a pointy-eared Vulcan!''" 4.IX Item "Dammit, Jim, I'm a doctor, not a pointy-eared Vulcan!".Vb 2\&       ERROR (line 1): Invalid McCoy: Expected a profession but found\&                       "pointy\-eared Vulcan!" instead.Ve.RE.RS 4.SpNote that, when autogenerating error messages, all underscores in anyrule name used in a message are replaced by single spaces (for example\&\*(L"a_production\*(R" becomes \*(L"a production\*(R"). Judicious choice of rulenames can therefore considerably improve the readability of automaticerror messages (as well as the maintainability of the originalgrammar)..SpIf the automatically generated error is not sufficient, it is possible toprovide an explicit message as part of the error directive. For example:.Sp.Vb 3\&        Spock: "Fascinating \*(Aq,\*(Aq (name | \*(AqCaptain\*(Aq) \*(Aq.\*(Aq\&             | "Highly illogical, doctor."\&             | <error: He never said that!>.Ve.Spwhich would result in \fIall\fR failures to parse a \*(L"Spock\*(R" subrule printing thefollowing message:.Sp.Vb 1\&       ERROR (line <N>): Invalid Spock:  He never said that!.Ve.SpThe error message is treated as a \*(L"qq{...}\*(R" string and interpolatedwhen the error is generated (\fInot\fR when the directive is specified!).Hence:.Sp.Vb 1\&        <error: Mystical error near "$text">.Ve.Spwould correctly insert the ambient text string which caused the error..SpThere are two other forms of error directive: \f(CW\*(C`<error?>\*(C'\fR and\&\f(CW\*(C`<error?:\ msg>\*(C'\fR. These behave just like \f(CW\*(C`<error>\*(C'\fRand \f(CW\*(C`<error:\ msg>\*(C'\fR respectively, except that they areonly triggered if the rule is \*(L"committed\*(R" at the time they areencountered. For example:.Sp.Vb 3\&        Scotty: "Ya kenna change the Laws of Phusics," <commit> name\&              | name <commit> \*(Aq,\*(Aq \*(Aqshe\*(Aqs goanta blaw!\*(Aq\&              | <error?>.Ve.Spwill only generate an error for a string beginning with \*(L"Ya kennachange the Laws o' Phusics,\*(R" or a valid name, but which still fails to match thecorresponding production. That is, \f(CW\*(C`$parser\->Scotty("Aye, Cap\*(Aqain")\*(C'\fR willfail silently (since neither production will \*(L"commit\*(R" the rule on thatinput), whereas \f(CW\*(C`$parser\->Scotty("Mr\ Spock,\ ah\ jest\ kenna\ do\*(Aqut!")\*(C'\fRwill fail with the error message:.Sp.Vb 2\&       ERROR (line 1): Invalid Scotty: expected \*(Aqshe\*(Aqs goanta blaw!\*(Aq\&                       but found \*(AqI jest kenna do\*(Aqut!\*(Aq instead..Ve.Spsince in that case the second production would commit after matchingthe leading name..SpNote that to allow this behaviour, all \f(CW\*(C`<error>\*(C'\fR directives which arethe first item in a production automatically uncommit the rule justlong enough to allow their production to be attempted (that is, whentheir production fails, the commitment is reinstated so thatsubsequent productions are skipped)..SpIn order to \fIpermanently\fR uncommit the rule before an error message,it is necessary to put an explicit \f(CW\*(C`<uncommit>\*(C'\fR before the\&\f(CW\*(C`<error>\*(C'\fR. For example:.Sp.Vb 5\&        line: \*(AqKirk:\*(Aq  <commit> Kirk\&            | \*(AqSpock:\*(Aq <commit> Spock\&            | \*(AqMcCoy:\*(Aq <commit> McCoy\&            | <uncommit> <error?> <reject>\&            | <resync>.Ve.SpError messages generated by the various \f(CW\*(C`<error...>\*(C'\fR directivesare not displayed immediately. Instead, they are \*(L"queued\*(R" in a buffer andare only displayed once parsing ultimately fails. Moreover,\&\f(CW\*(C`<error...>\*(C'\fR directives that cause one production of a ruleto fail are automatically removed from the message queueif another production subsequently causes the entire rule to succeed.This means that you can put \&\f(CW\*(C`<error...>\*(C'\fR directives wherever useful diagnosis can be done,and only those associated with actual parser failure will ever bedisplayed. Also see \*(L"Gotchas\*(R"..SpAs a general rule, the most useful diagnostics are usually generatedeither at the very lowest level within the grammar, or at the veryhighest. A good rule of thumb is to identify those subrules whichconsist mainly (or entirely) of terminals, and then put an\&\f(CW\*(C`<error...>\*(C'\fR directive at the end of any other rule which callsone or more of those subrules..SpThere is one other situation in which the output of the various types oferror directive is suppressed; namely, when the rule containing themis being parsed as part of a \*(L"look-ahead\*(R" (see \*(L"Look-ahead\*(R"). In thiscase, the error directive will still cause the rule to fail, but will doso silently..SpAn unconditional \f(CW\*(C`<error>\*(C'\fR directive always fails (and hence has noassociated value). This means that encountering such a directivealways causes the production containing it to fail. Hence an\&\f(CW\*(C`<error>\*(C'\fR directive will inevitably be the last (useful) item of arule (a level 3 warning is issued if a production contains items after an unconditional\&\f(CW\*(C`<error>\*(C'\fR directive)..SpAn \f(CW\*(C`<error?>\*(C'\fR directive will \fIsucceed\fR (that is: fail to fail :\-), ifthe current rule is uncommitted when the directive is encountered. Inthat case the directive's associated value is zero. Hence, this typeof error directive \fIcan\fR be used before the end of aproduction. For example:.Sp.Vb 3\&        command: \*(Aqdo\*(Aq <commit> something\&               | \*(Aqreport\*(Aq <commit> something\&               | <error?: Syntax error> <error: Unknown command>.Ve.Sp\&\fBWarning:\fR The \f(CW\*(C`<error?>\*(C'\fR directive does \fInot\fR mean \*(L"always fail (butdo so silently unless committed)\*(R". It actually means "only fail (and report) ifcommitted, otherwise \fIsucceed\fR\*(L". To achieve the \*(R"fail silently if uncommitted"semantics, it is necessary to use:.Sp.Vb 2\&        rule: item <commit> item(s)\&            | <error?> <reject>      # FAIL SILENTLY UNLESS COMMITTED.Ve.SpHowever, because people seem to expect a lone \f(CW\*(C`<error?>\*(C'\fR directiveto work like this:.Sp.Vb 3\&        rule: item <commit> item(s)\&            | <error?: Error message if committed>\&            | <error:  Error message if uncommitted>.Ve.SpParse::RecDescent automatically appends a \&\f(CW\*(C`<reject>\*(C'\fR directive if the \f(CW\*(C`<error?>\*(C'\fR directiveis the only item in a production. A level 2 warning (see below)is issued when this happens..SpThe level of error reporting during both parser construction andparsing is controlled by the presence or absence of four globalvariables: \f(CW$::RD_ERRORS\fR, \f(CW$::RD_WARN\fR, \f(CW$::RD_HINT\fR, and<$::RD_TRACE>. If \f(CW$::RD_ERRORS\fR is defined (and, by default, it is)then fatal errors are reported..SpWhenever \f(CW$::RD_WARN\fR is defined, certain non-fatal problems are also reported. Warnings have an associated \*(L"level\*(R": 1, 2, or 3. The higher the level,the more serious the warning. The value of the corresponding globalvariable (\f(CW$::RD_WARN\fR) determines the \fIlowest\fR level of warning tobe displayed. Hence, to see \fIall\fR warnings, set \f(CW$::RD_WARN\fR to 1.To see only the most serious warnings set \f(CW$::RD_WARN\fR to 3.By default \f(CW$::RD_WARN\fR is initialized to 

⌨️ 快捷键说明

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