programming-languages - 我如何修改我的 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
与+
/ -
like 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"
请注意,我允许布尔文字的相等比较,但是如果您不想允许这样做,您可以更改规则以仅允许它们用于 and 操作数。
现在我们可以在另一个规则中使用它们,例如赋值:
<assignment> ::= <variable> ":=" ( <simple_expression> | <boolean_expression> )
一切都完成了。
推荐阅读
- sql - SQL 外键帮助。ORA-00907 缺少右括号
- javascript - 为每个对象创建唯一 ID
- java - 未找到 XPathFactory 实现,ubuntu 服务器中的 xpath 工厂实例创建问题。如何解决问题?
- c++ - 使用 KissFFT 获取频域图像并返回
- javascript - 角度服务工作者缓存的 index.html
- java - 文本。无需删除先前数据即可添加的文件
- python-3.x - Fresh Anaconda 安装给出“ImportError: cannot import name 'constants' from 'zmq.backend.cython'”
- python - 在多个 GPU 上训练会导致 Keras 中的 NaN 验证错误
- javascript - 如何让异步/等待等待我的嵌套数组填充
- r - 如何使用确认选择按钮根据上面现有数据表中的行选择生成和显示新数据表