项目中用的JavaCC做查询编译,在这里小结一下,作为备忘。
JavaCC是一个很不错的词法、语法解析器的生成器,只需要编写规则就可以生成Java语言的词法、语法解析器(新版本的JavaCC还支持C/C++作为目标语言)。JavaCC相当与Yacc/Bison+Lex/Flex很类似。
[引用请注明出处:http://blog.csdn.net/bhq2010/article/details/8763920]
JavaCC首页:
http://javacc.java.net/
在首页上下载的JavaCC是最新版的,使用方法和Bison一样,在命令提示符或者终端中执行、获得生成的结果。
也可已用javacc eclipse插件:
http://sourceforge.net/projects/eclipse-javacc/files/
下载插件、解压之后,把plugins和features目录下的文件分别拷贝到eclipse的相应目录中即可。
不论哪种方式,所需编写的规则都是一样的。
通过JavaCC自带的example和文档其实就可以上手了,下面就简单小结一下:
词法和语法规则都写在一个.jj的文件中。这个文件应该这样写:
1、开头:
options { JDK_VERSION = "1.5"; STATIC = false; }
2、主类
PARSER_BEGIN(Sparql) package cn.edu.ruc.iir.sparql; import cn.edu.ruc.iir.query.*; import cn.edu.ruc.iir.query.model.*; import cn.edu.ruc.iir.query.util.*; import java.text.*; public class Sparql { public static void main(String args []) throws ParseException { Sparql parser = new Sparql(System.in); int res = 0; while (true) { System.out.print("MyRDF >"); try { res = parser.one_query(); if (res == 0) {} else if (res == 1) { break; } else { System.out.println("Please correct your query."); } } catch (Exception e) { System.out.println("NOK."); System.out.println(e.getMessage()); parser.ReInit(System.in); } catch (Error e) { System.out.println("Oops."); System.out.println(e.getMessage()); break; } } } } PARSER_END(Sparql)
3、定义词法规则
SKIP : { " " | "\t" | "\r" | "\n" } TOKEN : /* OPERATORS */ { < SELECT : "select" | "SELECT" > | < WHERE : "where" | "WHERE" > | < OBRACE : "{" > | < CBARCE : "}" > } TOKEN : { < EXIT : | "exit" | "EXIT" > | < UNKNOWN : "?" < KNOWN > > | < KNOWN : ([ "<", ">", "a"-"z", "A"-"Z", "0"-"9", ":", "/", "_", "-", "\"", "'", "~", "#" ])+ > | < MISSEDP : "[" "]" > }
4、定义语法规则
JavaCC的语法单元形如这样:
Token subject() : { Token token = null; } { token = < UNKNOWN > { return token; } | token = < KNOWN > { Token token1 = token; } ( "." token = < KNOWN > { token1.image += "."+ token.image; } )* { return token1; } }开头是一个声明,包括返回值类型、规则名和一个冒号。对于这样一条语法规则,JavaCC就会在语法分析器类中生成一个同名的方法。紧接着的一对花括号中写一些变量声明。下一对花括号中写该规则的具体内容。
一个语法单元中有多个规则时,用|分开。每个规则都有一系列词法或语法单元组成,每个词法或者语法单元之后跟着一对花括号,里面写处理的代码
基本上就是这样了。