我有一个表示表达式的语法。为简单起见,假设它是:
S -> E
E -> T + E | T
T -> P * T | P
P -> a | (E)
, a
, +
,*
和是我的字母表中的字母(
。)
上述规则可以使用正确的运算顺序和关联性生成包含括号、乘法和加法的有效算术表达式。
我的目标是接受每个字符串,其中包含 0 个或更多字母。这是我的限制:
- 语法必须“接受”所有包含 0 个或多个字母的字符串。
- 可以通过算法引入新终端并将其插入到输入中。(我发现
EOF
,出于某种原因,在检测到超出其他有效表达式的额外标记时,显式提供终端会有所帮助。) - 可能会引入新的生产规则。新规则将是错误标志(即,如果使用 1 解析字符串,那么尽管字符串被接受,但在语义上被认为是错误)。
- 可以修改产生规则以便插入新引入的终端。
- 语法应该是 LALR(1),至少可以由 Lex/Yacc 类工具处理(如果我记得悬空的 else 问题需要非 LALR(1),尽管与 Lex/Yacc 兼容)。
此外,我希望额外的规则对应于不同类型的错误(缺少二进制操作的参数、缺少括号 - 左或右 - 超出其他可接受的表达式的额外标记等)。我这么说是因为可能有一些简单的方法可以回答我的问题以“接受”所有输入,否则这些输入对错误报告无益。
我发现这些规则很有用,尽管我不知道它们是否违反了我的约束:
P -> @ [error]
P -> (E [error]
S -> E $ [instead of S -> E]
S -> E X $ [error]
X -> X Y [error]
X -> Y [error]
Y -> a [error]
Y -> ( [error]
Y -> ) [error]
Y -> * [error]
Y -> + [error]
where$
是显式EOF
标记,@
是空字符串。
如果我的问题不清楚:如何在我的约束范围内修改我的语法以实现接受所有输入的目标,最好是规则与错误类型的良好对应?我的规则是否符合我的目标?