在形成算术表达式的正确语法方面需要帮助

Need help in forming a correct grammar for arithmetic expressions

我正在尝试开设一门没有论坛帮助的旧存档 java 课程。几天来我一直被一个问题所困扰,非常感谢任何形式的帮助。我应该使用解析器制作抽象语法树。解析器从表达式语法文件中读取,然后我必须使用递归调用创建一个抽象树。我写的表达式语法是

    @skip whitespace{
    root ::= expr;
    expr ::=  (product | sum) ((add| multi)* (product | sum)*)*   ;
    sum ::= primitive ( add  primitive)*  ;
    product ::=  primitive (multi primitive)*;
    primitive ::= variable | number | '(' sum ')' | '(' product ')' ;
    
}

    whitespace ::= [ \t\r\n];
    number ::= [0-9]+('.'[0-9]+)*;
    variable ::= [a-zA-Z]+;
    add ::= '+';
    multi ::= '*';

使用此语法,我生成的树用于输入 1+2+3*4+5+6*7+8+(3*2*1) 附在下面

您可以看到它在括号中选择产品,但我似乎不明白如何编写语法以便 3*46*7 被捕获为 product同样,在 Sums 中,乘号之前的数字不包含在前一个求和节点中

您可以在此处删除 expr,但它可能像这样更具可扩展性。无论如何,它真的比你想象的要简单得多:

root ::= expr;
expr ::= sum;
sum ::= product ( add product )* ;
product ::= primitive ( multi primitive )* ;
primitive ::= variable | number | '(' expr ')' ;

这应该是直观的(如果你磨练你的直觉:-)总和是几个乘积的总和;乘积不能是总和的乘积。它可以是带括号的和的乘积,但带括号的和不是和;从语法上讲,这是一个原始的。