- 浏览: 243763 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
liuqiang5151:
你好,按照这种方式,如果传递参数,在服务端报错
org.ofb ...
ofbiz的服务(service)export成web service的方法(3) -
吹泡泡程序猿:
你甚至会发现自己现在成熟得可怕,一件很复杂的事情,你一眼就看穿 ...
30岁的痛 -
吹泡泡程序猿:
mark
关于BOSS系统以及计费系统的一些书 -
gao241:
您好tower,您介绍的都是电信行业的计费方法,如果是在线支付 ...
计费系统与自主开发 -
javams:
你好,请问你那里有LDAP的分页查询demo吗?谢谢了,如果可 ...
LDAP读书笔记2-LDAP协议
前段时间做了一个简单的内存数据库,需要提供点简单的SQL支持,在参考了《Lex与Yacc》和网上的相关资料后,以《Lex与Yacc》中的SQL解释器为基础,做了修改,最后生成了一个简单的SQL解释器。
这个SQL解释器由于本身内存数据库提供的功能限制,提供的SQL也有很多的限制:
1、select不支持按字段取值,一次查询获取所有字段
2、查询条件之间的关系只支持AND
3、UPDATE一次只更新一个字段
4、不支持函数
在SQL解释器中,关键是我们要构建我们的语法结构,也就是最终通过SQL解释器要生成的一个程序能识别的结构。负责的SQL支持对应负责的负责的结构,因为我们支持的SQL简单,所以相对应的结构也就很简单了。
主题程序由3个文件组成,sql_plan.h parser_lex.l parser_yacc.y。其中,sql_plan.h是语法结构的定义,parser_lex.l是词法解释和主程序入口部分,parser_yacc.y是语法解释部分。
#ifndef __SQL_DEFINE__ #define __SQL_DEFINE__ #define NAME_SIZE 24 #define MAX_BUFFER_SIZE 8192 typedef enum { SQL_SELECT = 1, SQL_INSERT, SQL_UPDATE, SQL_DELETE, SQL_COUNT_ALL }sql_action; typedef struct{ char field_name[NAME_SIZE]; char field_value[256]; }FieldNameValue; typedef struct{ int list_len; FieldNameValue fnv_par[5]; }FieldNameValue_List; typedef struct{ int action; char tab_name[256]; FieldNameValue_List w_fnv_list; char u_field_name[256]; char u_field_value[256]; int pos; char buffer[MAX_BUFFER_SIZE]; }SQL_PLAN; extern SQL_PLAN sql_plan; #endif |
%{ #include "parser_yacc.h" #include "sql_define.h" #include <stdio.h> #include <stdlib.h> #include <string.h> int lineno = 1; void yyerror(char *s); void TrimString(char *str) { char *copied, *tail = NULL; if ( str == NULL ) return; for( copied = str; *str; str++ ) { if ( *str != ' ' && *str != '\t' && *str != '\n' && *str != '\r' && *str != '\'' && *str != ';') { *copied++ = *str; tail = copied; } else { if ( tail ) *copied++ = *str; } } if ( tail ) *tail = 0; else *copied = 0; return; } char *_xInput; int _xLen = 0; int myinput(char *buff,int max) { if(!_xLen) return 0; if(max > _xLen) max = _xLen ; memcpy(buff,_xInput,max); _xInput += max; _xLen -= max; return max; } #define YY_INPUT(b, r, m) (r = myinput(b, m)) %} %% and { return AND; } CHAR(ACTER)? { return CHARACTER; } CLOSE { return CLOSE; } CREATE { return CREATE; } CURRENT { return CURRENT; } CURSOR { return CURSOR; } count { return COUNT; } DECLARE { return DECLARE; } delete { return DELETE; } DOUBLE { return DOUBLE; } FETCH { return FETCH; } FLOAT { return FLOAT; } FOR { return FOR; } from { return FROM; } insert { return INSERT; } INT(EGER)? { return INTEGER; } into { return INTO; } NOT { return NOT; } NULL { return NULLX; } NUMERIC { return NUMERIC; } OF { return OF; } OPEN { return OPEN; } OR { return OR; } REAL { return REAL; } select { return SELECT; } set { return SET; } table { return TABLE; } update { return UPDATE; } values { return VALUES; } where { return WHERE; } /* punctuation */ "=" { return L_EQ; } "<>" | "<" | ">" | "<=" | ">=" { return COMPARISON; } [-+*/:(),.;] { return yytext[0]; } /* names */ [A-Za-z][A-Za-z0-9_]* { strcpy(yylval.nameval,yytext); return NAME; } /* numbers */ -?[0-9]+ { yylval.intval = atoi(yytext); return INTNUM; } [0-9]+"."[0-9]* { yylval.floatval = atof(yytext); return FLOATNUM; } [0-9]+[eE][+-]?[0-9]+ | [0-9]+"."[0-9]*[eE][+-]?[0-9]+ | "."[0-9]*[eE][+-]?[0-9]+ { return APPROXNUM; } /* strings */ '[^'\n]*' { TrimString(yytext); strcpy(yylval.strval,yytext); return STRING; } '[^\'\n]*$ { yyerror("Unterminated string"); } \n lineno++; [ \t\r]+ ; /* white space */ "--".*$ ; /* comment */ %% void yyerror(char *s) { printf("%d: %s at %s\n", lineno, s, yytext); } int yywrap() {return 1;} main(int argc, char **argv) { int pos; int ret; char *buffer; char prompt_buffer[MAX_BUFFER_SIZE]; char last_prompt_buffer[MAX_BUFFER_SIZE]; int count; while(1) { printf("mdbsql>>"); fgets(prompt_buffer, sizeof(prompt_buffer), stdin); _xInput = prompt_buffer; _xLen = strlen(prompt_buffer); if (prompt_buffer[0]=='\\') { strcpy(prompt_buffer, last_prompt_buffer); _xLen = strlen(prompt_buffer); } if (strncmp(prompt_buffer, "quit", 4)==0 || strncmp(prompt_buffer, "exit", 4)==0 ) { break; } memset(&sql_plan, 0, sizeof(sql_plan) ); strcpy(last_prompt_buffer, prompt_buffer); if(!yyparse()) { if (sql_plan.action == SQL_SELECT) { printf("%d records are retrieved\n", count); } else if (sql_plan.action == SQL_DELETE) { printf("%d records are deleted\n", ret); } else if (sql_plan.action == SQL_UPDATE) { printf("%d records are updated\n", ret); } else if (sql_plan.action == SQL_INSERT) { if (ret>0) printf("1 record is inserted\n"); } else if (sql_plan.action == SQL_COUNT_ALL) { if (ret>0) printf("1 record is retrieved\n"); } } else { printf("SQL parse failed\n"); } } } |
%{ #include "parser_yacc.h" #include "sql_define.h" #include <stdio.h> #include <stdlib.h> #include <string.h> int lineno = 1; void yyerror(char *s); void TrimString(char *str) { char *copied, *tail = NULL; if ( str == NULL ) return; for( copied = str; *str; str++ ) { if ( *str != ' ' && *str != '\t' && *str != '\n' && *str != '\r' && *str != '\'' && *str != ';') { *copied++ = *str; tail = copied; } else { if ( tail ) *copied++ = *str; } } if ( tail ) *tail = 0; else *copied = 0; return; } char *_xInput; int _xLen = 0; int myinput(char *buff,int max) { if(!_xLen) return 0; if(max > _xLen) max = _xLen ; memcpy(buff,_xInput,max); _xInput += max; _xLen -= max; return max; } #define YY_INPUT(b, r, m) (r = myinput(b, m)) %} %% and { return AND; } CHAR(ACTER)? { return CHARACTER; } CLOSE { return CLOSE; } CREATE { return CREATE; } CURRENT { return CURRENT; } CURSOR { return CURSOR; } count { return COUNT; } DECLARE { return DECLARE; } delete { return DELETE; } DOUBLE { return DOUBLE; } FETCH { return FETCH; } FLOAT { return FLOAT; } FOR { return FOR; } from { return FROM; } insert { return INSERT; } INT(EGER)? { return INTEGER; } into { return INTO; } NOT { return NOT; } NULL { return NULLX; } NUMERIC { return NUMERIC; } OF { return OF; } OPEN { return OPEN; } OR { return OR; } REAL { return REAL; } select { return SELECT; } set { return SET; } table { return TABLE; } update { return UPDATE; } values { return VALUES; } where { return WHERE; } /* punctuation */ "=" { return L_EQ; } "<>" | "<" | ">" | "<=" | ">=" { return COMPARISON; } [-+*/:(),.;] { return yytext[0]; } /* names */ [A-Za-z][A-Za-z0-9_]* { strcpy(yylval.nameval,yytext); return NAME; } /* numbers */ -?[0-9]+ { yylval.intval = atoi(yytext); return INTNUM; } [0-9]+"."[0-9]* { yylval.floatval = atof(yytext); return FLOATNUM; } [0-9]+[eE][+-]?[0-9]+ | [0-9]+"."[0-9]*[eE][+-]?[0-9]+ | "."[0-9]*[eE][+-]?[0-9]+ { return APPROXNUM; } /* strings */ '[^'\n]*' { TrimString(yytext); strcpy(yylval.strval,yytext); return STRING; } '[^\'\n]*$ { yyerror("Unterminated string"); } \n lineno++; [ \t\r]+ ; /* white space */ "--".*$ ; /* comment */ %% void yyerror(char *s) { printf("%d: %s at %s\n", lineno, s, yytext); } int yywrap() {return 1;} main(int argc, char **argv) { int pos; int ret; char *buffer; char prompt_buffer[MAX_BUFFER_SIZE]; char last_prompt_buffer[MAX_BUFFER_SIZE]; int count; while(1) { printf("mdbsql>>"); fgets(prompt_buffer, sizeof(prompt_buffer), stdin); _xInput = prompt_buffer; _xLen = strlen(prompt_buffer); if (prompt_buffer[0]=='\\') { strcpy(prompt_buffer, last_prompt_buffer); _xLen = strlen(prompt_buffer); } if (strncmp(prompt_buffer, "quit", 4)==0 || strncmp(prompt_buffer, "exit", 4)==0 ) { break; } memset(&sql_plan, 0, sizeof(sql_plan) ); strcpy(last_prompt_buffer, prompt_buffer); if(!yyparse()) { if (sql_plan.action == SQL_SELECT) { printf("%d records are retrieved\n", count); } else if (sql_plan.action == SQL_DELETE) { printf("%d records are deleted\n", ret); } else if (sql_plan.action == SQL_UPDATE) { printf("%d records are updated\n", ret); } else if (sql_plan.action == SQL_INSERT) { if (ret>0) printf("1 record is inserted\n"); } else if (sql_plan.action == SQL_COUNT_ALL) { if (ret>0) printf("1 record is retrieved\n"); } } else { printf("SQL parse failed\n"); } } } |
mdbsql: parser_yacc.o parser_lex.o gcc -o $@ parser_yacc.o parser_lex.o -lfl parser_yacc.c parser_yacc.h: parser_yacc.y yacc -vdt parser_yacc.y mv y.tab.h parser_yacc.h mv y.tab.c parser_yacc.c mv y.output parser_yacc.out parser_lex.o: parser_yacc.h parser_lex.c parser_lex.c : parser_lex.l flex $< mv lex.yy.c $*.c |
上述程序在cygwin、redhat as5下测试过
评论
2 楼
tower
2009-01-06
只是一个很简单的样例而已。要看完整的,实际上书上的例子也比较详细了
1 楼
yananay
2009-01-06
不晓得sql语法的BNF?如果有现成的BNF,我想解释器会更完善一些。
发表评论
-
Linux2.6下如何配置core文件
2009-08-20 17:28 4337下面的资料是从互联网上整理的来的,参考文献如下: http: ... -
Linux下查看FIFO剩余字节的方法
2009-05-05 09:48 1620FIFO做为一种有名管道的形式,在unix下编程经常会用到,在 ... -
一个多对多的消息存储转发工具
2009-04-23 13:41 1357本文原创作品,如需转载请注明来源,作者:姜涛, towerjt ... -
xmlrpc++真的粉OO
2009-03-30 22:26 1295一个改写自py-xmlrpc的c++项目,支持xmlrpc的客 ... -
occi在linux编译运行时报libstdc++.so.6冲突的问题
2009-03-02 16:39 3804OCCI库在linux编译的时候,由于linux版本太高,会提 ... -
被libpq逼疯,闪
2009-02-16 16:32 981postgreSQL的C语言接口库libpq实在是相当的难用, ... -
CMarkupSTL中的复位
2009-02-13 17:22 2151CMarkupSTL是一个C++写的xml操作的轻量级的类,相 ... -
一个C实现的记日志的函数库
2006-04-02 10:02 2440在实际应用中,日志是一个比较重要的部分。在unix下用得比较多 ... -
收藏的一个linux下proxy实现的源码
2006-04-02 10:04 2553/****************************** ... -
以为informix没有产生sequence的功能,所以自己造了一个车轮
2006-04-02 10:07 1776#include <unistd.h>#inclu ... -
chinaunix上的flw写的超级trim
2006-04-02 10:10 1122#include <stdlib.h> void ... -
在SunOS8上调试通过的获取指定进程信息的程序
2006-04-02 16:50 868#include <stdio.h>#inc ... -
FastDB程序崩溃后的锁清理
2008-03-18 15:02 3006本文原创作品,如需转载请注明来源,作者:姜涛, tower ... -
FastDB不同访问模式带来的影响
2008-03-18 15:05 3685本文原创作品,如需转载请注明来源,作者:姜涛, tower ... -
yacc的使用
2008-04-03 09:50 3984本来不打算全部拷贝过来的,但是这篇文章在网上已经删除了,我是从 ... -
incognito的查询接口
2008-04-25 16:19 840今天运气很好,昨天搞了一天的一个查询接口,一直没有成功。下午的 ... -
多线程的pthread_cond_wait后,记住再次检测条件
2008-05-28 11:15 10557一般来说,在多线程竞争一个资源的时候,会用到pthread_c ... -
perl与C和C++集成的问题
2008-07-16 16:18 1114一直在关注脚本语言与C、C++语言集成的问题。我希望我们的业务 ...
相关推荐
通过实践编写简单的词法分析器和语法分析器,你可以逐步掌握如何使用Lex和Yacc构建自己的编译器或解析器。 总的来说,掌握Lex和Yacc是提升编程技能和理解编译原理的重要步骤。它们提供了强大的工具,帮助开发者高效...
总结起来,lex和yacc是构建编译器和解释器的重要工具,它们将复杂的文法规则和词法分析工作自动化,使得开发者能够专注于更高层次的逻辑实现。通过对"lex_yacc_example"的学习和实践,我们可以更好地理解和掌握这两...
在计算机科学领域,SQL(Structured Query Language,结构化查询语言)是...以上知识点概述了使用yacc和lex实现SQL解释器的理论基础和实现步骤,这些知识点对于深入理解编译原理和数据库管理系统的开发具有重要的意义。
《我的SQL解释器0.1》是一个不错的起点,对于想要深入了解数据库和SQL语言的人来说,这是一个很好的实践项目。尽管目前功能有限,但随着不断迭代和改进,有望成为一个功能丰富的自定义SQL工具。对于初学者,可以从这...
《在Windows下使用Flex与Bison:解析与...它们不仅适用于编译器的开发,还可以应用于配置文件解析、SQL查询解析、编程语言解释器等领域。理解并熟练掌握这两款工具的使用,对于深入学习编译原理和软件工程至关重要。
PLY是Python的一个实现,用于词法分析(Lex)和语法分析(Yacc)的工具,它允许开发者编写自己的解析器来处理特定的语言或数据格式。在计算机科学中,词法分析和语法分析是编译器和解释器设计中的关键步骤,它们分别...
本文将深入探讨一个名为“Simple-RDBMS”的项目,该项目通过使用经典的词法分析工具Lex和语法分析工具Yacc,实现了一个简单的SQL查询解析器,并构建了一个基础的文件系统,以支持数据的存储和操作。 一、理解SQL...
1. **MinGW/MSYS**:这是一个模拟Unix环境的工具集,提供了一个命令行界面,可以运行许多Unix工具,包括Flex和Yacc。首先,你需要下载并安装MinGW和MSYS,然后通过包管理器`pacman`安装flex和bison。 2. **Cygwin**...
同时还包含了一个MinGW的GNU的C++编译器环境:)可以直接使用:) <br>这个包包含的文件列表: <br>MinGW GNU的C/C++编译程序(windows版本) bison.exe GNU的yacc程序 bison.hairy GNU的yacc程序...
在学习编译原理时,`flex` 和 `yacc` 提供了一个很好的实践平台,让开发者能够深入理解词法分析和语法分析的过程。通过编写 `.l` 和 `.y` 文件,学生可以实现自己的编译器或解释器,从而更好地理解编程语言的内部...
这个工具主要用于将词法分析器(通常由lex或flex生成)产生的词法单元流转换为语法分析树,是构建编译器和解释器的重要组成部分。在本“Yacc英文教程”中,我们将深入探讨Yacc的工作原理、语法定义、以及如何使用它...
在使用YACC时,开发者需要编写一个名为`.y`的文件,里面包含了文法规则和动作代码。文法规则由非终结符、终结符、优先级和结合性等组成,而动作代码则定义了当解析器遇到特定符号序列时应执行的操作。YACC会读取这个...
2. **解释器实现**:对于不需生成目标代码的解释器,yacc同样适用。 3. **配置文件解析**:许多配置文件格式可以通过yacc进行解析。 4. **DSL(领域特定语言)**:构建特定领域的解析器,如SQL查询解析。 **五、...
在Python编程环境中,`ply`是一个著名的词法分析和语法分析工具,用于构建解析器。...在这个项目中,用户可以利用`ply`理解并执行简单的SQL查询,这对于学习SQL语法和解析原理,或者构建自己的SQL解释器都非常有帮助。
此外,作者还提到了从PostgreSQL的SQL解析器中学习经验,以及Lex和Yacc的其他应用场景,比如编译器设计、脚本语言解释器等。 总之,为BerkeleyDB添加SQL支持是一个复杂的过程,涉及到数据库系统设计、解析理论和...
描述提到的是一个适用于Windows操作系统的集成开发环境(IDE),该环境集成了lex和yacc工具。lex,也称为flex,是用于生成词法分析器的工具,它能够识别程序源代码中的基本符号或标记。而yacc,或者在某些实现中被...
Flex接受一个包含正则表达式和动作的输入文件(通常命名为lex.yy.c),然后生成C代码,该代码可以读取输入流并识别这些模式。 Bison,原名Yacc(Yet Another Compiler-Compiler),是一个语法分析器生成器。它根据...
其中,flex是一种快速词法分析器生成器,而bison则是一个语法分析器生成器,它们能够帮助用户创建出适用于各种文本数据处理任务的编译器和解释器。《flex与bison》这本书籍即是深入讲解如何使用这两个工具的经典参考...
Flex(以前称为lex)是一个词法分析器生成器,而Bison(以前称为yacc)是一个语法分析器生成器。它们共同帮助开发者将高级语言的语法规则转化为可执行代码。 **Flex** Flex是一个广泛使用的开源工具,用于创建词法...
Flex接受用户定义的正则表达式和动作,生成C代码(通常是`lex.yy.c`),这个代码实现了一个词法分析器,它可以扫描输入文本并产生一系列的标记供语法分析器使用。通常,Flex使用的输入文件扩展名为`.l`。 Bison和...