问题描述
请考虑以下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不同,通常将其用括号括起来,以避免出现意外情况)。您不能动态定义它们,除非您打算动态重新生成扫描仪然后进行动态编译。也许那一直是你的计划。