我怎样才能与Bison有一个"隐式乘法"规则?

zne*_*eak 3 bison

我正在为一个数学表达式解析器的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 */ }
Run Code Online (Sandbox Code Playgroud)

具有隐含乘法法则创建了减法规则歧义:是x - log(x)的减法log(x)x或相乘x-log(x)

我已经准备好迎接一个简单的解决方案,比如"除非它减去"这是一个乘法,但我不知道如何告诉Bison.

ric*_*ici 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); }
       ;
Run Code Online (Sandbox Code Playgroud)

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

就个人而言,我更愿意能够输入sin 2x,log 3n但开始变得有点棘手.什么sin 2x cos 2x意思?据推测,这意味着(sin(2*x))*(cos(2*x)).但这不log nlog n意味着log(n*log(n))什么?这一切都可以实现; 它只需要思考所有可能性.