I’m working on a Bison file for a mathematical expression parser. Up to now it’s mostly fine, but I’m facing a problem with implicit multiplications.
You see, I’d like to support expressions like 2x sin(4x) cos(4x). It should parse like 2 * x * sin(4 * x) * cos(4 * x). Nothing too bad here, but consider the following set of rules:
expr
: /* snip */
| '-' expr { /* negate expression */ }
| expr '-' expr { /* subtract expressions */ }
| expr expr { /* multiply expressions */ }
Having that implicit multiplication rule creates an ambiguity with the subtraction rule: is x - log(x) the subtraction of log(x) to x or the multiplication of x by -log(x)?
I’d be ready to settle for an easy solution, like “it’s a multiplication unless it’s subtracting”, but I don’t know how to tell that to Bison.
Or even, is it
x - l * o * g * x? Or maybe justx - log * x?So not quite a simple problem. Suppose you can tell just by looking at
logthat it is a function. Then you can disambiguate in your lexer, and you’re left with “in case of doubt, an operator that looks like an infix operator is an infix operator”. Here’s a quick solution:This particular grammar disallows –x, although it’s perfectly happy with y–x, which means y-(-x). If you want to accept –x, you could change the second
prefixproduction to'-' prefix.Personally, I’d prefer to be able to type
sin 2xandlog 3nbut that starts to get a bit tricky. What doessin 2x cos 2xmean? Presumably, it means(sin(2*x))*(cos(2*x)). But doeslog nlog nnot meanlog(n*log(n))? This can all be achieved; it just requires thinking through all the possibilities.