使用flex,bison構建簡單的json解析器

背景 正則表達式

    閒來無聊,抽空寫篇博客對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



從百度百科拿下一段json文本,以下

{ 
"people": [
                { "firstName": "Brett", "lastName":"McLaughlin", "email": "aaaa" },
                { "firstName": "Jason", "lastName":"Hunter", "email": "bbbb"},
                { "firstName": "Elliotte", "lastName":"Harold", "email": "cccc" }
            ]
}



保存爲,bison中所寫的config.file文件。

而後,便可對此json文檔進行解析。

相關文章
相關標籤/搜索