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,就麻烦多了:
Coco/R 我用的时间比较长,简单易学,可以很快上手,但对于一些复杂的语法有点力不从心,而 Antlr 很强大,整个社区也很活跃,相比之下,Coco/R 的圈子要小得多,以前我用的一个版本对于 String 的 Scan 会有一个问题,我是发邮件给作者的,不过作者很快就回信了并给出了对应的修复手法,很PF并感谢他。
在初步使用 Antlr 的过程中,碰到一些小麻烦,比如说:
Parser 必须为小写字母开头,Lexer 必须大写开头(不知这样原因何在)
对于参数的定义及初始化,初始化要写在 Assignment 的前面,因为 Assignment 会在 try 内执行的
附上一个简单的 parser (只能处理 select a,b,c....),通过这个例子,我主要是学习了Antlr 的 Lexer 定义,参数使用,基本上对我移植SqlBroker无障碍了。
评论Feed: /feed.asp?q=comment&id=260
彼时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); }
;
看到没,必须用$setType来标明这个Token不会进入parser,只要碰到符合此条件的,就一律跳过。还有,Coco/R 可以很方便地支持像 python 那种缩进式的语法分析,不过具体如何弄我忘了。Antlr 也有 Python 语法文件,具体如何处理我还不是很清楚。ML_COMMENT
: "/*"
( { LA(2)!='/' }? '*'
| '\n' { newline(); }
| ~('*'|'\n')
)*
"*/"
{ $setType(Token.SKIP); }
;
Coco/R 我用的时间比较长,简单易学,可以很快上手,但对于一些复杂的语法有点力不从心,而 Antlr 很强大,整个社区也很活跃,相比之下,Coco/R 的圈子要小得多,以前我用的一个版本对于 String 的 Scan 会有一个问题,我是发邮件给作者的,不过作者很快就回信了并给出了对应的修复手法,很PF并感谢他。
在初步使用 Antlr 的过程中,碰到一些小麻烦,比如说:
Parser 必须为小写字母开头,Lexer 必须大写开头(不知这样原因何在)
对于参数的定义及初始化,初始化要写在 Assignment 的前面,因为 Assignment 会在 try 内执行的
附上一个简单的 parser (只能处理 select a,b,c....),通过这个例子,我主要是学习了Antlr 的 Lexer 定义,参数使用,基本上对我移植SqlBroker无障碍了。
class SQLParser extends Parser;
options
{
exportVocab = SQL;
buildAST = false;
k = 2;
}
ansisql
returns [Node parent]
{parent = new Node();}
:
SELECT fieldlist[parent] EOF
;
fieldlist
[Node parent]
{Node f = new Node();}
:
f = field
{parent.next = f;}
(COMMA fieldlist[f])*
;
field
returns [Node node]
{node = new Node();}
:
id :ID
{node.value = id.getText(); }
;
options
{
exportVocab = SQL;
buildAST = false;
k = 2;
}
ansisql
returns [Node parent]
{parent = new Node();}
:
SELECT fieldlist[parent] EOF
;
fieldlist
[Node parent]
{Node f = new Node();}
:
f = field
{parent.next = f;}
(COMMA fieldlist[f])*
;
field
returns [Node node]
{node = new Node();}
:
id :ID
{node.value = id.getText(); }
;
评论Feed: /feed.asp?q=comment&id=260
标签:
Antlr
Parser
coco/r
Sql Broker
浏览模式: 显示全部 |
评论: 1 |
引用: 0 | 排序 | 浏览: 1899
[ 2007-06-27 12:10:47 ]
大侠 ,你写的 大都让俺看不懂 。。 你开发的 到底是 什么

