使用flex,bison构建简单的json解析器
背景 ????闲来无聊,抽空写篇博客对flex,bison这两个小工具进行介绍一下。工具本身的用途我不在此赘述。由于自己曾经做过配置文件的解析的工作,深知其中的艰辛与痛苦。flex,bion的出现,为自己解决这类问题打开了另外一扇门。当然,如果拿flex,bison来解析我用到的这些配置文件,有点小题大做了。所以,这个地方,我选择了解析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 ??????? [ trn] %% " 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的正则表达式也有待改进。 词法分析 词法分析使用的是bison工具,其内容如下(文件名为json.y)
%{ #include <stdio.h> #include <string.h> void yyerror(const char* s) { printf("ERROR:%sn",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对的名字进行简单的打印。 后记 ????依次使用如下命令即可完成对项目的编译工作。 ???? 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文档进行解析。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |