How can I have an “implicit multiplication” rule with Bison?

前端 未结 1 679
小鲜肉
小鲜肉 2021-01-06 18:19

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\'

1条回答
  •  时光说笑
    2021-01-06 19:12

    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)?

    Or even, is it x - l * o * g * x? Or maybe just x - log * x?

    So not quite a simple problem. Suppose you can tell just by looking at log that 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:

    term   : ID
           | NUMBER
           | '(' expr ')'      { $$ = $2; }
           | FUNC '(' expr ')' { $$ = new_expr($1, 'c', $3); }
           ;
    
    factor : term
           | term factor       { $$ = new_expr($1, '*', $2); }
           ;
    
    prefix : factor
           | '-' factor        { $$ = new_expr(0, '-', $2); }
           ;
    
    muldiv : prefix
           | muldiv '/' prefix { $$ = new_expr($1, '/', $3); }
           | muldiv '*' prefix { $$ = new_expr($1, '*', $3); }
           ;
    
    expr   : muldiv
           | expr '+' muldiv { $$ = new_expr($1, '+', $3); }
           | expr '-' muldiv { $$ = new_expr($1, '-', $3); }
           ;
    

    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 prefix production to '-' prefix.

    Personally, I'd prefer to be able to type sin 2x and log 3n but that starts to get a bit tricky. What does sin 2x cos 2x mean? Presumably, it means (sin(2*x))*(cos(2*x)). But does log nlog n not mean log(n*log(n)) ? This can all be achieved; it just requires thinking through all the possibilities.

    0 讨论(0)
提交回复
热议问题