javacc的功能和yacc相似,主要根据bnf范式生成解析程序,不过javacc是集合了词法分析和语法分析生成java解析代码,主页为:https://javacc.dev.java.net/
javacc有三个工具
javacc 用来处理语法文件(jj)生成解析代码;
jjtree 用来处理jjt文件,生成树节点代码和jj文件,然后再通过javacc生成解析代码;
jjdoc 根据jj文件生成bnf范式文档(html)
javacc使用的各种语言的grammar 文件这里有很多http://www.cobase.cs.ucla.edu/pub/javacc/ ,例如html,xml,python,vb…..,很多足够用了,呵呵。
javacc 的使用
javacc生成的文件中,最主要的是《grammar》.java这个就是解析器的主程序了了,《grammar》名由jj中定义。
现在根据例子说明jj文件的定义:
bnf范式为:
expression
::=
( ( <newline> )* simple_expression <newline> )* <eof>
simple_expression
::=
term ( addop term )*
addop
::=
<plus>
|
<minus>
term
::=
factor ( mulop factor )*
mulop
::=
<timers>
|
<over>
factor
::=
<id>
|
<num>
|
<minus>
|
<plus>
|
<lparen> simple_expression <rparen>
/*这是一个整数的四则运算的例子*/
/* 运行 javacc grammar.jj
javac *.java
java grammar
>>> 1+1*(1+1)
3
>>>^z
*/
parser_begin(grammar) /*解析代码的入口*/
public class grammar {
public static final int plusop=1;
public static final int minusop=2;
public static final int timersop=3;
public static final int overop=4;
public static void main(string args[]) throws parseexception {
grammar parser = new grammar(system.in);
parser.expression();
}
}
parser_end(grammar)
skip : /* 不处理的字符*/
{
" " | "/t"
}
token : /*生成token的字符定义*/
{
< id: ["a"-"z","a"-"z","_"] ( ["a"-"z","a"-"z","_","0"-"9"] )* >
| < num: ( ["0"-"9"] )+ >
| < plus: "+" >
| < minus: "-" >
| < timers: "*" >
| < over: "/" >
| < lparen: "(" >
| < rparen: ")" >
| <newline: ("/r/n"|"/n"|"/r")>
}
void expression() :
/*完成 expression ::=( ( <newline> )* simple_expression <newline> )* <eof> 的配陪*/
{
int value=0; /* 这个{}中是expression()的定义的局部变量*/
}
{
{
system.out.print(">>>");
}
( (<newline> /* 首先匹配newline 这个taken,完成后转到下一个解析*/
{
system.out.print(">>>"); /*在<newline>下的{}中为如果匹配到<newline>执行的java代码。*/
}
)* value= simple_expression() <newline> /*在换行之前simple_expression()解析表达式 ,输入换行后,一个预算解析完成*/
{system.out.println(value);
system.out.print(">>>");/*在<newline>下的{}中为完成表达式解析,匹配到<newline>执行的java代码。*/
}
)*
<eof> /*系统定义的taken,输入结束符*/
}
int simple_expression() :
/*完成simple_expression ::=bnf term ( addop term )*配陪 */
{
/* 这个{}中是simple_expression()的定义的局部变量*/
int value;
int tvalue;
int op;
}
{
value= term (){} /*配陪term 相*/
(
op=addop() tvalue=term()
{
switch(op)
{
case plusop:
value=value+tvalue;
break;
case minusop:
value=value - tvalue;
break;
}
}
)* /*匹配 ( addop term )* */
{ return value; }
}
int addop() : {}
{
<plus> { return plusop; }
| <minus> { return minusop; }
}
int term() :
{
int value;
int tvalue;
int op;
}
{
value=factor(){}
(
op=mulop() tvalue=factor()
{
switch(op)
{
case timersop:
value=value * tvalue;
break;
case overop:
value=value / tvalue;
break;
}
}
)*
{
return value;
}
}
int mulop() :{}
{
<timers> { return timersop; }
| <over> { return overop; }
}
int factor() :
{
int value;
token t;
}
{
t=<id> /*获得<id>的解析的值*/
{
value=100;
return value;
}
|
t=<num>
{
value= (integer.valueof(t.image)).intvalue();
return value;
}
|
t=<minus>
{
value=0-factor();
return value;
}
|
t=<plus>
{
value=factor();
return value;
}
|
<lparen> value=simple_expression() <rparen>
{
return value;
}
}
根据例子: 基本上是一个taken下跟一个{}用于处理当前tabkn的java代码
jjtree的使用:
jjtree的使用,需要根据实际情况写自己的node类,但是都必须实现node.java接口,jj
闽公网安备 35060202000074号