Hacker News new | ask | show | jobs
by kragen 1644 days ago
You could make 1/2x where x = 4 evaluate to either 2 or 0.125, but either choice will have surprising results in some cases or to some people. Perhaps a better choice, especially for an interactive calculator, is to adopt partially ordered operator precedence, and reject the expression as ambiguous. Then the user can insert parentheses to disambiguate.

In a CFG this is easy enough to express. Here's an untested and at any rate incomplete CFG demonstrating the technique:

    expr ::= term | term "+" expr | term "-" expr
    term ::= quotient | product
    quotient ::= atom "/" atom | atom "/" quotient
    product ::= atom product | atom "*" product | atom
    atom ::= number | variable | "-" atom | "(" expr ")"
But typical parser generators don't give you an easy way to provide a useful error message there.

That version of the grammar, btw, avoids left recursion, so it ought to work as a PEG, but at the cost of the wrong associativity for "/" and "-". You either need to use left recursion or restructure the syntax tree afterwards.

2 comments

> You could make 1/2x where x = 4 evaluate to either 2 or 0.125

Ouch, you just made me think that if I see this equation just "horizontally" like it's presented here, I would say 2. But if I imagine it like you would write it on paper, I would answer 0.125.

The solution is to differentiate between 2*x and 2x. / would have higher priority than *, but lower priority than conjunction
That is a thing you can do, and for example units(1) does just that, but doing it creates the usability problems we are discussing in its thread. My comment is aimed at solving those problems, not worsening them.