我已经为我计划在以后的项目中使用的预处理器语言编写了tokenizer和表达式求值程序。我开始想我也许应该用EBNF(Extended Backus-Naur Form)来描述语言,以保持语法更易于维护,甚至用它来生成解析器的更高版本。
我的第一印象是EBNF用于标记化过程和语法验证。后来我发现它也可以用来描述in this post或Wikipedia article中的运算符优先级:
expression ::= equality-expression
equality-expression ::= additive-expression ( ( '==' | '!=' ) additive-expression ) *
additive-expression ::= multiplicative-expression ( ( '+' | '-' ) multiplicative-expression ) *
multiplicative-expression ::= primary ( ( '*' | '/' ) primary ) *
primary ::= '(' expression ')' | NUMBER | VARIABLE | '-' primary
我可以看到如何允许生成器生成内置运算符优先级的代码,但这究竟应该如何表达优先级?运算符优先级更多是关于语义还是关于语法的EBNF?如果我决定在EBNF中编写我的语言描述,我应该在考虑运算符优先级的情况下编写它还是在单独的部分中记录它?
答案 0 :(得分:5)
为我的同事学位做了类似的事情。
我建议不要使用运算符优先级功能,即使看起来比较简单,例如" syntact sugar"。
大多数语言将由EBNF描述,使用许多具有不同功能的运算符,这些运算符更好地描述&更新,使用EBNF表达式,而不是运算符优先级。
一些运算符是一元前缀,一些是一元posfix,一些是二进制(a.k.a。" infix"),一些二进制从左到右进行评估,&有些是从右到左进行评估的。某些符号在某些上下文中是运算符,在其他上下文中用作其他标记,例如" +"," - ",可以是二元运算符(" x - y"),一元前缀运算符(" x - -y"),或文字的一部分(" x + -5")。
根据我的经验,它更安全"用EBNF表达式描述它们。除非您描述的编程语言非常小,只有很少和类似的语法运算符(例如:所有二进制或所有前缀一元)。
只需2美分。