【翻譯階段】預處理記號的最長字符序列處理

最大吞噬 (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> 不是頭文件名
相關文章
相關標籤/搜索