问题描述
我想用Backus-Naur-Form编写这些布尔表达式。
我得到的是:
:: = | |
:: =
| |
:: =
:: = |
我使用 进行了恢复,以便每当有方括号时都会启动一个新实例,但是我仍然不知道何时关闭方括号。有了这个,您就可以设置一个右括号并创建一个新实例,但是我只想用它来作为右括号。
我可以在和中分开吗? 我的Backus-Naur表格正确吗?互联网上关于带布尔布尔代数的Backus-Naur形式的信息很少。这样的解析树是什么样的?
解决方法
我假设您想使用Backus-Naur形式为布尔表达式定义语法,并且您的示例是此类表达式的具体实例。您的语法有多个问题:
首先,您希望语法仅生成正确的布尔表达式。使用语法,您可以使用路径∨
生成一个简单的运算符<variable> -> <operator> -> <OR>
作为有效表达式,这显然是错误的,因为该运算符缺少其操作数。换句话说,∨
本身不能是正确的布尔表达式。语法可能会衍生出各种其他不正确的表达式。出于同样的原因,在生产规则中,左括号和右括号应一起出现,因为您要确保每个左括号都有一个右括号。将它们放在单独的生产规则中可能会破坏这种保证,具体取决于您语法的总体结构。
第二,您要区分非终端符号(通过生产规则精炼的符号,即写在<
和>
之间的符号)和终端符号(如变量的原子符号) p
,q
,r
和s
)。因此,您的非终端符号<p>
,<q>
,<r>
和<s>
应该是终端符号p
,q
,{{1} }和r
。括号和运算符等其他符号也是如此。
第三,为了获得明确的解析树,您希望正确地确定运算符的优先级和关联性,即,您要确保例如在求和之前对求反求值,因为它具有更高的含义。优先级(类似于算术表达式,其中必须在加法之前求出乘法)。换句话说,我们希望具有较高优先级的运算符看起来更接近解析树的叶子节点,而具有较低优先级的运算符则看起来更接近树的根节点,因为首先要评估树的叶子。我们可以通过以递减的方式反映运算符优先级的方式定义语法来实现:
s
从<expression> ::= <expression> ↔ <implication> | <implication>
<implication> ::= <implication> → <disjunction> | <disjunction>
<disjunction> ::= <disjunction> ∨ <conjunction> | <conjunction>
<conjunction> ::= <conjunction> ∧ <negation> | <negation>
<negation> ::= ¬ <negation> | <variable> | ( <expression> )
<variable> ::= p | q | r | s
开始,我们可以看到一个有效的布尔表达式首先将所有<expression>
运算符链接在一起,然后是所有↔
运算符,然后是所有→
运算符,依此类推。因此,优先级较低的运算符(例如∨
)位于树的根附近,而优先级较高的运算符(例如↔
)则位于树的叶子附近。
请注意,上面的语法是左递归的,这可能会导致无法处理它们的软件工具(例如解析器生成器)出现一些问题。