就我所見,沒有任何理由讓預處理器詞法分析器在include指令中查看文件名作爲除了不透明序列的字符以外的其他任何文件。確切的名稱與預處理器無關;它可能不包含任何擴展名或多個.
(前提是操作系統允許這樣做,現在這些操作系統最多);它可能包含特殊字符,如斜槓;它可能是一個數字;等等。
此外,角括號和引號的處理在include指令的參數內是特異的。因此,處理include指令的常用方法是使用上下文敏感模式,例如使用(f)lex start conditions。
由於換行符在所有的預處理指令中也被特別處理,您通常也需要一個上下文相關的模式。
使用flex語法的粗略草圖。很多細節被遺漏。
%x PP_DIRECT PP_ARG PP_INCLUDE
%%
^[[:blank:]]*"#" { BEGIN(PP_DIRECT); }
<PP_DIRECT>include { BEGIN(PP_INCLUDE); return T_INCLUDE; }
/* You might want to recognize other include directives as
* specific keyword tokens. In particular, the scanner needs
* to be aware of conditionals, since it might have to put itself
* into a mode where it skips to the matching #endif
*/
<PP_DIRECT>[[:alpha:]]+ { BEGIN(PP_ARG); /* ... */ }
/* Normally newlines are not returned to the parser, but here we do. */
<PP_ARG>\n { BEGIN(INITIAL); return '\n'; }
/* This should actually be done in a previous step */
<PP_ARG>\\\n /* IGNORE */
<PP_INCLUDE>["][^"]*["] { yytext[yyleng-1] = 0;
do_include(yytext+1);
/* Really, should check that only whitespace follows */
BEGIN(PP_ARG);
}
<PP_INCLUDE>[<][^>]*[>] { yytext[yyleng-1] = 0;
do_system_include(yytext+1);
BEGIN(PP_ARG);
}
謝謝。我不知道上下文敏感的語法,以前的在線搜索是徒勞的。非常感謝 – Sharad
@sharad:您可能還想查看[多個緩衝區上的flex手冊部分](http://flex.sourceforge.net/manual/Multiple-Input-Buffers.html#Multiple-Input-Buffers),其中有使用緩衝區堆棧實現「包含」功能的示例代碼。 – rici