例如:
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
抽象对我来说并不那么直观。(我不太明白它们是如何制作的)
规范化此类表达式时是否有任何步骤?
答案 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,插入符号是正确关联的。”