`
hemowolf
  • 浏览: 154612 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

练手写了个SQLite解析器

阅读更多

    书看了大半,天马行空似懂非懂。返回头看看感觉没学到什么东西,所以还是动手尝试下。实际这个解析器只是sqlite语法的一个create table语法,而且也没完全实现(不支持check约束和指定数据库)。

   

     为了定一个模子我先写了一个create table 的antlr文法(如下)照着做的。

grammar sqlitcreatetable;

@members{
private boolean isType(String id){
	id=id.toLowerCase();
	return id.equals("int")|| id.equals("integer") 
			||id.equals("bool")||id.equals("boolean")
			||id.equals("long")
			||id.equals("short")||id.equals("byte")
			||id.equals("float")
			||id.equals("real")||id.equals("double")
			||id.equals("blob")
			||id.equals("text")||id.equals("varchar")||id.equals("nvarchar")||id.equals("string")||id.equals("char");
}
}

createTableStatment
	:	'create' (temp='temp'|temp='temporary')? 'table' ('if' 'not' 'exists')?
	 name
	 columnList ';'?
	 {
	 	System.out.print(($temp.text!=null? "temporary ":"") + "table:"+$name.text);
	 }
	;

columnList
	:	'(' column (',' column)* ')' 
	;
	
column	:	
	name
	type typelimit?
	constainst*
	{
	 	System.out.println("column:" +$name.text +" "+$type.text);
	}
	;

typelimit
	:	'(' a=INT ( ',' b=INT)? ')'
	{
		if($a.text!=null && $b.text!=null){
			System.out.print("(" +$a.text+ ","+$b.text+")");
		}else if($a.text!=null ){
			System.out.print("(" +$a.text+")");
		}
	}
	;
	
type	:	{ isType( input.LT(1).getText() ) }?ID
	;

constainst
	:	'primary' 'key'	{System.out.print(" primary key"); }
	|	'unique'	{System.out.print(" unique"); }
	|	'default' '(' (v=INT|v=FLOAT|v=STRING) ')'	{System.out.print(" default("+$v.text+")"); }
	|	'not' 'null'	{System.out.print(" not null"); }
	|	'autoincrement' {System.out.print(" autoincrement"); }
	;

name	:	'[' ID ']'
	|	ID
	;


ID  :	('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
    ;

INT :	'0'..'9'+
    ;

FLOAT
    :   ('0'..'9')+ '.' ('0'..'9')* EXPONENT?
    |   '.' ('0'..'9')+ EXPONENT?
    |   ('0'..'9')+ EXPONENT
    ;

COMMENT
    :   '--' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
    |   '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
    ;

STRING
    :  '\'' ( ESC_SEQ | ~('\\'|'\'') )* '\''
    ;

fragment
EXPONENT : ('e'|'E') ('+'|'-')? ('0'..'9')+ ;

fragment
HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;

fragment
ESC_SEQ
    :   '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
    |   UNICODE_ESC
    |   OCTAL_ESC
    ;

fragment
OCTAL_ESC
    :   '\\' ('0'..'3') ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7') ('0'..'7')
    |   '\\' ('0'..'7')
    ;

fragment
UNICODE_ESC
    :   '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
    ;
    
 WS  :   ( ' '
        | '\t'
        | '\r'
        | '\n'
        ) {$channel=HIDDEN;}
    ;

 

   生成这个文法的代码调试输入create table 语句则会输出表、列、列类型和约束信息。

   sqlite的create table 语法还是比较简单的,用LL(1)即可以实现了。比较麻烦的还是词法分析部分,由于  Terence Parr讲解的例子里面未涉及到关键字的识别,所以对于关键字的识别我采用了向前看(n+1)来判断是否为某关键字。这个算法(isKW函数)或许是错误的方法请各位有经验的朋友指教。

    代码没神码好贴的了有兴趣的朋友下载代码编译跑跑。看看输入内容

" create temporary table\n/*MLComment*/ IF NOT EXISTS [table_name] (\n[a1] int  unique not null,b1 double(22) primary key,c1 string(1,2) AUTOINCREMENT,e1 float not null,ff char default(0.123) )--SLComment";

 在节点的保存上我采用了简单的收集需要的节点,而不是异形树或同型树之类,遍历的结果将输出这样的

MLComment
SLComment
tbl--temporaray table_name
Column--a1 int unique not null
Column--b1 double(22) primary key
Column--c1 string(1,2) autoincrement
Column--e1 float not null
Column--ff string default(0.123)

 

 

 

分享到:
评论

相关推荐

    sqlite-create-table-parser:LL手写练习递归下降算法sqlte创建表语句解析器

    introduction LL handwriting practice recursive descent algorithm sqlite create table statement parser. See Bowen practicing handwriting a SQLite parser ...详见博文 练手写了个SQLite解析器

    java新手练手的一些小项目

    标题“java新手练手的一些小项目”揭示了这个压缩包包含了一系列适合初学者的简单项目,旨在通过实践来提升编程技能。 描述中提到的小项目,如“记事本”、“计算器”和“管理系统”,涵盖了不同的编程概念和技巧。...

    Python 爬虫练手项目.zip

    【Python 爬虫练手项目】是一个针对初学者或有一定基础的Python开发者设计的实践项目,旨在通过实际操作来提升对Python爬虫技术的理解和应用能力。该项目可能包含了一系列的Python脚本,用于从互联网上抓取数据,...

    python 100个小例子.rar_luck3eo_python_python小程序_python练手_suddenzuv

    这个资源由用户luck3eo分享,并被标签为"python小程序"和"python练手",表明它非常适合那些想要通过实践来巩固Python知识的人。 在Python的学习过程中,实践是非常关键的一部分。这100个小例子覆盖了Python的各个...

    Android入门练手项目,基于AndroidStudio的餐厅收银点餐系统源代码

    这个Android入门练手项目是一个基于Android Studio开发的餐厅收银点餐系统,旨在帮助初学者理解和实践Android应用开发。通过这个项目,你可以学习到如何构建一个功能完整的Android应用程序,掌握核心的Android编程...

    Python-爬虫-学习代码(学习使用)【Python爬虫练手项目】

    它是一个完整的爬虫框架,包含爬虫、中间件、调度器、下载器等多个组件,支持分布式爬取,适合大规模的数据抓取。 7. **实战项目**:压缩包中的学习代码应该包含了各种实战项目的源码,比如抓取新闻、微博、商品...

    简单的学生管理系统

    这可以通过设计一个简单的命令解析器实现,比如使用正则表达式匹配命令格式。 5. **业务逻辑**:在执行用户命令时,系统需要执行相应的业务逻辑。例如,添加学生时检查学号的唯一性,修改信息时确保指定的学生存在...

    Android 翻页效果txt阅读器源码.rar

    此篇将详细探讨一个特别的项目——"Android翻页效果txt阅读器源码",它不仅是一个实用的练手项目,而且是开发者提升技能、准备实际项目、获取软著参考的宝贵资源。通过分析这个源码,我们可以深入理解Android应用...

    新版Android开发教程.rar

    ----------------------------------- Android 编程基础 1 封面----------------------------------- Android 编程基础 ...• SQLite SQLite SQLite SQLite 用作结构化的数据存储 • 多媒体支持 包括常见的音频、视频和...

    Android 动漫阅读器源码.rar

    Android 动漫阅读器源码,作为一款练手项目,不仅提供了宝贵的实践经验,还为开发者在实际项目开发中提供了丰富的参考框架。这款源码集成了软著参考、快速上线等功能,是教学案例、毕业设计、出书项目实例的理想选择...

    Android 图书书架源码.rar

    本篇将深入探讨名为“Android 图书书架源码”的项目,它不仅是一个练手的好项目,也是软著参考、实际项目框架参考的理想选择,对于提升开发者的技术水平和增加实际项目经验具有显著作用。 首先,我们来分析源码中的...

    简单的管理系统

    【描述】"学徒弄着玩的,喜欢的朋友可以拿去看看,代码很简陋,别见笑"这部分描述暗示了这个管理系统是由一个新手程序员(学徒)编写的,可能作为练手项目。开发者谦虚地表示代码质量不高,可能在设计、结构或效率上...

    背单词的java小软件

    同时,提到了"练手不错",这可能意味着这个软件也是Java初学者练习编程技能的好项目。 【标签解析】 "java" 表明编程语言;"背单词" 是软件的主要功能;"软件" 指出这是一个程序应用;"SE" 可能是指"Software ...

    新闻阅读器(扩展版)

    4. **输入链接网址**:用户可以直接输入网址,阅读器会尝试解析出该网址对应的RSS或Atom feed。这扩展了应用的使用范围,使得用户不仅能订阅已知的新闻源,还能探索和添加新的内容来源。 5. **C#新闻阅读器源码**:...

    日记本软件

    7. **软件测试**:作为一个练手项目,可能包含了单元测试和集成测试,以验证各个功能模块的正确性。 8. **软件发布**:如果源码中包含发布相关的配置,那么开发者可能考虑到了软件的部署和分发,例如设置安装包制作...

    Android 万年历源码.zip

    在Android平台上开发一款万年历应用,不仅可以作为提升个人技能的练手项目,也是实际项目开发、教学案例、毕业设计的宝贵资源。这款万年历源码提供了完整的解决方案,帮助开发者快速上线,同时也适合学生提升经验值...

    Python项目案例开发从入门到实践.rar

    这一章深入到更复杂的爬虫项目,可能是建立一个小型的搜索引擎,涉及到网页爬取、数据存储(如SQLite或MongoDB)、索引构建以及搜索算法的实现。这需要对网络爬虫、数据库操作和信息检索有一定理解。 5. **第7章 ...

    android手机卫士源码

    作为一款适合新手练手的项目,它涵盖了Android开发中的多个核心知识点,对于学习Android开发具有很高的实践价值。 1. **Android架构与组件** Android系统是基于组件模型构建的,包括四大组件:Activity、Service、...

Global site tag (gtag.js) - Google Analytics