Why are there no parser actions - Logicalshift/TameParse GitHub Wiki

This is a Philosophical Thing, so the reasoning may be incorrect. The short version is that they should be unnecessary.

Parser actions are used for two main things: building a syntax tree and error recovery. With conventional LALR parsers, using actions to build the syntax tree is useful because the language definition as presented to the parser is often quite different to the one presented in the specification, as the LALR form of the language is often not particularly readable.

TameParse is based on a LALR parser, but has a different approach to resolving ambiguities: rather than rewrite the language definition, guards should be used to specify the 'right' meaning. The goal is to make it so that the specification and parser definition are the same.

Assuming that goal is met - as the author, I believe it is, as I've used it on fairly complex languages with real ambiguities - this means that the parser definition can match the language specification, and that means it can define the structure of the AST with no further work. That eliminates a lot of the extra 'boilerplate' code that has to be written around a parser, and also makes it possible to use the same parser definition to target multiple languages or use cases. (It also enables the 'language inheritance' feature - see the C99.tp example)

Error recovery is a bit trickier: it's often not well covered by any parser. Yacc-style recovery tends to produce parser files that are even less readable than they were before and can't cover a lot of fairly trivial cases. TameParse simply stops and returns the parser state: the parser can be run manually to implement error recovery rules like 'insert a semicolon wherever one was expected'. A future version will likely add support for doing this automatically.

A third reason for actions is to resolve ambiguities. This isn't that common (in my experience, though it is used in many C grammars) but TameParse provides guards to make it possible to specify how ambiguities should be resolved in the parser definition. There may be other types of ambiguities: these should in general be treated by extending the definition language rather than adding parser actions.

(All of that said, it's not the case that I believe parser actions are unnecessary in general: 'user implemented guards' would be useful for resolving ambiguities that the algorithm can't currently handle, for instance)

⚠️ **GitHub.com Fallback** ⚠️