1、概述
Lemon是一个LALR(1)文法分析器生成工具,与bison和yacc类似,是一个可以独立于SQLite使用的开源的分析器生成工具。而且它使用与yacc(bison)不同的语法规则,可以减少编程时出现错误的机会。Lemon比yacc和bison更精致、更快,而且是可重入的,也是线程安全的——这对于支持多线程的程序是非常重要的。
Lemon的主要功能就是根据上下文无关文法(CFG),生成支持该文法的分析器。程序的输入文件有两个:
(1) 语法规则文件;
(2) 分析器模板文件。
一般来说,语法规则是由程序员定义的;Lemon有一个适用于大多数应用程序的默认分析器模板。
根据命令行选项,Lemon会生成以下一些文件:
(1) 分析器的C代码;
(2) 一个为每个终结符定义一个整型ID的头文件;
(3) 一个描述分析器状态的文件。
语法规范文件以”.y”为后缀,如果语法规范文件为”gram.y”,则可以使用该命令生成分析器:lemon gram.y。
1.1、分析器接口
Lemon不会生成一个完整的、可以运行的程序。它仅仅生成一些实现分析器的子例程,然后由用户程序在适当的地方调用这些子例程,从而生成一个完整的分析器。
1.1.1、ParseAlloc
程序在使用Lemon生成的分析器之前,必须创建一个分析器。如下:
void *pParser = ParseAlloc( malloc );
ParseAlloc为分析器分配空间,然后初始化它,返回一个指向分析器的指针。SQLite对应的函数为:
void *sqlite3ParserAlloc(void *(*mallocProc)(size_t))
函数的参数为一个函数指针,并在函数内调用该指针指向的函数。如:
void *sqlite3ParserAlloc(void *(*mallocProc)(size_t)){ yyParser *pParser; pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) ); if( pParser ){ pParser->yyidx = -1; #ifdef YYTRACKMAXSTACKDEPTH pParser->yyidxMax = 0; #endif #if YYSTACKDEPTH<=0 pParser->yystack = NULL; pParser->yystksz = 0; yyGrowStack(pParser); #endif } return pParser; }
1.1.2、ParseFree
当程序不再使用分析器时,应该回收为其分配的内存。如下:
ParseFree(pParser, free);
SQLite对应的函数如下:
void sqlite3ParserFree( void *p, /* The parser to be deleted */ void (*freeProc)(void*) /* Function used to reclaim memory */ ){ yyParser *pParser = (yyParser*)p; if( pParser==0 ) return; while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser); #if YYSTACKDEPTH<=0 free(pParser->yystack); #endif (*freeProc)((void*)pParser); }
1.1.3、Parse
Parse是Lemon生成的分析器的核心例程。在分析器调用ParseAlloc后,分词器就可以将切分的词传递给Parse,进行语法分析。SQLite对应的函数如下:
void sqlite3Parser( void *yyp, /* The parser */ int yymajor, /* The major token code number */ sqlite3ParserTOKENTYPE yyminor /* The value for the token */ sqlite3ParserARG_PDECL /* Opt