你如何将一些表达抽象为BNF?

时间:2011-07-24 05:50:06

标签: bnf

例如:

waldo:=fern+alpha/-beta^gamma;

上述算术表达式可能会被这个BNF抽象出来(可能与标准BNF有所不同,但暂时忽略它):

AEXP = AS $AS ;

AS = .ID ':=' EX1 ';' ;

EX1 = EX2 $( '+' EX2 / '-' EX2 ) ;

EX2 = EX3 $( '*' EX3 / '/' EX3 ) ;

EX3 = EX4 $( '^' EX3 ) ;

EX4 = '+' EX5 / '-' EX5 / EX5 ;

EX5 = .ID / .NUMBER / '(' EX1 ')' ;

.END

EX1~EX5抽象对我来说并不那么直观。(我不太明白它们是如何制作的)

规范化此类表达式时是否有任何步骤?

1 个答案:

答案 0 :(得分:1)

您可以直接将此表示法转换为EBNF。

命名类别EX1到EX5并不是指定运算符优先级的罕见方法。实际上它是一个很好的,恕我直言,特别是在一些语言中有15个或更多的优先级,比如C和C ++。 :)

您可以将它们重命名为表达式,术语,因子,主要等等(或任何对您有意义的术语)。

附录

如果您需要将上述内容翻译成更传统的EBNF,我将采用以下方式:

AEXP => AS+
AS   => id ':=' EX1 ';'
EX1  => EX2 (('+' | '-') EX2)*
EX2  => EX3 (('*' | '/') EX3)*
EX3  => EX4 ('^' EX3)*
EX4  => ('+'|'-')? EX5
EX5  => id | number | '(' EX1 ')'

我将'*'用于零或更多,'+'用于一个或多个,以及'?'可选。我认为,在这里处理运算符优先级非常酷。

ADDENDUM 2:

请注意:看来EX3的规则是错误的。它现在的方式你可以得到像这样的解析树

                  EX3
                   |
     +---+----+----+----+---------+
     |   |    |    |    |    |    |
    EX4  ^   EX3   ^   EX3   ^   EX3
            / | \               / | \
         EX4  ^  EX3         EX4  ^  EX3

所以写a^b^c^d^e^f可能意味着a^(b^c)^d^(e^f)。但实际上还有其他方法来制作这棵树。语法含糊不清。

似乎语法的设计者想要使^运算符成为右关联的。但要这样做,规则应该是

EX3 => EX4 ('^' EX3)?

现在语法不再含糊不清。看看a^b^c^d^e^f的推导现在必须如何进行:

          EX3
         / | \
      EX4  ^  EX3
             / | \
          EX4  ^  EX3
                 / | \
              EX4  ^  EX3
                     / | \
                  EX4  ^  EX3
                         / | \
                      EX4  ^  EX3

现在a^b^c^d^e^f只能解析为a^(b^(c^(d^(e^f))))

另一种方法是将规则重写为EX3 => EX4 ('^' EX4)*,并有一个侧面规则,说“OBTW,插入符号是正确关联的。”