带括号的逻辑运算符的上下文无关文法的实现
Implementation of a context-free grammar for logical operators with parentheses
我正在尝试为带括号的逻辑运算符语言实现上下文无关语法,包括运算符优先级。
例如,如下:
{1} or {2}
{1} and {2} or {3}
({1} or {2}) and {3}
not {1} and ({2} or {3})
...
我从以下语法开始:
expr := control | expr and expr | expr or expr | not expr | (expr)
control := {d+}
为了实现运算符优先级和eliminate left recursion,我按以下方式进行了更改:
S ::= expr
expr ::= control or expr1 | expr1
expr1 ::= control and expr2 | expr2
expr2 ::= not expr3 | expr3
expr3 ::= (expr) | expr | control
control := {d+}
但此类语法不支持包含 'and' / [=34= 的示例,例如:({1} 或 {2})和 {3} ] 括号后。
现在,我有以下语法:
S ::= expr
expr ::= control or expr1 | expr1
expr1 ::= control and expr2 | expr2
expr2 ::= not expr3 | expr3
expr3 ::= (expr) | (expr) expr4 | expr | control
expr4 :: = and expr | or expr
control := {d+}
这个语法正确吗?
可以通过某种方式简化吗?
谢谢!
要实现您的运算符优先级,您只需要:
S ::= expr
expr ::= expr or expr1 | expr1
expr1 ::= expr1 and expr2 | expr2
expr2 ::= not expr2 | expr3
expr3 ::= (expr) | control
control := {d+}
这是左递归是为了左关联,因为这通常是您想要的(为了正确性和大多数解析器生成器),但是如果您出于某种原因需要避免左递归,您可以使用右递归右结合文法:
S ::= expr
expr ::= expr1 or expr | expr1
expr1 ::= expr2 and expr1 | expr2
expr2 ::= not expr2 | expr3
expr3 ::= (expr) | control
control := {d+}
因为and
和or
都是结合运算符,所以左右不重要。
在这两种情况下,您都可以通过将 expr3 和控制折叠成 expr2 来“简化”它:
expr2 ::= not expr2 | ( expr ) | {d+}
我正在尝试为带括号的逻辑运算符语言实现上下文无关语法,包括运算符优先级。
例如,如下:
{1} or {2}
{1} and {2} or {3}
({1} or {2}) and {3}
not {1} and ({2} or {3})
...
我从以下语法开始:
expr := control | expr and expr | expr or expr | not expr | (expr)
control := {d+}
为了实现运算符优先级和eliminate left recursion,我按以下方式进行了更改:
S ::= expr
expr ::= control or expr1 | expr1
expr1 ::= control and expr2 | expr2
expr2 ::= not expr3 | expr3
expr3 ::= (expr) | expr | control
control := {d+}
但此类语法不支持包含 'and' / [=34= 的示例,例如:({1} 或 {2})和 {3} ] 括号后。
现在,我有以下语法:
S ::= expr
expr ::= control or expr1 | expr1
expr1 ::= control and expr2 | expr2
expr2 ::= not expr3 | expr3
expr3 ::= (expr) | (expr) expr4 | expr | control
expr4 :: = and expr | or expr
control := {d+}
这个语法正确吗? 可以通过某种方式简化吗?
谢谢!
要实现您的运算符优先级,您只需要:
S ::= expr
expr ::= expr or expr1 | expr1
expr1 ::= expr1 and expr2 | expr2
expr2 ::= not expr2 | expr3
expr3 ::= (expr) | control
control := {d+}
这是左递归是为了左关联,因为这通常是您想要的(为了正确性和大多数解析器生成器),但是如果您出于某种原因需要避免左递归,您可以使用右递归右结合文法:
S ::= expr
expr ::= expr1 or expr | expr1
expr1 ::= expr2 and expr1 | expr2
expr2 ::= not expr2 | expr3
expr3 ::= (expr) | control
control := {d+}
因为and
和or
都是结合运算符,所以左右不重要。
在这两种情况下,您都可以通过将 expr3 和控制折叠成 expr2 来“简化”它:
expr2 ::= not expr2 | ( expr ) | {d+}