BNF 和 EBNF 表示法中是否允许使用正则表达式?

Are regexs allowed in BNF and EBNF notations?

例如,如果我想定义 Lisp 编程语言,其中名称甚至可以包含非字母数字字符,我是否应该使用如下符号列出所有可用字符:

validchar ::= "a" | "b" | "c" ... "-" | "*" | "$" ... ;
name = validchar, (validchar | digit)+;

或者我可以使用正则表达式,例如:

validchar ::= "[^(^)^\s^\d]";
name ::= validchar, (validchar | digit)*;

甚至:

name ::= "[^(^)^\s^\d]", "[^(^)^\s]"*;

这样会缩短很多,甚至会包括₩,¥,€等字符,我不能列出但实际上可以使用。

这是否允许取决于您使用的实现 (E)BNF 表示法的工具。

一些工具相当严格并坚持 (E)BNF 的原始定义,最多允许在语言标记上使用 Kleene * 或 +。另外一点是经典的 (E)BNF 没有要求将字符作为终端进行操作。

很明显,能够直接根据字符定义一些语言标记是很方便的,并且可以想象(正如你所拥有的)一个 EBNF,其中不仅可以将字符作为终端,还可以对字符进行正则表达式.

您建议使用的工具是否允许...完全取决于工具。许多处理 (E)BNF 的工具,例如 YACC,实际上被设计为与另一个工具一起工作,一个 "lexer generator"(对于 YACC,这称为 FLEX)定义了标记的字符序列。对于这样的工具对,(E)BNF 工具通常不允许在它们之上提及任何字符或正则表达式,但词法分析器生成器工具明确允许标记的字符和正则表达式规范。

有数百种 (E)BNF 和词法分析器生成器工具,每个工具都有一些(截然不同的)规则。查看工具文档。

或者按照您想要的方式编写,并构建您自己的(第 101 个)工具。