从coco/r 迁移到 antlr 心得体会
[ 2007-03-28 21:18:47 | 作者: progame ]
终于将sql broker从coco/r迁移到antlr了,并且把单元测试都跑得通过了,总结下来,转换工作量不是太大,我加起来用了2个工作日左右,语法文件大小从原来的1200多行到现在的1500多行,首先看一个例子的不同语法定义
coco/r :
antlr:
一些区别:
1、antlr中keyword必须定义在lexer中,而且不能发生LL冲突,否则需要放入tokens节,这点coco/r要方便很多
2、因为antlr的[]是参数定义,所以coco/r中的表示zero or one的 '[]'就不能用了,必须'()?'
3、{}在antlr中为代码段,等同coco/r的(..),所以不能再用它表示zero or more,而应该使用'()*'
4、coco/r 可以用t.val得到最后一个token的value,而antlr中可以使用LT(0),依此类推,还可以使用LT(1), LT(-1)...,另外就是可通过定义符号来取值
5、antlr的buildast应该比较有用,我可以通过它构建初步的AST,再根据这个AST生成我自己的AST,但因为原来coco/r是直接通过嵌入代码构造好了最终的AST,所以就没有用antlr的这个功能,况且要重复在TreeParser中定义一次类似的语法也挺烦人的
coco/r :
InsertValue<out InsertValue node> =
(. node = new InsertValue(); .)
("DEFAULT" (. ExceptLevel(2); node.usedefault = true; .)
| Expression<out node.expression> )
.
(. node = new InsertValue(); .)
("DEFAULT" (. ExceptLevel(2); node.usedefault = true; .)
| Expression<out node.expression> )
.
antlr:
insertvalue
returns [InsertValue node]
{ node = new InsertValue(); }
:
(DEFAULT { ExceptLevel(2); node.usedefault = true; }
| {Expression exp = null;} exp = expression {node.expression = exp;} )
;
returns [InsertValue node]
{ node = new InsertValue(); }
:
(DEFAULT { ExceptLevel(2); node.usedefault = true; }
| {Expression exp = null;} exp = expression {node.expression = exp;} )
;
一些区别:
1、antlr中keyword必须定义在lexer中,而且不能发生LL冲突,否则需要放入tokens节,这点coco/r要方便很多
2、因为antlr的[]是参数定义,所以coco/r中的表示zero or one的 '[]'就不能用了,必须'()?'
3、{}在antlr中为代码段,等同coco/r的(..),所以不能再用它表示zero or more,而应该使用'()*'
4、coco/r 可以用t.val得到最后一个token的value,而antlr中可以使用LT(0),依此类推,还可以使用LT(1), LT(-1)...,另外就是可通过定义符号来取值
5、antlr的buildast应该比较有用,我可以通过它构建初步的AST,再根据这个AST生成我自己的AST,但因为原来coco/r是直接通过嵌入代码构造好了最终的AST,所以就没有用antlr的这个功能,况且要重复在TreeParser中定义一次类似的语法也挺烦人的
Antlr的一个例子分析
[ 2007-02-13 22:47:23 | 作者: progame ]
Antlr 和 Coco/R 的一个初步比较
[ 2007-02-13 00:02:00 | 作者: progame ]
之前我第一个版本的 SqlBroker 是用 VB6 手写词法分析和语法分析器的, 感谢老外写的那本编译原理, 之前看国人的教材,愣是看了和没看没什么区别, 到了 Persistore 的时候,决定重写 SqlBroker,因为C#下还是有些从 Java 移植过来的 Parser Generator 的,于是我找啊找,比较了几个,最后选择了 Coco/R,主要原因是它不用引用额外的 DLL,而且语法很易学,例子也够多,SQL 的也有一个,便于我抄袭。
彼时Antlr也看到了,但其语法实在是有点复杂,Options 就一堆,有点晕,现在 Persistore 因为其复杂性已经被我遗弃了,但 SqlBroker 仍然是一个非常有价值的东西被我用到新的持久层--ObjectDataSet上了,因为 Coco/R对LL(K)的冲突解决并不好,必须加入额外的函数进行 nexttoken 读取并处理,所以我现在准备把 SqlBroker 的语法分析使用 Antlr 来实现。
这几天学习了一下 Antlr的语法(有时候想,这种 Parser Generator 真是好,可以实现自编译,像 Coco/R 本身的 grammer 文件的 parse 就是用它自己生成的 Parser去完成的,这样可以一直递归优化),感觉确实很强大,怪不得成了 java 世界里最流行的不二选择,C# 版本也有,不过命令行工具仍然是调用jar来完成的。
Coco/R 虽然不够 Antlr 强大,但它确实有它的独门利器,举个例子:
换成Antlr,就麻烦多了:
阅读全文...
彼时Antlr也看到了,但其语法实在是有点复杂,Options 就一堆,有点晕,现在 Persistore 因为其复杂性已经被我遗弃了,但 SqlBroker 仍然是一个非常有价值的东西被我用到新的持久层--ObjectDataSet上了,因为 Coco/R对LL(K)的冲突解决并不好,必须加入额外的函数进行 nexttoken 读取并处理,所以我现在准备把 SqlBroker 的语法分析使用 Antlr 来实现。
这几天学习了一下 Antlr的语法(有时候想,这种 Parser Generator 真是好,可以实现自编译,像 Coco/R 本身的 grammer 文件的 parse 就是用它自己生成的 Parser去完成的,这样可以一直递归优化),感觉确实很强大,怪不得成了 java 世界里最流行的不二选择,C# 版本也有,不过命令行工具仍然是调用jar来完成的。
Coco/R 虽然不够 Antlr 强大,但它确实有它的独门利器,举个例子:
COMMENTS FROM "/*" TO "*/"
COMMENTS FROM "--" TO eol
IGNORE eol + cr + tab
COMMENTS FROM "--" TO eol
IGNORE eol + cr + tab
换成Antlr,就麻烦多了:
protected
ML_COMMENT
: "/*"
( { LA(2)!='/' }? '*'
| '\n' { newline(); }
| ~('*'|'\n')
)*
"*/"
{ $setType(Token.SKIP); }
;
...ML_COMMENT
: "/*"
( { LA(2)!='/' }? '*'
| '\n' { newline(); }
| ~('*'|'\n')
)*
"*/"
{ $setType(Token.SKIP); }
;
阅读全文...
1
