4 ms·
PEG parsers get rid of the dangling else problem with recursive descent parsers where it's unclear in the following statement whether if e then s1 else if e
by kevinburke 15y ago
PEG parsers get rid of the dangling else problem with recursive descent parsers where it's unclear in the following statement whether
if e then s1 else if e then s2 else s3
the else s3 should be with the first if or the second if - usually you have to code special rules into your parser. It also allows for a worst-case linear time parse, and there are some language rules you can express with a PEG parser that you can't with a recursive descent parser.
- andrewflnr 15y agoWouldn't you just have an end symbol for if statements, "end" or "}" or something? That's what I did in my little recursive parser. Maybe what I should ask is, how does a PEG parser resolve it?
- chipsy 15y agoIn a PEG you operate under the expectation that all rules will be tried exhaustively, so if one fails you just move on to the next, and if they all fail you drop back a level of recursion. Thus you can have rules like: "if <if-expr>" where if-expr can contain "<statements> else" or "<statements> if" or "then <statements>", where statements is a set of predefined keywords, another set of PEG rules, or a regular expression matcher. And then you can just expect that they'll all be tried at some point. The main issue with this, of course, is the one you raised, with endings and creating rules for delimiting new blocks. Although it's possible to define a good set of rules, it's still hard to distinguish between a continuation of a statement and the start of a new one, and in most cases you won't get a useful syntax error message using a naive PEG system like the one in PEG.js, because it'll just drop all the way to the top level and then fail at the first character without telling you how far/deep it got before the syntax broke. So in practice having end symbols is still useful to make the grammar operate sanely. PEG can also be used to execute a relatively flat pass that mostly produces tokens and simple expressions, while other methods are applied to the resulting tree to get the complete structure. This is an approach which I find a little less mind-bending than trying to cram everything into PEG rules, since you can use varying methods of parsing as the situation dictates.