简要说明一下用javacc实现四则运算。
1.下载javacc eclipse插件
http://keihanna.dl.sourceforge.net/sourceforge/eclipse-javacc/EclipseJavaCC-1.5.1.zip
2.编写Calc.jj文件,新增会有个例子,在此基础上修改即可。jjt不好用,值没存入节点中,且傻瓜式地根据文法产生中间无用对象,还是自己解析AST好。
3.Calc.jj文件
------------------------------------------------------------
/**
* JavaCC file
* 四则运算
* zfzheng
*/
options {
JDK_VERSION = "1.5";
}
PARSER_BEGIN(Calc)
package com.mycc;
public class Calc {
public static void main(String args[]) throws ParseException {
System.out.print("请输入算术表达式,以;号结束:");
Calc calc = new Calc(System.in);
TreeNode root=calc.parse();
double value=root.evalAll();
System.out.println("/n解析完毕,计算值="+value);
}
}
PARSER_END(Calc)
SKIP :
{
" "
| "/r"
| "/t"
| "/n"
}
TOKEN : /* OPERATORS */
{
< PLUS: "+" >
| < MINUS: "-" >
| < MULTIPLY: "*" >
| < DIVIDE: "/" >
| <LPAREN:"(">
| <RPAREN:")">
}
TOKEN :
{
< CONSTANT: ( <DIGIT> )+ ("."(<DIGIT>)+)?>
| < #DIGIT: ["0" - "9"]>
}
TreeNode parse() : {
TreeNode node=null;
TreeNode root=null;
}
{
(
node=sum(){
if(root==null){
root=node;
}else{
TreeNode p;
p=root;
while(p.next!=null){
p=p.next;
}
p.next=node;
}
}
)*";"
{
return node;
}
}
TreeNode sum() : {
TreeNode root=null;
TreeNode left;
TreeNode right;
int op;
}
{
left=term()
(
op=addop()
right=term()
{
TreeNode buf=new TreeNode();
buf.addChild(left);
buf.addChild(right);
buf.type=op;
switch(op){
case NodeType.PLUS:
buf.text="+";
break;
case NodeType.MINUS:
buf.text="-";
break;
}
// System.err.println(buf+" 左="+left+"右="+right);
if(root==null){
root=buf;
}else{
TreeNode p=root;
while(p.next!=null){
p=p.next;
}
p.next=buf;
}
left=buf;//重要
}
)*
{
if(root==null){
root=left;
}
return root;
}
}
int addop():{}
{
<PLUS> {return NodeType.PLUS;}|<MINUS> {return NodeType.MINUS;}
}
TreeNode term() : {
TreeNode root=null;
TreeNode left;
TreeNode right;
int op;
}
{
left=unary()
(
op=mulop()
right=unary()
{
TreeNode buf=new TreeNode();
buf.addChild(left);
buf.addChild(right);
buf.type=op;
switch(op){
case NodeType.MULTIPLY:
buf.text="*";
break;
case NodeType.DIVIDE:
buf.text="/";
break;
}
if(root==null){
root=buf;
}else{
TreeNode p=root;
while(p.next!=null){
p=p.next;
}
p.next=buf;
}
left=right;
}
)*
{
if(root==null){
root=left;
}
return root;
}
}
int mulop():{}
{
<MULTIPLY> {return NodeType.MULTIPLY;} | <DIVIDE> {return NodeType.DIVIDE;}
}
TreeNode unary() : {
TreeNode node;
}
{
<MINUS> node=element()
{
node.text="-"+node.text;
return node;
}
|
node=element(){
return node;
}
}
TreeNode element() : {
TreeNode node;
Token t;
}
{
t=<CONSTANT>
{
//System.err.println(token.image);
node=new TreeNode();
node.text=t.image;
node.type=NodeType.VALUE;
return node;
}
| <LPAREN> node=sum() <RPAREN>{
return node;
}
}
------------------------------------------------------------
4.新增TreeNode、NodeType:TreeNode的evalAll只需要搜索到最后节点,求eval(TreeNode本身求值方法)值即可,从底第归求值。
运行结果:
-------------------------------------------------
请输入算术表达式,以;号结束:1+2*3-4/5;
2.0*3.0=6.0
1.0+6.0=7.0
4.0/5.0=0.8
7.0-0.8=6.2
解析完毕,计算值=6.2