3

我正在为数学表达式解析器处理 Bison 文件。到目前为止,它大部分都很好,但我面临着隐式乘法的问题。

你看,我想支持像2x sin(4x) cos(4x). 它应该像2 * x * sin(4 * x) * cos(4 * x). 这里没什么太糟糕的,但请考虑以下一组规则:

expr
    : /* snip */
    | '-' expr      { /* negate expression */ }
    | expr '-' expr { /* subtract expressions */ }
    | expr expr     { /* multiply expressions */ }

具有该隐式乘法规则会与减法规则产生歧义:是tox - log(x)的减法还是by的乘法?log(x)xx-log(x)

我已经准备好接受一个简单的解决方案,比如“除非它是减法,否则它是一个乘法”,但我不知道如何告诉 Bison。

4

1 回答 1

5

具有该隐式乘法规则会与减法规则产生歧义:x - log(x) 是 log(x) 与 x 的减法还是 x 与 -log(x) 的乘法?

甚至,是x - l * o * g * x吗?或者也许只是x - log * x

所以不是一个很简单的问题。假设您可以通过查看log它来判断它是一个函数。然后你可以在你的词法分析器中消除歧义,并且你会留下“如有疑问,看起来像中缀运算符的运算符是中缀运算符”。这是一个快速的解决方案:

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); }
       ;

这种特殊的语法不允许使用--x,尽管它对y--x 非常满意,这意味着y-(-x)。如果您想接受 --x,您可以将第二个prefix产生式更改为'-' prefix.

就个人而言,我更喜欢能够打字sin 2xlog 3n但这开始有点棘手。是什么sin 2x cos 2x意思?大概意思就是(sin(2*x))*(cos(2*x))。但log nlog n不是什么意思log(n*log(n))?这一切都可以实现;它只需要考虑所有的可能性。

于 2012-10-14T02:59:51.697 回答