取幂运算的明确语法

时间:2013-06-18 07:24:24

标签: context-free-grammar

E -> E+T | E-T | T
T -> T*F | T/F | F
F -> i | (E)

如何修改此语法以允许取幂操作^,以便我可以编写i+i^i*i?既然我们知道^的操作顺序更高,那么我所知道的就是我必须使其正确关联。

3 个答案:

答案 0 :(得分:8)

在EBNF(Extended Backus-Naur Form)中,这可能如下所示:

expr -> term [ ('+' | '-') term ]*
term -> factor [ ('*' | '/') factor ]*
factor -> base [ '^' exponent ]*
base -> '(' expr ')' | identifier | number
exponent -> '(' expr ')' | identifier | number

(摘自here

翻译成您的符号(数字和标识符之间没有区别):

E -> E+T | E-T | T
T -> T*F | T/F | F
F -> F^X | B
B -> i | (E)
X -> i | (E)

为了清楚起见,可以合并“B”和“X”。

答案 1 :(得分:3)

对称如下。

E -> E + T | E - T | T
T -> T * F | T / F | X
X -> X ^ Y | Y
Y -> i | (E)

说明:
 ==========
注意这个语法是明确的。要生成由运算符^*/+-组成的表达式,首先我们需要开始编写较低优先级运算符的步骤,以便可以在较高的+之前添加-*/^。然后可以在目标表达式中添加^。因此,在抽象语法树(parse-tree)中,运算符^将出现在底部(朝向叶子)。这样,如果我们根据树计算表达式,X -> O ^ Y将首先执行。

注意:根据语法规则,以感情形式+,我们无法返回添加-E+T | E-T | T ..,但如果您有任何感性形式, i + i ^ i * i然后我们可以再次添加其他运营商。所以在这种形式的语法中,我们可以控制任何有效表达式(字符串)的生成流属于语法语言。(这是如何在明确的情况下控制运算符优先级)。

例如,为了生成表达式E --> T --> X ---> X ^ Y,我们不能像X ^ Y那样,因为一旦有+,就无法添加-,{{1} }(不带括号(E))。

生成表达式i + i ^ i * i的可能选择如下:

E --> E - T --> E + T - T --> E + X - T --> E + X ^ Y - T --*--> i+i^i*i

`--*-->` means more than one step 

注意操作符^在最后一步添加(因此可以显示在树的底部,如下图所示):

树将是这样的:

                     E 
                   / | \ 
                  /  |  \
                 E   -   T    <--  - evaluates 3rd 
               / | \     '
              /  |  \    '
             E   +   T   i    <--  + evaluates 2nd 
             '       |    
             '       |
             i       X 
                   / | \
                  /  |  \ 
                 X   ^   Y     <--  ^ evaluates first 
                 '       '
                 '       '
                 i       i
    NOTE:

    in tree  '  means more than one steps 
             '
    ^ has higher precedence 

    because of Left to right associativity + evaluated before then -     

当您开始评估此树时,将首先评估^

记住高优先级运算符总是在底部添加,因此语法应该是以后可以添加运算符(在句子合成中)。

你应该理解为什么你的语法+-可以通过ET直接生成,你可以添加{{ 1}},*。为什么其他明确的版本/E -> E*T | E/T | T不正确!这个语法生成的语言和你的语法是等价的。原因是你的语法生成了正确的树从评估角度来看

此外,如果您正在使用YACC工具编写解析器。你可以使用这个语法的模糊版本,生成规则数量较少,并在语法规则之外指定运算符优先级(这将大致了解首先要评估哪个运算符,因此应该如何构建树)。这将是比这种明确的形式更好的方式,因为较少数量的制作规则在较高的情况下构建较小的树(因此有效的编译器 - 花费较少的时间来解析)。

答案 2 :(得分:2)

这里提供的两个答案都是错误的。在这些答案中,^关联到左边,而实际上它应该与右边相关联。正确修改的语法应该是:

  E -> E+T | E-T | T
  T -> T*X | T/X | X
  X -> F^X | F //Note: it's F^X not X^F
  F -> i | (E)

通过这种方式,您的语法按预期工作,其表达式如下:

a+b^c^d^e*f

谢谢!