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

📄 bison_9.htm

📁 Lex和Yacc的Manual
💻 HTM
字号:
<HTML><HEAD><!-- This HTML file has been created by texi2html 1.44     from /opt/src/gnu/bison-1.25/bison.texinfo on 30 June 1997 --><TITLE>Bison 1.25 - Error Recovery</TITLE></HEAD><BODY>Go to the <A HREF="bison_1.html">first</A>, <A HREF="bison_8.html">previous</A>, <A HREF="bison_10.html">next</A>, <A HREF="bison_15.html">last</A> section, <A HREF="index.html">table of contents</A>.<HR><H1><A NAME="SEC81" HREF="index.html#SEC81">Error Recovery</A></H1><P><A NAME="IDX180"></A><A NAME="IDX181"></A></P><P>It is not usually acceptable to have a program terminate on a parseerror.  For example, a compiler should recover sufficiently to parse therest of the input file and check it for errors; a calculator should acceptanother expression.</P><P>In a simple interactive command parser where each input is one line, it maybe sufficient to allow <CODE>yyparse</CODE> to return 1 on error and have thecaller ignore the rest of the input line when that happens (and then call<CODE>yyparse</CODE> again).  But this is inadequate for a compiler, because itforgets all the syntactic context leading up to the error.  A syntax errordeep within a function in the compiler input should not cause the compilerto treat the following line like the beginning of a source file.</P><P><A NAME="IDX182"></A>You can define how to recover from a syntax error by writing rules torecognize the special token <CODE>error</CODE>.  This is a terminal symbol thatis always defined (you need not declare it) and reserved for errorhandling.  The Bison parser generates an <CODE>error</CODE> token whenever asyntax error happens; if you have provided a rule to recognize this tokenin the current context, the parse can continue.  </P><P>For example:</P><PRE>stmnts:  /* empty string */        | stmnts '\n'        | stmnts exp '\n'        | stmnts error '\n'</PRE><P>The fourth rule in this example says that an error followed by a newlinemakes a valid addition to any <CODE>stmnts</CODE>.</P><P>What happens if a syntax error occurs in the middle of an <CODE>exp</CODE>?  Theerror recovery rule, interpreted strictly, applies to the precise sequenceof a <CODE>stmnts</CODE>, an <CODE>error</CODE> and a newline.  If an error occurs inthe middle of an <CODE>exp</CODE>, there will probably be some additional tokensand subexpressions on the stack after the last <CODE>stmnts</CODE>, and therewill be tokens to read before the next newline.  So the rule is notapplicable in the ordinary way.</P><P>But Bison can force the situation to fit the rule, by discarding part ofthe semantic context and part of the input.  First it discards states andobjects from the stack until it gets back to a state in which the<CODE>error</CODE> token is acceptable.  (This means that the subexpressionsalready parsed are discarded, back to the last complete <CODE>stmnts</CODE>.)  Atthis point the <CODE>error</CODE> token can be shifted.  Then, if the oldlook-ahead token is not acceptable to be shifted next, the parser readstokens and discards them until it finds a token which is acceptable.  Inthis example, Bison reads and discards input until the next newlineso that the fourth rule can apply.</P><P>The choice of error rules in the grammar is a choice of strategies forerror recovery.  A simple and useful strategy is simply to skip the rest ofthe current input line or current statement if an error is detected:</P><PRE>stmnt: error ';'  /* on error, skip until ';' is read */</PRE><P>It is also useful to recover to the matching close-delimiter of anopening-delimiter that has already been parsed.  Otherwise theclose-delimiter will probably appear to be unmatched, and generate another,spurious error message:</P><PRE>primary:  '(' expr ')'        | '(' error ')'        ...        ;</PRE><P>Error recovery strategies are necessarily guesses.  When they guess wrong,one syntax error often leads to another.  In the above example, the errorrecovery rule guesses that an error is due to bad input within one<CODE>stmnt</CODE>.  Suppose that instead a spurious semicolon is inserted in themiddle of a valid <CODE>stmnt</CODE>.  After the error recovery rule recoversfrom the first error, another syntax error will be found straightaway,since the text following the spurious semicolon is also an invalid<CODE>stmnt</CODE>.</P><P>To prevent an outpouring of error messages, the parser will output no errormessage for another syntax error that happens shortly after the first; onlyafter three consecutive input tokens have been successfully shifted willerror messages resume.</P><P>Note that rules which accept the <CODE>error</CODE> token may have actions, justas any other rules can.</P><P><A NAME="IDX183"></A>You can make error messages resume immediately by using the macro<CODE>yyerrok</CODE> in an action.  If you do this in the error rule's action, noerror messages will be suppressed.  This macro requires no arguments;<SAMP>`yyerrok;'</SAMP> is a valid C statement.</P><P><A NAME="IDX184"></A>The previous look-ahead token is reanalyzed immediately after an error.  Ifthis is unacceptable, then the macro <CODE>yyclearin</CODE> may be used to clearthis token.  Write the statement <SAMP>`yyclearin;'</SAMP> in the error rule'saction.</P><P>For example, suppose that on a parse error, an error handling routine iscalled that advances the input stream to some point where parsing shouldonce again commence.  The next symbol returned by the lexical scanner isprobably correct.  The previous look-ahead token ought to be discardedwith <SAMP>`yyclearin;'</SAMP>.</P><P><A NAME="IDX185"></A>The macro <CODE>YYRECOVERING</CODE> stands for an expression that has thevalue 1 when the parser is recovering from a syntax error, and 0 therest of the time.  A value of 1 indicates that error messages arecurrently suppressed for new syntax errors.</P><HR>Go to the <A HREF="bison_1.html">first</A>, <A HREF="bison_8.html">previous</A>, <A HREF="bison_10.html">next</A>, <A HREF="bison_15.html">last</A> section, <A HREF="index.html">table of contents</A>.</BODY></HTML>

⌨️ 快捷键说明

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