背景 正則表達式
閒來無聊,抽空寫篇博客對flex,bison這兩個小工具進行介紹一下。工具自己的用途我不在此贅述。因爲本身曾經作過配置文件的解析的工做,深知其中的艱辛與痛苦。flex,bion的出現,爲本身解決這類問題打開了另一扇門。固然,若是拿flex,bison來解析我用到的這些配置文件,有點小題大作了。因此,這個地方,我選擇瞭解析json文本。選擇解析json文本的緣由是你們在平時作應用層工做時候確定會用獲得,並且,json文本自己的格式並非太複雜。 json
本文在協做的過程當中,最初參考了costaxu的這篇文章(http://my.oschina.net/costaxu/blog/107714)。在此表示感謝。因爲是做爲探索性的嘗試,並無徹底實現對json的解析,以及封裝成爲可供上層調用的庫。但整個框架已經可以應用到實際的項目中。 框架
分詞 函數
分詞使用的是flex工具,其腳本以下:(文件名爲json.fl) 工具
%{ #include "stdio.h" #include "json.tab.h" int yywrap(void) //自定義此函數,是應用程序徹底脫離對flex庫的依賴 { return 1; //返回默認值1 } %} VALUE_INT [-]?[1-9]+[0-9]* VALUE_FLOAT [-]?[1-9]+[0-9]\.[0-9]+ VALUE_STRING [_a-zA-Z]+[_a-zA-Z0-9]+ IGNORE [ \t\r\n] %% \" return QUOTE; \, return COMMA; \[ return BRACE_LEFT; \] return BRACE_RIGHT; \{ return BRACEETS_LEFT; \} return BRACEETS_RIGHT; \: return COLON; {VALUE_STRING} yylval = strdup(yytext); return VALUE_STRING; {VALUE_FLOAT} return VALUE_FLOAT; {VALUE_INT} return VALUE_INT; {IGNORE} %%
目前,只對三種數據類型,int,float,string類型做了處理,並且string的正則表達式也有待改進。 flex
詞法分析 spa
詞法分析使用的是bison工具,其內容以下(文件名爲json.y) .net
%{ #include <stdio.h> #include <string.h> void yyerror(const char* s) { printf("ERROR:%s\n",s); } int main() { FILE * infp = NULL; infp = fopen("config.file","r"); yyrestart(infp); yyparse(); fclose(infp); return 0; } %} %token QUOTE COMMA BRACE_LEFT BRACE_RIGHT BRACEETS_LEFT BRACEETS_RIGHT COLON VALUE_STRING VALUE_FLOAT VALUE_INT %% root: | BRACEETS_LEFT items BRACEETS_RIGHT ; items: | items COMMA item | item ; item: item_int | item_float | item_string | item_item ; item_int: QUOTE VALUE_STRING QUOTE COLON VALUE_INT { printf("Model item_int![Name:%s]\n",$2); } ; item_float: QUOTE VALUE_STRING QUOTE COLON VALUE_FLOAT { printf("Model item_float![Name:%s]\n",$2); } ; item_string: QUOTE VALUE_STRING QUOTE COLON QUOTE VALUE_STRING QUOTE { printf("Model item_string![Name:%s]\n",$2); } ; roots: | roots COMMA root | root ; item_item: QUOTE VALUE_STRING QUOTE COLON BRACE_LEFT roots BRACE_RIGHT { printf("Model item_item![Name:%s]\n",$2); } ;
備註,上面僅僅是對json文件進行語法分析,再此僅將json對的名字進行簡單的打印。 rest
後記 code
依次使用以下命令便可完成對項目的編譯工做。
flex json.fl bison -d json.y gcc -o lex.exe json.tab.c lex.yy.c
{ "people": [ { "firstName": "Brett", "lastName":"McLaughlin", "email": "aaaa" }, { "firstName": "Jason", "lastName":"Hunter", "email": "bbbb"}, { "firstName": "Elliotte", "lastName":"Harold", "email": "cccc" } ] }
而後,便可對此json文檔進行解析。