Parsing 有限域中计算器的文法

Parsing 有限域中计算器的文法,parsing,compiler-construction,grammar,bison,Parsing,Compiler Construction,Grammar,Bison,除了一元运算符“-”之外,我还有一个可以工作的计算器 必须在两种不同情况下对其进行评估和处理: 当有更像这样的表达式时-(3+3) 当没有时:-3 对于案例1,我想得到一个后缀输出3+- 对于案例2,我想在这个字段中得到这个标记的正确值,例如在Z10中,它是10-3=7 我目前的想法是: E: ... | '-' NUM %prec NEGATIVE { $$ = correct(-yylval); appendNumber($$); } |

除了一元运算符“-”之外,我还有一个可以工作的计算器

必须在两种不同情况下对其进行评估和处理:

  • 当有更像这样的表达式时-(3+3)
  • 当没有时:-3
  • 对于案例1,我想得到一个后缀输出3+- 对于案例2,我想在这个字段中得到这个标记的正确值,例如在Z10中,它是10-3=7

    我目前的想法是:

    E:  ...
        |   '-' NUM %prec NEGATIVE      { $$ = correct(-yylval); appendNumber($$);          }
        |   '-' E %prec NEGATIVE        { $$ = correct(P-$2); strcat(rpn, "-");                                 }
        |   NUM     { appendNumber(yylval); $$ = correct(yylval); }
    

    其中NUM是一个标记,但显然编译器说存在一个compact reduce/reduce,因为E在某些情况下也可以是NUM,尽管它可以工作,但我想消除编译器警告。。我没有主意了。

    通常,这应该作为两条规则来实现(伪代码,我不知道bison语法):

    这是表达式的“terminal”元素的可能规则。自然地,带括号的表达式会导致递归到最高规则:

    Element => Number
               | '(' Expression ')'
    
    一元负号(以及一元加号!)仅在产品堆栈的上一层(语法规则):

    当然,这可以分解为所有可能的组合,例如
    '-'数字
    '-''('Expression')'
    ,同样地,使用
    '+'
    ,并且根本不使用任何一元运算符

    假设我们需要加法/减法和乘法/除法。那么剩下的语法将如下所示:

    Expression => Expression '+' MultiplicationExpr
                  | Expression '-' MultiplicationExpr
                  | MultiplicationExpr
    
    MultiplicationExpr => MultiplicationExpr '*' Term
                          | MultiplicationExpr '/' Term
                          | Term
    

    为了完整起见:

    终端:

    • 编号
    非终端:

    • 表达式
    • 元素
    • 术语
    • MultiplicationExpr
    Number
    是一个终端,它应该匹配这样的regexp
    [0-9]+
    。换句话说,它不解析负号,它总是一个正整数(或零)。通过匹配标记的
    '-'编号
    序列来计算负整数

    必须在两种不同情况下对其进行评估和处理:

    不,没有。这些情况并不明显

    -E
    -NUM
    都不正确。正确的语法应该是:

    primary
        : NUM
        | '-' primary
        | '+' primary /* for completeness */
        | '(' expression ')'
        ;
    

    E在某些情况下也可以是NUM
    -对,那么为什么您甚至需要第一条规则呢?因为如果“-”之后只有标记NUM,我必须做不同的事情,如果“-”之后有一个完整的表达式,则编辑代码以使差异更清晰。对于情况2,为什么不只使用相同的rpn输出呢?(即:3-)。您只需删除第一条规则即可获得此结果。因为-(2+2)无法识别。您可以添加一些内容吗?我知道我可以区分“'-'TOKEN”和“TOKEN”,但我必须在“'-'TOKEN”和“'-'EXPRESSION”之上的一个级别进行区分。类似于如果表达式==token'将是greatA,则token是一个标记,而不是一个表达式。这将扩展我的答案。好的,这是嵌入在较低级别的生产中的。这样的设计有什么问题?我开始认为你看到的是一个不存在的问题<代码>数字本身从不包含
    -
    符号。我概述的语法没有歧义。这就是表达式解析在真正的编译器中的工作方式,它与数学规则是内联的。@adaPlease这不是任何事情的特例。这是一个一元负号。这方面的语法比比皆是。你不需要重新发明这个轮子。它是在1959年左右解决的。它们在我的用例中是不同的,正如你在问题中看到的。不,我不能从你的问题中看到它。我所能看到的是不一致性,这让我对一个了解有限域的人感到惊讶。我只是想聪明一点,同时实现三件事,但我问教授,他说这样做是不可能的,或者必须写得很糟糕,所以。。无论如何,谢谢你的回答。
    primary
        : NUM
        | '-' primary
        | '+' primary /* for completeness */
        | '(' expression ')'
        ;