Presentation is loading. Please wait.

Presentation is loading. Please wait.

Joey Paquet, 2000, 20021 Lecture 5 Error Recovery Techniques in Top-Down Predictive Syntactic Analysis.

Similar presentations


Presentation on theme: "Joey Paquet, 2000, 20021 Lecture 5 Error Recovery Techniques in Top-Down Predictive Syntactic Analysis."— Presentation transcript:

1 Joey Paquet, 2000, 20021 Lecture 5 Error Recovery Techniques in Top-Down Predictive Syntactic Analysis

2 Joey Paquet, 2000, 20022 Syntax Error Recovery A syntax error happens when the stream of tokens coming from the lexical analyzer disobeys the grammatical rules defining the programming language. The next token in input is not expected according to the syntactic definition of the language One of the main roles of a compiler is to identify programming errors and give meaningful indications about the location and nature of errors in the input program.

3 Joey Paquet, 2000, 20023 Goals of Error Handling Detect all compile-time errors Report the presence of errors clearly and accurately Recover from each error quickly enough to be able to detect subsequent errors Should not slow down the processing of correct programs Beware of spurious errors that are just a consequence of earlier errors

4 Joey Paquet, 2000, 20024 Reporting Errors Give the position of the error in the source file, maybe print the offending line and point at the error location If the nature of the error is easily identifiable, give a meaningful error message The compiler should not provide erroneous information about the nature of errors If the error is easily correctable, a solution can be proposed or applied by the compiler and a simple warning issued

5 Joey Paquet, 2000, 20025 Good Error Recovery Should recover from each error quickly enough to be able to detect subsequent errors. Error recovery should skip as less tokens as possible. Should not identify more errors than there really is. Cascades of errors should be avoided. Should give meaningful information about the errors, while avoiding to give erroneous information. Should not significantly slow down the compilation of correct programs. Error recovery should induce processing overhead only when errors are encountered. Should not report errors that are consequences of the application of error recovery, e.g. semantic errors.

6 Joey Paquet, 2000, 20026 Error Recovery Strategies There are many different strategies that a parser can employ to recover from syntactic errors. Although some are better than others, none of these methods provide a universal solution. –Panic mode –Phrase level –Error productions –Global correction

7 Joey Paquet, 2000, 20027 Error Recovery Strategies Panic Mode –On discovering an error, the parser discards input tokens until an element of a designated set of synchronizing tokens is found. Synchronizing tokens are typically delimiters such as semicolons or end of block delimiters. –Skipping tokens often has a side-effect of skipping other errors. Choosing the right set of synchronizing tokens is of prime importance. –Simplest method to implement. –Can be integrated in most parsing methods. –Cannot enter an infinite loop.

8 Joey Paquet, 2000, 20028 Error Recovery Strategies Phrase Level –On discovering an error, the parser performs a local correction on the remaining input, e.g. replace a comma by a semicolon, delete an extraneous semicolon, insert a missing semicolon, etc. –Replacements are done in specific contexts. There are myriads of different such contexts. –Cannot cope with errors that occurred before the point of detection. –Can enter an infinite loop, e.g. insertion of an expected token.

9 Joey Paquet, 2000, 20029 Error Recovery Strategies Error Productions –The grammar is augmented with “error” productions. For each possible error, an error production is added. An error is trapped when an error production is used. –Assumes that all kinds of errors are known in advance. –One error production is needed for each possible error. –Error productions are specific to the rules in the grammar. A change in the grammar implies a change of the corresponding error productions. –Extremely hard to maintain.

10 Joey Paquet, 2000, 200210 Error Recovery Strategies Global Correction –Ideally, a compiler should make as few changes as possible in processing an incorrect token stream. –Global correction is about choosing the minimal sequence of changes to obtain a least-cost correction. –Given an incorrect input token stream x, such an algorithm will find a parse tree for a related token stream y, such that the number of insertions, deletions, and changes of tokens required to transform x into y is as small as possible. –Too costly to implement. –The closest correct program does not carry the meaning intended by the programmer anyway. –Can be used as a benchmark for other error correction techniques.

11 Joey Paquet, 2000, 200211 Error Recovery in Recursive Descent Predictive Parsers Two possible cases: –The lookahead symbol or  are not in FIRST(RHSs) –The match() function is called in a no match situation Solution : –Create a skipErrors() function that skips tokens until an element of FIRST(LHS) or FOLLOW(LHS) is encountered –Call this function upon entering any production function

