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

问题描述

请考虑以下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标识符的C变体为ImplementationDefinedChars的定义动态插入不同的可能值。但是,我不清楚如何使用C变体来实现此功能,该变体未在标识符中定义任何实现定义的字符。

解决方法

理论上,您可以使用flex的集合差异运算符{-}定义一个空字符类。我不知道这是否真的合法-手册上写着“小心不要意外地创建一个永远不会匹配的空集”,这使得故意进行此操作的可能性不大-但是我担心 它可能会触发错误或警告(可能在将来的版本中)。

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

ImplementationDefinedChars    {NonDigit}

(F)lex定义实际上是宏的替代(但flex与lex不同,通常将其用括号括起来,以避免出现意外情况)。您不能动态定义它们,除非您打算动态重新生成扫描仪然后进行动态编译。也许那一直是你的计划。