News for hackers. Stuff that matters.
Re:Just Write the Parser by wrs on Wednesday October 21, 2020 @05:12PM (#24852237)
One reason to use a parser generator for a new language is that it will tell you that your language is inherently ambiguous or otherwise broken in a way you didn’t realize. A hand-coded parser tends to just codify your bad assumptions.

It can actually be a good idea to maintain a YACC (or other) grammar for your language just to run the tool as a kind of “grammar linter”, even if you’re going to write the parser by hand.

Re:Just Write the Parser by pklausler on Wednesday October 21, 2020 @07:16PM (#24853335)
If you construct your parser in some kind of declarative fashion (e.g., a parser combinator DSL), you can do that kind of error checking directly on the same spec that you compile to produce your parser.
Re:Just Write the Parser by thequux on Wednesday October 21, 2020 @07:19PM (#24853358)
Most parser combinator DSLs use PEGs to parse, which don't actually prevent ambiguity, but instead hide it. I strongly recommend using something that compiles your declarative grammar into LL(k) or LALR(k)
Re:Just Write the Parser by UK-Al05 on Thursday October 22, 2020 @06:12AM (#24856465)
Do they hide or do they just apply order to choices. Making it impossible to be ambiguous compared to the CFG definition?

It's only sweeping under the rug, if you look at PEG under CFG rules. PEG is not CFG.

I think practice of writing industrial software that is better.

Re:Just Write the Parser by WorldMaker on Thursday October 22, 2020 @02:20PM (#24861368)
I do sometimes wonder if a lot of these arguments themselves would be less ambiguous if PEGs (or some other name of them) were formally added to Chomsky's Hierarchy of Languages between Regular Languages and the languages expressed by CFGs. Though I think it would take someone with a much more rigorous math background than myself to make the case formal enough to get it accepted.

(If it helps, and it may be a red herring, the dualism between PEGs and Parser Combinators has me thinking it's a Category Theory related "step" in the hierarchy. "Deterministic Monadic Compositions" in a reflection of DFA/NFA duals to Regular Languages might imply "Monadic Languages" as a possible name? Again, my math background is definitely not formal enough here to make actual suggestions, but maybe it sparks an idea for someone else.)

Re:Just Write the Parser by chrisseaton on Thursday October 22, 2020 @07:09AM (#24856782)
PEGs absolutely do prevent ambiguity - they don't 'hide' it - I don't even know what that would mean?

There is exactly one way a PEG can parse - there is no ambiguity at all.

Re:Just Write the Parser by chrisseaton on Thursday October 22, 2020 @04:35AM (#24855968)
If you define your language using a recursive descent parser then it can’t be ambiguous.
Re:Just Write the Parser by wrs on Thursday October 22, 2020 @12:30PM (#24859848)
Yes, exactly — that means you’re resolving ambiguities whether or not you’re aware of them (“codify your bad assumptions”).
Re:Just Write the Parser by chrisseaton on Thursday October 22, 2020 @01:15PM (#24860427)
You're not aware of them... because they never exist. A language specified by a recursive descent parser is never ambiguous in the first place. There's nothing to resolve.

I don't know where 'codify your bad assumptions' comes into it? What assumptions? How are they codified without you knowing?

Re:Just Write the Parser by wrs on Thursday October 22, 2020 @06:39PM (#24864033)
The language your parser parses may not be the language you had in mind. Indeed, the language you had in mind may not actually exist. It’s easy to operate based only on examples, and think you know what your language is, when in fact there are cases you didn’t consider. Your parser will resolve the ambiguity (because it has to), but if the tool had told you about the ambiguity, you might have redesigned the language. The result is often that one of your users will discover the ambiguity instead, and then it may be too late.

As an example too well-known to actually occur, suppose you parse “if x then if y then x else z” with the else clause associated to the first if statement, because that’s just how you happened to write the parser. It’s not ambiguous, but your users won’t be happy when they find out the unambiguous rule.

Re:Just Write the Parser by chrisseaton on Thursday October 22, 2020 @06:47PM (#24864097)
> The result is often that one of your users will discover the ambiguity instead, and then it may be too late.

But there are no ambiguities in recursive descent! They won't discover them because... they don't exist! It's literally impossible.

> As an example too well-known to actually occur, suppose you parse...

Great example - and the good thing about recursive descent means it's impossible to write this ambiguously - you must prefer one or the other.

> It’s not ambiguous

Correct. So why are you telling me the problems of ambiguity?

> but your users won’t be happy when they find out the unambiguous rule

Why won't they be happy? You can tell them exactly how their code is going to be parsed. I thought ambiguities was bad but now you're complaining about ambiguity as well?!

Re:Just Write the Parser by wrs on Friday October 23, 2020 @01:10AM (#24866207)
We seem to be talking past each other. :) Of course there are no ambiguities in any parser (unless it returns multiple parses, which would hardly be practical). But that’s almost always because the designer had to resolve some ambiguities present in the grammar.

The question is, did the designer resolve them deliberately or accidentally? And were they resolved in an ergonomic way?

The grammar fragment “expr :: IF expr THEN expr ELSE expr” is ambiguous. If I write a statement like the example, I expect (from 60 years of language tradition and simple ergonomics) a language author to choose to resolve that ambiguity by associating an ELSE with the nearest IF. Telling your puzzled users “it’s not ambiguous, it always goes with the farthest IF!” isn’t going to make them happier. It also won’t work to say “well, + has higher precedence than /, but that’s OK, it always does that”. Those are just bugs in the language design caused by a bad resolution of ambiguity.

If you use a tool to flag the ambiguities in your grammar, then you can be sure all the resolutions in your parser are deliberate and not accidental.

Re:Just Write the Parser by chrisseaton on Friday October 23, 2020 @05:41AM (#24867598)
> But that’s almost always because the designer had to resolve some ambiguities present in the grammar.

Not if they started with a grammar that didn't have any ambiguity in the first place.

I think you're coming from the angle that you always start with a CFG, resolve ambiguity, then write a parser.

Imagine that I never write a CFG for my language. No CFG exists! Instead - I start by writing a PEG, and then I write a recursive descent parser from that. At no point in this process have I had to resolve ambiguity. I didn't start with an ambiguous CFG and then write a PEG from it. I started with a PEG. It's never been ambiguous, and never will be ambiguous. There's no ambiguity.

> The grammar fragment “expr :: IF expr THEN expr ELSE expr” is ambiguous.

Right.... but I wouldn't write that because I'm not starting with a CFG I'm starting with a PEG.

> Telling your puzzled users “it’s not ambiguous, it always goes with the farthest IF!” isn’t going to make them happier.

I can't understand this - if I give them a simple well-defined rule that tells them what the code means they'll be happy. What do you think they'd want instead? No rule? A badly defined rule?

Re:Just Write the Parser by yencabulator on Friday October 23, 2020 @06:55PM (#24875229)
> The language your parser parses may not be the language you had in mind.

This can happen even if you write a formal specification.