设为首页 收藏本站
查看: 1743|回复: 0

[经验分享] 练手写了个SQLite解析器

[复制链接]

尚未签到

发表于 2016-11-30 10:38:21 | 显示全部楼层 |阅读模式
  书看了大半,天马行空似懂非懂。返回头看看感觉没学到什么东西,所以还是动手尝试下。实际这个解析器只是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)

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-307623-1-1.html 上篇帖子: Android 深入研究SQLite实例(二) 下篇帖子: 一步一步实现C++操作SQLite数据库
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表