首先编写.jjt文件SQLParser.jjt:
PARSER_BEGIN(SQLParser)
public class SQLParser{
public static void main(String args[]) {
System.out.println("Reading from standard input...");
SQLParser p = new SQLParser(System.in);
try {
SimpleNode n = p.Start();
n.dump("");
System.out.println("Thank you.");
} catch (Exception e) {
System.out.println("Oops.");
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
PARSER_END(SQLParser)
/*定义词法分析*/
SKIP:{" "}
SKIP:{"\n"|"\r"|"\r\n"}
TOKEN:/*定义关键字*/
{
<CREATE:"create">
| <TABLE:"table">
| <DROP:"drop">
| <SELECT:"select">
| <INSERT:"insert">
| <WHERE:"where">
| <FROM:"from">
| <INTO:"into">
| <DISTINCT:"distinct">
| <LIKE:"like">
| <ORDER:"order">
| <BY:"by">
| <VALUES:"values">
| <AND:"and">
| <IN:"in">
| <INT:"int">
| <CHAR:"char">
| <DATE:"date">
| <DELETE:"delete">
}
TOKEN:/*定义符号*/
{
<UNDERSCORE:"_">
| <COMMA:",">
| <SEMICOLON:";">
| <COLON:":">
| <LEFTPARENTHESES:"(">
| <RIGHTPARENTHESES:")">
| <EQUAL:"=">
| <PLUS:"+">
| <MINUS:"-">
| <TIMES:"*">
| <DIVIDE:"/">
| <LEFTQUOTATION:"\"">
| <LQUOTATION:"'">
}
TOKEN:/* 定义整数 */
{
<INTEGER_LITERAL:["1"-"9"](<DIGIT>)*>
}
TOKEN:/*定义数字*/
{
<#DIGIT:["0"-"9"]>
}
TOKEN:/* 定义标识符 */
{
<IDENTIFIER:<LETTER>
|<LETTER><DIGIT>
| <LETTER>(<LETTER>
| <DIGIT>
| <UNDERSCORE>)*(<LETTER>
| <DIGIT>)+>
| <#LETTER:["a"-"z", "A"-"Z"]>
}
/* 语法解析*/
SimpleNode Start() : {}
{
Expression() ";"
{ return jjtThis; }
}
void Expression() : {}
{
Query()|CreT()|DropT()|DelT()|InsT()
}
void Query():{}
{
SFW()[<ORDER><BY>Attribute()]
}
void SFW():{}
{
<SELECT>[<DISTINCT>]SelList()<FROM>FromList()<WHERE>Condition()
}
void SelList():{}
{
Attribute()[(<COMMA>Attribute())+]
}
void FromList():{}
{
Relation()[(<COMMA>Relation())+]
}
void Condition():{}
{
/*[Condition()<AND>Condition()]|*/
/*[Tuple()<IN>Query()]*/
[Attribute()<EQUAL>Attribute()]
|[Attribute()<LIKE>Pattern()]
|[Attribute()<EQUAL>IDENTIFIER()]
}
void Tuple():{}
{
Attribute()
}
/*-------------------*/
void CreT():{}
{
<CREATE><TABLE>Relation()<LEFTPARENTHESES>ColList()<RIGHTPARENTHESES>
}
void ColList():{}
{
Attribute()Type()[(<COMMA>Attribute()Type())+]
}
void Type():{}
{
<INT>|<DATE>|<CHAR><LEFTPARENTHESES><INTEGER_LITERAL><RIGHTPARENTHESES>
}
/*-------------------*/
void DropT():{}
{
<DROP><TABLE>Relation()
}
void DelT():{}
{
<DELETE>DelList()<FROM>FromList()<WHERE>Condition()
}
void DelList():{}
{
Attribute()[(<COMMA>Attribute())+]
}
/*-------------------*/
void InsT():{}
{
<INSERT><INTO>Relation()<LEFTPARENTHESES>InList()<RIGHTPARENTHESES><VALUES><LEFTPARENTHESES>VList()<RIGHTPARENTHESES>
}
void InList():{}
{
Attribute()[(<COMMA>Attribute())+]
}
void VList():{}
{
<LEFTQUOTATION>IDENTIFIER()<LEFTQUOTATION>[(<COMMA><LEFTQUOTATION>IDENTIFIER()<LEFTQUOTATION>)+]
}
/*-------------------*/
void Attribute():{}
{
IDENTIFIER()
}
void Relation():{}
{
IDENTIFIER()
}
void Pattern():{}
{
<LQUOTATION>IDENTIFIER()<LQUOTATION>
}
/*-------------------*/
void IDENTIFIER():{}
{
<IDENTIFIER>
}
得到SQLParser.jj:
/*@bgen(jjtree) Generated By:JJTree: Do not edit this line. .\SQLParser.jj *//*@egen*/PARSER_BEGIN(SQLParser)public class SQLParser/*@bgen(jjtree)*/implements SQLParserTreeConstants/*@egen*/{/*@bgen(jjtree)*/ protected static JJTSQLParserState jjtree = new JJTSQLParserState();/*@egen*/ public static void main(String args[]) { System.out.println("Reading from standard input..."); SQLParser p = new SQLParser(System.in); try { SimpleNode n = p.Start(); n.dump(""); System.out.println("Thank you."); } catch (Exception e) { System.out.println("Oops."); System.out.println(e.getMessage()); e.printStackTrace(); } }}PARSER_END(SQLParser)/*\u5b9a\u4e49\u8bcd\u6cd5\u5206\u6790*/SKIP:{" "}SKIP:{"\n"|"\r"|"\r\n"}TOKEN:/*\u5b9a\u4e49\u5173\u952e\u5b57*/{ <CREATE:"create"> | <TABLE:"table"> | <DROP:"drop"> | <SELECT:"select"> | <INSERT:"insert"> | <WHERE:"where"> | <FROM:"from"> | <INTO:"into"> | <DISTINCT:"distinct"> | <LIKE:"like"> | <ORDER:"order"> | <BY:"by"> | <VALUES:"values"> | <AND:"and"> | <IN:"in"> | <INT:"int"> | <CHAR:"char"> | <DATE:"date"> | <DELETE:"delete">}TOKEN:/*\u5b9a\u4e49\u7b26\u53f7*/{ <UNDERSCORE:"_"> | <COMMA:","> | <SEMICOLON:";"> | <COLON:":"> | <LEFTPARENTHESES:"("> | <RIGHTPARENTHESES:")"> | <EQUAL:"="> | <PLUS:"+"> | <MINUS:"-"> | <TIMES:"*"> | <DIVIDE:"/"> | <LEFTQUOTATION:"\""> | <LQUOTATION:"'">}TOKEN:/* \u5b9a\u4e49\u6574\u6570 */{ <INTEGER_LITERAL:["1"-"9"](<DIGIT>)*>}TOKEN:/*\u5b9a\u4e49\u6570\u5b57*/{ <#DIGIT:["0"-"9"]>}TOKEN:/* \u5b9a\u4e49\u6807\u8bc6\u7b26 */{ <IDENTIFIER:<LETTER> |<LETTER><DIGIT> | <LETTER>(<LETTER> | <DIGIT> | <UNDERSCORE>)*(<LETTER> | <DIGIT>)+> | <#LETTER:["a"-"z", "A"-"Z"]>}/* \u8bed\u6cd5\u89e3\u6790*/SimpleNode Start() : {/*@bgen(jjtree) Start */ SimpleNode jjtn000 = new SimpleNode(JJTSTART); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000);/*@egen*/}{/*@bgen(jjtree) Start */ try {/*@egen*/ Expression() ";"/*@bgen(jjtree)*/ { jjtree.closeNodeScope(jjtn000, true); jjtc000 = false; }/*@egen*/ { return jjtn000; }/*@bgen(jjtree)*/ } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { throw (RuntimeException)jjte000; } if (jjte000 instanceof ParseException) { throw (ParseException)jjte000; } throw (Error)jjte000; } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } }/*@egen*/}void Expression() : {/*@bgen(jjtree) Expression */ SimpleNode jjtn000 = new SimpleNode(JJTEXPRESSION); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000);/*@egen*/}{/*@bgen(jjtree) Expression */ try {/*@egen*/ Query()|CreT()|DropT()|DelT()|InsT()/*@bgen(jjtree)*/ } catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { throw (RuntimeException)jjte000; } if (jjte000 instanceof ParseException) { throw (ParseException)jjte000; } throw (Error)jjte000; } finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); } }/*@egen*/}void Query():{/*@bgen(jjtree) Query */ SimpleNode jjtn000 = new SimpleNode(JJTQUERY); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000);/*@egen*/}{/*@bgen(jjtree) Query */try {/*@egen*/SFW()[<ORDER><BY>Attribute()]/*@bgen(jjtree)*/} catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { throw (RuntimeException)jjte000; } if (jjte000 instanceof ParseException) { throw (ParseException)jjte000; } throw (Error)jjte000;} finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); }}/*@egen*/}void SFW():{/*@bgen(jjtree) SFW */ SimpleNode jjtn000 = new SimpleNode(JJTSFW); boolean jjtc000 = true; jjtree.openNodeScope(jjtn000);/*@egen*/}{/*@bgen(jjtree) SFW */try {/*@egen*/<SELECT>[<DISTINCT>]SelList()<FROM>FromList()<WHERE>Condition()/*@bgen(jjtree)*/} catch (Throwable jjte000) { if (jjtc000) { jjtree.clearNodeScope(jjtn000); jjtc000 = false; } else { jjtree.popNode(); } if (jjte000 instanceof RuntimeException) { throw (RuntimeException)jjte000; } if (jjte000 instanceof ParseException) { throw (ParseException)jjte000; } throw (Error)jjte000;} finally { if (jjtc000) { jjtree.closeNodeScope(jjtn000, true); }}/*@egen*/}void SelList():{/*@bgen(jjtree) SelList */ SimpleNode jjtn000 = new SimpleNode(JJTSELLIST); boolean jjtc000 = tr