Error recovery - mattacosta/php-parser GitHub Wiki

Parsing is conceptually just a series of nested loops that try to recognize a particular language construct. When parsing a file, this means that the first loop will only look for top-level statements. It may then delegate to an inner loop that looks for method declarations, which may in turn delegate to yet another loop that looks for parameters and so on.

Recovery Strategy

When an unexpected token is encountered, a loop will generally take one of two possible actions. It will either determine if an outer loop knows what to do or skip the token and keep going.

For example:

function a() {
  echo 'hello world';

class B {}

Here the function statement loop expects a closing brace but encounters an unexpected class token. Instead of skipping it, the function loop will check if an outer loop knows what to do. In this case the result is true, because the top-level loop knows how to parse a class, so a missing brace is created and the function loop will end. If the result was false however, the token would be skipped, and the function loop would continue.

Diagnostics

In both cases, a diagnostic is created, either for the missing token or for the skipped token. Unlike errors created by PHP and some other parsers, these diagnostics are also designed to be specific enough so that a programmer can easily determine how to fix the problem (and so that certain diagnostics can be automatically fixed).

This is helpful in large pieces of code where a generic error like: PHP Parse error: syntax error, unexpected '{', expecting variable (T_VARIABLE) may occur some distance from where the actual error is. Instead, this parser will report something like Parameter or ')' expected which helps narrow down the location and fix.

In the end, the result is also a syntax tree that contains nodes which are much more likely to contain the expected tokens. So if the previous error message occurred in a parameter list, the opening brace would likely appear in its expected location since it technically was expected, just at a later point.