先看一下在打開文件裏用到的一個函數 lua_setinput
數據結構
void lua_setinput (Input fn) { current = ' '; input = fn; if (yytext == NULL) { textsize = MINBUFF; yytext = newvector(textsize, char); } }
設置當前是的輸入字符爲空格。
設置函數指針,函數指針的定義爲:
typedef int (*Input) (void);
即:函數指針指向一個無參的函數,返回一個整數類型。
若是 yytext 爲空,則設置其大小,並給它分配內存。newvector 內存分配宏,在 mem.h 中定義。Lua2.4 中的內存分配相關方法都在 mem.h 中聲明。
函數
char *lua_lasttext (void) { *yytextLast = 0; return yytext; }
在語法錯誤時會調用到它,以獲取出錯處的輸入文本。
lua
static struct { char *name; int token; } reserved [] = { {"and", AND}, {"do", DO}, {"else", ELSE}, {"elseif", ELSEIF}, {"end", END}, {"function", FUNCTION}, {"if", IF}, {"local", LOCAL}, {"nil", NIL}, {"not", NOT}, {"or", OR}, {"repeat", REPEAT}, {"return", RETURN}, {"then", THEN}, {"until", UNTIL}, {"while", WHILE} }; #define RESERVEDSIZE (sizeof(reserved)/sizeof(reserved[0])) void luaI_addReserved (void) { int i; for (i=0; i<RESERVEDSIZE; i++) { TaggedString *ts = lua_createstring(reserved[i].name); ts->marked = reserved[i].token; /* reserved word (always > 255) */ } }
定義保留字,或叫關鍵字。
結構體 name 字段是名字,token 是保留字的值。保留字的值在詞法分析的時候會用到。
luaI_addReserved 把全部保留字添加到全局字符串中去。同時設置其爲不可回收,也就是把 TaggedString 的 marked 字段設置爲上面提到的保留字的值。
luaY_lex 是詞法分析的主要部分,它內部是一個循環,輸入中的字符一經詞法分析以後變成一個個的 token. token 有幾種:
一個整數值,在 parser.c 中定義的一些宏,好比 WRONGTOKEN, IF, THEN 之類的, 直接表示它本身的,就是看到這個整數值,它的意思明確的表示了本身.
一個整數值和一個表示內容的數據結構 YYSTYPE luaY_lval,像 NAME, NUMBER 就是此類. 好比 NUMBER,返回一個這個類型則只知道 token 是一個數值,至於具體數值是什麼,要看 luaY_lval 的 vFloat 字段.
luaY_lex 就不一行一行的看了,裏面相對沒有什麼難點,照着每一個 switch case 一點點來就好。注意就是這裏面的和長字符串表示,就是由兩個左中括號起頭的字符串,這裏是特別處理,長字符串中的內容所有保持原樣。
詞法分析先到這裏了。
----------------------------------------
記一下到目前爲止的問題:
lex.c
> newvector 內存分配相關的方法
> lua_createstring 是什麼? TaggedString 是個什麼數據結構?
> luaI_codedebugline 是什麼? 調試相關信息有哪些?
inout.c
> luaI_createfixedstring 是什麼? 那個 TaggedString 是個什麼數據結構?
luac.c
> do_compile 裏的 TFunc 是什麼?那個初始化 luaI_initTFunc 是什麼?
> lua_parser 是什麼? do_dump 方法裏調的那幾個方法又分別是幹什麼的?
----------------------------------------
debug