Understanding the heuristics in error recovery (panic mode) in predictive parsing through suitable example

411 views Asked by At

I was going through the text Compilers: Principles,Techniques and Tools by Ullman et. al where I came across the concept of Panic mode recovery in predictive parsing. The text says about some heuristics which should be followed. But the example which they give later in the text illustrates only the points (1) and (5) of the heuristics.

Panic-mode error recovery is based on the idea of skipping symbols on the the input until a token in a selected set of synchronizing tokens appears. Its effectiveness depends on the choice of synchronizing set. The sets should be chosen so that the parser recovers quickly from errors that are likely to occur in practice.

Some heuristics are as follows:

  1. As a starting point, we can place all symbols in FOLLOW(A) into the synchronizing set for nonterminal A. If we skip tokens until an element of FOLLOW(A) is seen and pop A from the stack, it is likely that parsing can continue.

  2. It is not enough to use FOLLOW(A) as the synchronizing set for A. For example, if semicolons terminate statements, as in C, then keywords that begin statements may not appear in the FOLLOW set of the nonterminal generating expressions. A missing semicolon after an assignment may therefore result in the keyword beginning the next statement being skipped. Often, there is a hierarchical structure on constructs in a language; e.g., expressions appear within statements, which appear within blocks, and so on. We can add to the synchronizing set of a lower construct the symbols that begin higher constructs. For example, we might add keywords that begin statements to the synchronizing sets for the nonterminals generating expressions.

  3. If we add symbols in FIRST(A) to the synchronizing set for nonterminal A, then it may be possible to resume parsing according to A if a symbol in FIRST(A) appears in the input.

  4. If a nonterminal can generate the empty string, then the production deriving \epsilon can be used as a default. Doing so may postpone some error detection, but cannot cause an error to be missed. This approach reduces the number of nonterminals that have to be considered during error recovery.

  5. If a terminal on top of the stack cannot be matched, a simple idea is to pop the terminal, issue a message saying that the terminal was inserted, and continue parsing. In effect, this approach takes the synchronizing set of a token to consist of all other tokens.

In general I could not understand the meaning of the heuristic which is stated in point (4).

Could anyone give me an example (or examples) where points (2), (3) , (4) could be useful. Though I could understand the meaning of all the points other than (4), but since the book does not illustrate the points (2),(3) and (4), an example would help me understand the thing better.

0

There are 0 answers