配置檔案解析的編譯性

2021-05-24 23:18:22 字數 3152 閱讀 7041

序:貌似很久沒有寫博文了,到這回有兩年之隔了~上回聽10屆畢業同僚們的找工作交流之談,說寫博文很

重要,要養成這個習慣,可是每次想寫的時候都會給自己找一大堆的理由說服自己沒有時間

;後來想想,這與在紙上做筆記是同乙個性質,同等重要:即記下當時的某種想法或為這段時間的學習而作總結。正好這兩年把記錄本都耗光了,所以以後還是改用電子版吧,同時還可以方便地進行歸類以及與別人分享和討論。

一、 編譯是這樣乙個過程:從原始檔中取出有意義的詞,並按照事先約定好的規則對它們可能的組合進行檢測,與此同時對每乙個合法組合翻譯成目標語言的句子,最後將生成的目標語言檔案輸入直譯器進行執行;

雖然編譯的每個過程中都有一套相應的理論對分析進行支撐,但是

編譯器實現仍然是個非常龐大且複雜的工作,所以目前所使用的編譯器都是由一些非常專業的人來實現,它們的數量隨程式語言數量的增加而增加,所以需求量很穩定。

即使在這種幾乎沒有什麼實現需求的情況下,電腦科學與技術仍將「編譯原理」列為基礎課中非常重要的一門;因為它讓讀者有了運用前面所學的資料結構以及其它與程式設計相關的知識的機會之外,還讓讀者學到了處理某類問題的方法和程式

實現框架。目前,我所知道的編譯原理主要應用領域有對dfa/nfa狀態機的使用(比如模式匹配)以及對配置檔案的解析(現在絕大多數開源軟體都是通過解析配置檔案來獲取配置引數)。

詞法分析就是從待分析的文字中獲取有意義的單詞(比如常數,變數);但在實現之前,需要對源語言中可能出現的單詞進行分類,其實,稍微想想就能發現這些單詞就是在後面進行語法分析時所謂的終結符;待單詞分類之後,就可以使用dfa對它們進行描述了,這帶來的好處是我們可以很容易根據dfa的狀態轉移圖來實現程式,這就是規律:if 轉移條件1 else if

轉移條件1 ...

else if 轉移條件n,而在轉移的過程中來獲取對應的單詞;因為語法分析的過程就是檢查某些單詞所組成的語法單元是否符合構成源語言句子結構的規定的,所以它不管你獲取的單詞具體是什麼內容,它只管構成某一條源語句的這些單詞都是些什麼型別,比如「 變數 = 數字 」這種賦值語句,而不管它具體是什麼(a=2);所以在獲得具體單詞內容的同時還需要使用某乙個全域性變數來記錄獲得這個單詞的型別以供語法分析時使用。

語法分析就是檢查待分析檔案內容合法性的過程,同樣,為了能夠更好地進行程式實現,需要文法這種符號集來對語法進行描述(目前只懂ll(1)文法以及自上而下的分析方法)。ll中第乙個l表示從左至右掃瞄源程式的每一行,而第二個l表示最左推倒(即在進行文法匹配時總是左起第乙個非終結符),而自上向下的含義就是從原始檔的第一行開始分析直至最後一行。在這個分析過程中,如果不能確定使用哪一條文法中的推倒規則進行分析的話就會出現遞迴的現象(即)。所以在實現之前需要將這種文法進行化簡以及消除遞迴,ll(1)文法即滿足這種條件的文法:

1、無直接或間接左遞迴

2、推倒規則左部的所有右部first集不相交;

3、含有ε推倒結果的推倒規則右部(非終結符),其first集與fellow集的交集為空

只要使用ll(1)文法對整個語法結構進行描述之後,就可以使用一種規定的程式框架(遞迴下降分析法)進行實現。這又是乙個規律!

二  配置檔案解析器的實現

1、文法如下:

/*配置檔案文法:(忽略空格和製表符、注釋行和空白行)

* config->(#anystring/n)* |exp * | (/n)*

* exp->name=value exp'

* exp'->/n | #anysting(/n|eof)| eof「

即乙個配置檔案的每一行有如下例子描述的四種情況:

#########注釋符為」#「##########

(n個空格)qq = 32371323

(空行)

(n個製表符) username = value #注釋只能在開頭或最後

2、終結符有: 保留字(qq,

username

)  ,value,"=",注釋符(#),換行符(dfa就不畫了,很簡單)

三、部分實現原始碼:

1、 詞法分析:

[ code=c/c++ ]

static void getword()

while(global.line[global.j]==' '||global.line[global.j]=='/t') global.j++;  //跳過製表符和空格

if(global.line[global.j]=='#')

else if(global.line[global.j]=='/n')

else if(global.line[global.j]=='=')

elsewhile(global.line[global.j]!=' '&&global.line[global.j]!='/n'&&global.line[global.j]!='/0');  //規定每乙個詞之間必須用空格進行間隔

temp[i]='/0';  //字串結束符

if(isresv(temp))

else

del(temp);} }

[ /code]

2、對應於

config->(#anystring/n)* |exp * | (/n)*的語法分析部分:

int  parse_config(char * filename,config_t* config)  //去除空行和注釋行

assignment(config);

}if(global.errmsg->line_num!=0)

else return 0; //parse succ}

3、對應於

* exp->name=value exp'和* exp'->/n | #anysting(/n|eof)| eof「的語法分析部分:

注:這裡不是很嚴格地按照乙個非終結符需要一段**來實現這麼一條說法來的

static void assignment(config_t* config)else error("need a value");

}else error("need an equal");

}else error("need a name or not recognized");

getword();

if(feof(global.fd))

if(global.sym==ret ||global.sym==comment)

getword();

else error(" comment or return is ok here");}

Redis 配置檔案的解析

1.units單位 配置大小單位,開頭定義了一些基本的度量單位,只支援bytes,不支援bit,對大小寫不敏感 2.includes包含 和我們的struts2配置檔案類似,可以通過includes包含,redis.conf可以作為總閘,包含其他 3.general通用 daemonize 將no改...

spring mvc配置檔案的解析

1.它的作用是隱式地向 spring 容器註冊 autowiredannotationbeanpostprocessor commonannotationbeanpostprocessor persistenceannotationbeanpostprocessor requiredannotati...

nginx的配置檔案解析

今天有一位同學問到 nginx 的站點多路徑匹配的問題?1.www.domain.com a需要返回 var www domain.com a index.html 2.www.domain.com b需要返回 var www domain.com b index.html 如何配置 nginx 使...