2

我的编译器课程作业中的语言不允许在没有括号的表达式中使用混合运算符,大概是为了不让我们处理实现优先级。这意味着以下是有效的表达式:

# Valid
1 + 2 + 3
1 + (2 * 3)
1

但这不是:

# Invalid
1 + 2 * 3

空表达式也不是。摘自我的实际语法,表达式解析如下:

%token TNumber
%start expr

%%

expr : mulexpr
     | addexpr
     ;

mulexpr : mulexpr '*' term
        | term
        ;

addexpr : addexpr '+' term
        | term
        ;

term : '(' expr ')'
     | TNumber
     ;

但是,这会导致减少/减少冲突。我这是因为单项表达式 like123可以简化为TNumber -> term -> mulexpr -> expr, 或TNumber -> term -> addexpr -> expr,但我不太确定。我更喜欢语法明确,而不是希望歧义是我认为的那样。但是,我无法想出解决这种歧义的方法。

我的想法是我应该添加一个规则expr : term;,然后以某种方式制定addexprmulexpr要求 2 个或更多术语,但我不知道如何表达这一点。

更新:虽然我找到了一个可行的解决方案,但如果有一个“代码”重复较少的解决方案,它将被接受。

4

1 回答 1

2

使递归停止条件mulexpraddexpr成为一个两项表达式有效:

expr : mulexpr
     | addexpr
     | term
     ;

mulexpr : mulexpr '*' term
        | term '*' term
        ;

addexpr : addexpr '+' term
        | term '+' term
        ;

(在发布问题五秒钟后想通了这一点。所以是一只很棒的橡皮鸭。我想我的大脑只是着迷地试图避免这种重复。)

于 2013-05-06T17:11:16.210 回答