如何解决我如何修改我的 EBNF 以处理诸如`- not 12`、`not + -1`
我为下面的表达式创建了 EBNF
<expression> ::= <or_operand> [ "or" <or_operand> ]
<or_operand> ::= <and_operand> [ "and" <and_operand> ]
<and_operand> ::= <equality_operand> [ ( "=" | "!=" ) <equality_operand> ]
<equality_operand> ::= <simple_expression> [ <relational_operator> <simple_expression> ]
<relational_op> ::= "<" | ">" | "<=" | ">="
<simple_expression> ::= <term> [ ( "+" | "-" ) <term> ]
<term> ::= <factor> [ ( "*" | "/" ) <factor> ]
<factor> ::= <literal>
| "(" <expression> ")"
| "not" <factor>
| ( "+" | "-" ) <factor>
<literal> ::= <boolean_literal> | <number>
<boolean_literal> ::= "true" | "false"
<number> ::= <digit> [ <digit> ]
<digit> ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
我的问题出在因子部分
<factor> ::= <literal>
| "(" <expression> ")"
| "not" <factor>
| ( "+" | "-" ) <factor>
您可以看到我包含了三个一元运算符 not
、-
和 +
。它们适用于特定类型,例如 not
仅适用于布尔值,而 +
/-
仅适用于数字。
我不知道如何处理 not
与 +
/-
混合使用的情况,例如 not +7
、- not true
等。有什么办法可以修改语法,使 not
永远不能与 +
/-
混用吗?
够了吗?
<factor> ::= <literal>
| "(" <expression> ")"
| ( "not" | ( "+" | "-" ) ) <factor>
或者也许解析器的工作是解决这个问题?
解决方法
这很容易解决。你有两种不同风格的表达式,每种风格都有自己的语法,所以你不要混合它们,并保持它们的语法规则分开。
布尔表达式只能出现在某些地方,例如赋值或某种选择语句。数值表达式只能出现在比较或赋值中。这不是在语义层面处理的事情,如果看很多语言的语法,就是这样解决的。
所以你有数字表达式:
<simple_expression> ::= <term> [ ( "+" | "-" ) <term> ]
<term> ::= <factor> [ ( "*" | "/" ) <factor> ]
<factor> ::= <number>
| "(" <expression> ")"
| ( "+" | "-" ) <factor>
<number> ::= <digit> [ <digit> ]
<digit> ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
这现在是自包含的。我们现在可以将其构建为布尔表达式:
<boolean_expression> ::= "not" <boolean_expression>
| <logical_expression>
<logical_expression> ::= <or_operand> [ "or" <or_operand> ]
<or_operand> ::= <and_operand> [ "and" <and_operand> ]
<and_operand> ::= <equality_operand> [ ( "=" | "!=" ) <equality_operand> ]
<equality_operand> ::= <simple_expression> [ <relational_operator> <simple_expression> ]
| <boolean_literal>
<relational_op> ::= "<" | ">" | "<=" | ">="
<boolean_literal> ::= "true" | "false"
请注意,我允许布尔文字的相等比较,但是如果您不想允许这样做,您可以更改规则以仅允许它们用于和操作数。
现在我们可以在另一个规则中使用这些,例如赋值:
<assignment> ::= <variable> ":=" ( <simple_expression> | <boolean_expression> )
一切都完成了。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。