歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux綜合 >> Linux資訊 >> Linux文化 >> 如何處理C的預處理?

如何處理C的預處理?

日期:2017/2/27 12:09:57   编辑:Linux文化

>>> 此貼的回復 >> 語法分析和詞法分析 有專門的工具.LEX,YACC. 你可以找相關的資料看一下.

至於此問題.為何非要預處理 而不封裝成函數?

>>> 此貼的回復 >> >> 函數宏的處理比較麻煩,因為它有語法.如果作為語法處理 預處理就是簡單的宏替換, #指令解析等, 處理完畢的結果才作為詞法分析的輸入文件, 完全不涉及詞法、語法分析的操作啊。

>>> 此貼的回復 >> 根據我的經驗: C的宏處理完全是詞法分析的范疇,gcc調用預處理器cpp將所有包含文件和源文件進行預處理之後生成一個.i的中間文件,再將這個中間文件傳遞給cc1進行編譯. 可以使用-v選項觀察gcc編譯過程. 另外,預處理並不僅僅處理宏展開. 關於宏的展開可以參考gcc源代碼: 下面的代碼來自gcc-1.35的cccp.c

CODE:[Copy to clipboard]/* Structure allocated for every #define. For a simple replacement such as #define foo bar , nargs = -1, the `pattern' list is null, and the expansion is just the replacement text. Nargs = 0 means a functionlike macro with no args, e.g., #define getchar() getc (stdin) . When there are args, the expansion is the replacement text with the args squashed out, and the reflist is a list describing how to build the output from the input: e.g., "3 chars, then the 1st arg, then 9 chars, then the 3rd arg, then 0 chars, then the 2nd arg". The chars here come from the expansion. Whatever is left of the expansion after the last arg-occurrence is copied after that arg. Note that the reflist can be arbitrarily long--- its length depends on the number of times the arguments appear in the replacement text, not how many args there are. Example: #define f(x) x+x+x+x+x+x+x would have replacement text "++++++" and pattern list { (0, 1), (1, 1), (1, 1), ..., (1, 1), NULL } where (x, y) means (nchars, argno). */ /* 對每個#define 分配的結構. 對於簡單的替換例如: #define foo bar , nargs = -1 , `樣式' 列表(見結構體定義中的pattern list) 為空, expansion ( 見結構體中的expansion 定義) 僅僅是替換文本. Nargs=0 意味著一個不帶參數的函數類似的宏定義, 例如: #define getchar() getc(stdin). 當存在參數的時候, expansion 是不帶任何參數的替換文本, 並且reflist 是一個描述如何從輸入構建輸出的列表: 例如: " 三個字符, 然後第一個參數, 之後久個字符, 之後第三個參數, 之後零個字符, 之後第二個參數." 這裡的字符來自expansion. Whatever is left of the expansion after the last arg-occurrence is copied after that arg. 注意: reflist 可以是任意長度: 它的長度依賴於參數在替換文本中出現的次數, 而不是到底有多少參數, 例如: #define f(x) x+x+x+x+x+x+x 將會有替換文本"++++++" 和樣式列表: { (0, 1), (1, 1), (1, 1), ..., (1, 1), NULL } 這裡的(x,y) 的意義是(nchars,argno) 即(字符數, 參數序號) */ typedef struct definition DEFINITION; struct definition { int nargs; int length; /* length of expansion string */ /* expansion string 的長度*/ U_CHAR *expansion; /* expansion string*/ struct reflist { struct reflist *next; char stringify; /* nonzero if this arg was preceded by a # operator. */ /* 非零, 如果這個參數之前有# 操作符*/ char raw_before; /* Nonzero if a ## operator before arg. */ /* 非零如果一個## 在這個操作符前*/ char raw_after; /* Nonzero if a ## operator after arg. */ /* 非零如果一個## 在這個操作符後*/ int nchars; /* Number of literal chars to copy before this arg occurrence. */ /* 在這個參數出現之前需要復制的字符數*/ int argno; /* Number of arg to substitute (origin-0) */ /* 需要替換的參數的序號(初始為0) */ } *pattern; /* pattern list */ /* 樣式列表 */


Copyright © Linux教程網 All Rights Reserved