【翻译阶段】预处理记号的最长字符序列处理

最大吞噬 (maximal munch)

阶段 3.标记化(Tokenization)将输入分析为预处理记号,到某个给定字符为止时,一般将可构成一个预处理记号的最长字符序列处理成下一个预处理记号,即便这会致使后继分析失败也是如此。这常被称为最大吞噬 (maximal munch)spa

int foo = 1;
int bar = 0xE+foo;   // 错误:非法的预处理数字 0xE+foo
int baz = 0xE + foo; // OK
 
int quux = bar+++++baz; // 错误:bar++ ++ +baz,而非 bar++ + ++baz。

最大吞噬规则的惟一例外是:.net

  • 若下一个字符所开始的字符序列可做为原始字符串字面量的前缀和起始双引号,则下个预处理记号应当为原始字符串字面量。该字面量由匹配原始字符串模式的最短字符序列组成。
#define R "x"
const char* s = R"y"; // 非良构的原始字符串字面量,而非 "x" "y"
const char* s2 = R"(a)" "b)"; // 原始字符串字面量后随普通字符串字面量
  • 若其后三个字符是 <::,然后继字符既非 : 亦非 >,则把 < 自身当作预处理记号(而非代用记号 <: 的首字符)。
struct Foo { static const int v = 1; };
std::vector<::Foo> x; // OK,<: 未被看成 [ 的代用记号
extern int y<::>;     // OK,同 extern int y[]。
int z<:::Foo::value:>; // OK,int z[::Foo::value];
(C++11 起)
  • 头文件名预处理记号仅在 #include 指令中造成。
std::vector<int> x; // OK,<int> 不是头文件名
相关文章
相关标签/搜索