如何修改EBNF规则禁止not与一元+/-运算符混合使用?
EBNF一元运算符混用限制问题解答
你提供的修改方案没有任何作用,修改后的规则和原始规则语义完全等价,只是将两条一元运算符分支合并为一条,并没有限制不同类型一元运算符的嵌套关系,仍然允许not后接带+/-的因子,也允许+/-后接带not的因子,无法拦截not +7、- not true这类非法表达式。
如果你想要在EBNF语法层面就禁止两类一元运算符混用,可以将因子按类型拆分,区分布尔类因子和数值类因子,分别定义允许的一元运算符,修改后的规则如下:
-- 拆分原factor为布尔因子和数值因子两类 <factor> ::= <bool_factor> | <numeric_factor> <bool_factor> ::= <boolean_literal> | "(" <expression> ")" | "not" <bool_factor> <numeric_factor> ::= <number> | "(" <expression> ")" | ( "+" | "-" ) <numeric_factor> -- 其余原有规则保持不变即可
该方案的特点:
- 优势:在语法解析阶段就能直接识别非法表达式,抛出语法错误,不需要后续流程处理
- 劣势:会让语法规则变得冗余,后续如果新增类型、新增一元运算符,需要同步调整规则,维护成本较高
这类问题本质属于类型校验的职责范畴,不需要修改语法规则。语法规则只负责定义表达式的结构合法性,not +7这类表达式结构上是合法的,只是类型不匹配。更合理的处理流程是在解析生成抽象语法树(AST)之后,在类型检查阶段遍历AST做校验:遇到not运算符就检查其操作数的求值类型是否为布尔值,遇到+/-一元运算符就检查其操作数的求值类型是否为数值,不匹配则抛出类型错误即可。
内容的提问来源于stack exchange,提问作者The Rizzler
相关产品推荐
相关产品推荐

