The parser finds the stairs

The parser has found a staircase inside an arithmetic expression.

Make the grouping visible

The lexer handed it 1, +, 2, * and 3, all standing politely in a row. A row is not yet a calculation. The parser must decide which pieces belong together.

1 + 2 * 3

Add(
  Integer(1),
  Multiply(Integer(2), Integer(3))
)

These are sketch names for tree nodes, not Pooka’s internal constructor names. Their arrangement is the point. Multiplication sits inside addition’s right-hand side, so evaluating that subtree happens first.

Give operators their places

The grouping has an observable consequence:

main() {
  assert 1 + 2 * 3 == 7
  assert (1 + 2) * 3 == 9
}

A precedence-based expression parser gives operators different binding strengths. While reading the right-hand side of +, it allows * to gather its own operands. Parentheses can ask for a different grouping, and the parser must honour that request without keeping the parentheses as executable work.

Function calls and field access need their places in this arrangement too. A method call is not merely punctuation sprinkled on a name. It has a receiver and arguments that later phases must be able to inspect.

Find a safe place to resume

Then somebody forgets a closing bracket.

The parser has two jobs at that moment: explain what interrupted the construct, and find somewhere sensible to resume. Otherwise the rest of the file becomes a procession of errors caused by one missing character.

Recovery has to make progress. Returning an error without consuming anything can send the same token through the same unhappy function forever. I have considerable sympathy for the token, but nobody should spend their evening there.

A syntax tree is therefore more than a successful parse printed as a diagram. Its boundaries determine what can be checked, which locations can be highlighted, and how much useful work survives an incomplete file.

The arithmetic now has stairs. I am also putting a handrail on them.

— Peregrine Finch

· pooka, parsing, compilers