如何编写与空语言匹配的弹性模式?

How can I write a flex pattern that matches the null language?

考虑以下 flex 扫描仪:

IdentifierNonDigit {Nondigit}|{UniversalCharacterName}|{ImplementationDefinedChars}
Nondigit [_a-zA-Z]
HexDigit [0-9a-fA-F]
HexQuad {HexDigit}{4}
UniversalCharacterName (\u{HexQuad})|(\U{HexQuad}{2})
Digit [0-9]
%%
{IdentifierNonDigit}({IdentifierNonDigit}|{Digit})+ ;
%%

此扫描程序生成错误,因为没有名称 ImplementationDefinedChars 的定义。我如何定义 ImplementationDefinedChars 以便它匹配空语言?等价地,我如何定义 ImplementationDefinedChars 以便 IdentifierNonDigit 的定义等同于 IdentifierNonDigit {Nondigit}|{UniversalCharacterName}

注意我不是在问如何匹配空字符串。我在问如何制作一个不匹配任何字符序列的模式。

我想以这种方式编写我的扫描器的原因是我打算根据我尝试对 lex 标识符进行 lex 标识符的 C 变体动态插入不同的可能值来定义 ImplementationDefinedChars。但是,我不清楚如何使用未在标识符中定义任何实现定义字符的 C 变体来实现这一点。

理论上,您可以使用 flex 的集差运算符 {-} 定义一个空字符 class。我不知道这是否真的不合法——手册上说“小心不要不小心创建一个空集,它永远不会匹配”,这留下了故意这样做的可能性——但我担心 它可能会触发错误或警告(可能在未来的某个版本中)。

另一方面,对两个相同或重叠的操作数使用联合运算符 | 没有问题。所以您可以自由使用默认定义,例如:

ImplementationDefinedChars    {NonDigit}

(F)lex 定义实际上是宏替换(但 flex 与 lex 不同,通常用括号将宏扩展括起来以避免意外)。您不能动态定义它们,除非您计划动态重新生成扫描器然后动态编译它。也许那是你一直以来的计划。