12 Joey Paquet, 2000, 200212 Cont. skipErrors([FIRST],[FOLLOW]) if ( lookahead is in [FIRST] ) return (false)// no error detected else write (“syntax error at “ lookahead.location) while (lookahead not in [FIRST  FOLLOW] ) lookahead = nextToken() write (“parsing resumed at “ lookahead.location) return (true)// error detected match(token) if ( lookahead == token ) lookahead = nextToken() return (true) else write (“syntax error at” lookahead.location. “expected” token) lookahead = nextToken() return (false)

13 Joey Paquet, 2000, 200213 Constructing the Parser LHS(){ // LHS  RHS1 | RHS2 | … |  error = skipErrors( FIRST(LHS),FOLLOW(LHS) ) if (lookahead  FIRST(RHS1) ) if (non-terminals()  match(terminals) ) write(“LHS  RHS1”) else error = true else if (lookahead  FIRST(RHS2) ) if (non-terminals()  match(terminals) ) write(“LHS  RHS2”) else error = true else if … // other right hand sides else if (lookahead  FOLLOW(LHS) ) // only if LHS  exists write(“LHS  ”) else error = true error = skipErrors( FOLLOW(LHS),[empty] ) return (error)

14 Joey Paquet, 2000, 200214 Example E(){ error = skipErrors([0,1,(],[),$]) if (lookahead is in [0,1,(]) //FIRST(TE') if (T();E'();) write(E->TE') else error = true error = skipErrors([),$],[empty]) return (error) }

15 Joey Paquet, 2000, 200215 Example E'(){ error = skipErrors([+],[),$]) if (lookahead is in [+]) //FIRST[+TE'] if (match('+');T();E'()) write(E'->TE') else error = true else if (lookahead is in [$,)] //FOLLOW[E'](epsilon) write(E'->epsilon); else error = true error = skipErrors([$,)],[empty]) return (error) }

16 Joey Paquet, 2000, 200216 Example T(){ error = skipErrors([0,1,(],[+,),$]) if (lookahead is in [0,1,(]) //FIRST[FT'] if (F();T'();) write(T->FT') else error = true error = skipErrors([+,),$],[empty]) return (error) }

17 Joey Paquet, 2000, 200217 Example T'(){ error = skipErrors([*],[+,),$]) if (lookahead is in [*]) //FIRST[*FT'] if (match('*');F();T'()) write(T'->*FT') else error = true else if (lookahead is in [+,),$] //FOLLOW[T'] (epsilon) write(T'->epsilon) else error = true error = skipErrors([+,),$],[empty]) return (error) }

18 Joey Paquet, 2000, 200218 Example F(){ error = skipErrors([0,1,(],[*,+,$,)]) if (lookahead is in [0]) //FIRST[0] match('0') write(F->0) else if (lookahead is in [1]) //FIRST[1] match('1') write(F->1) else if (lookahead is in [(]) //FIRST[(E)] if (match('(');E();match(')')) write(F->1); else error = true error = skipErrors([*,+,$,)],[empty]) return (error) }

19 Joey Paquet, 2000, 200219 Error Recovery in Table-Driven Predictive Parsers All empty cells in the state transition table are syntax errors Each case represents a specific kind of error Task: –Recover from the error Either pop the stack or scan tokens –Output an error message

20 Joey Paquet, 2000, 200220 Building the table with error cases Two possible cases: error(){ // A is top() if (lookahead is $ or in FOLLOW(A)) pop() // equivalent to A   else lookahead = nextToken()// scan }

21 Joey Paquet, 2000, 200221 Original table, grammar and sets FLW(E): { $,) } FLW(E’) : { $,) } FLW(T) : { +,$,) } FLW(T’) : { +,$,) } FLW(F) : { ,+,$,) } E  TE E   | +TE T  FT T   | FT F  ( E ) | 0 | 1 FST(E): { 0,1,( } FST(E’) : { ,+ } FST(T) : { 0,1,( } FST(T’) : { ,* } FST(F) : { 0,1,( } 01()+*$ Er1 E’r3r2r3 Tr4 T’r6 r5r6 Fr7r8r9

22 Joey Paquet, 2000, 200222 State transition table with errors 01()+*$ Er1 popscan pop E’scan r3r2scanr3 Tr4 pop scanpop T’scan r6 r5r6 Fr7r8r9pop


Download ppt "Joey Paquet, 2000, 20021 Lecture 5 Error Recovery Techniques in Top-Down Predictive Syntactic Analysis."

Similar presentations


Ads by Google