📄 parser.java
字号:
package parser;
import exceptions.*;
import java.util.*;
import java.math.*;
/**
* 整个程序的parser,也是分析计算的核心所在
* @author zouhao
* @param opPos 这个字符串数组是用于定位查表的坐标
* @param table 这里是硬编码的OPP表
*/
public class Parser {
String opPos[] = {"(",")","f","-","^","m/d","+/-","cmp","!","&","|","?",":",",","Decimal","Boolean","$"};
static int table[][] = {
/* ( ) f - ^ m/d +/- cmp ! & | ? : , id T/F $*/
/*(*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -5, 0, 0, 0, -2},
/*)*/ {-3, 4, -3, -3, 4, 4, 4, 4, -3, 4, 4, 4, 4, 4, -3, -3, 4},
/*f*/ {0, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4},
/*-*/ {0, 5, 0, 0, 5, 5, 5, 5, -3, 5, 5, 5, 5, 5, 0, -6, 5},
/*^*/ {0, 3, 0, 0, 0, 3, 3, 3, -3, 3, 3, 3, 3, 3, 0, -6, 3},
/*m/d*/{0, 3, 0, 0, 0, 3, 3, 3, -3, 3, 3, 3, 3, 3, 0, -6, 3},
/*+/-*/{0, 3, 0, 0, 0, 0, 3, 3, -3, 3, 3, 3, 3, 3, 0, -6, 3},
/*cmp*/{0, 6, 0, 0, 0, 0, 0, 6, 6, 6, 6, 6, 6, 6, 0, -6, 6},
/*!*/ {0, 8, -3, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, -6, -6, 0, 8},
/*&*/ {0, 7, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 0, 0, 7},
/*|*/ {0, 7, 0, 0, 0, 0, 0, 0, 7, 0, 7, 7, 7, 7, 0, 0, 7},
/*?*/ {0, -5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -5, 0, 0, -5},
/*:*/ {0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -5, 0, 0, 9},
/*,*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -5, 0, 0, 0, -4},
/*id*/ {-3, 2, -3, -3, 2, 2, 2, 2, -3, 2, 2, 2, 2, 2, -3, -3, 2},
/*T/F*/{-3, 2, -3, -3, -6, -6, -6, -6, -3, 2, 2, 2, -6, -6, -3, -3, 2},
/*$*/ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -7, 0, 0, 1}};
double result;
String input;
ArrayList<Token> stack;
Scanner scanner;
int index;
/**
* 构造函数
* @param temp 初始化对象的输入流
*/
public Parser(String temp)
{
input = temp;
result = 0;
index = 0;
scanner = new Scanner(input);
stack = new ArrayList<Token>();
stack.add(new DollarToken());
}
/**
* 查表函数,其中会根据opp表中的空白项抛出异常
* @param l 用于查表的左token
* @param r 用于查表的右token
* @return 返回查表结果用于判断是shift还是reduce
* @throws exceptions.MissingOperandException 缺少运算量异常
* @throws exceptions.MissingRightParenthesisException 缺少右括号异常
* @throws exceptions.MissingOperatorException 缺少运算符异常
* @throws exceptions.FunctionCallException 函数调用异常
* @throws exceptions.TrinaryOperationException 三元函数调用异常
* @throws exceptions.TypeMismatchedException 类型不匹配异常
* @throws exceptions.SyntacticException 语法异常(通常不抛出)
*/
String search(Token l,Token r) throws
MissingOperandException,
MissingRightParenthesisException,
MissingOperatorException,
FunctionCallException,
TrinaryOperationException,
TypeMismatchedException,
SyntacticException
{
int indexl = 0,indexr = 0;
if(l.getType().equals("Decimal")||l.getType().equals("Boolean")||l.getType().equals("$"))
{for(indexl = 0;indexl < 17;indexl++)if(l.getType().equals(opPos[indexl]))break;}
else if(l.getType().equals("Operator")||l.getType().equals("Function"))
{for(indexl = 0;indexl < 17;indexl++)if(l.getToken().equals(opPos[indexl]))break;}
if(r.getType().equals("Decimal")||r.getType().equals("Boolean")||r.getType().equals("$"))
{for(indexr = 0;indexr < 17;indexr++)if(r.getType().equals(opPos[indexr]))break;}
else if(r.getType().equals("Operator")||r.getType().equals("Function"))
{for(indexr = 0;indexr < 17;indexr++) if(r.getToken().equals(opPos[indexr]))break;}
int address = table[indexl][indexr];
if(address == 0){return "shift";}
else if(address == 1){return "accept";}
else if(address == 2){return "bool";}
else if(address == 3){return "2y";}
else if(address == 4){return "()";}
else if(address == 5){return "-";}
else if(address == 6){return "2b";}
else if(address == 7){return "2g";}
else if(address == 8){return "!";}
else if(address == 9){return "3y";}
else if(address == -1){throw new MissingOperandException();}
else if(address == -2){throw new MissingRightParenthesisException();}
else if(address == -3){throw new MissingOperatorException();}
else if(address == -4){throw new FunctionCallException();}
else if(address == -5){throw new TrinaryOperationException();}
else if(address == -6){throw new TypeMismatchedException();}
else if(address == -7){throw new SyntacticException();}
return "";
}
/**
* shift操作的方法
* @param temp 用shift的token
*/
public void shift(Token temp)
{
if(!temp.getType().equals("$"))
{
stack.add(temp);
}
}
/**
* reduce方法
* @param type 指示reduce的操作
* @throws exceptions.MissingOperandException 缺少运算量异常
* @throws exceptions.MissingOperatorException 缺少运算符异常
* @throws exceptions.MissingRightParenthesisException 缺少右括号异常
* @throws exceptions.FunctionCallException 函数调用异常
* @throws exceptions.TrinaryOperationException 三元函数调用异常
* @throws exceptions.TypeMismatchedException 类型不匹配异常
* @throws exceptions.SyntacticException 语法异常(通常不抛出)
* @throws exceptions.SemanticException 语义异常(通常不抛出)
*/
public void reduce(String type) throws
MissingOperandException,
MissingOperatorException,
MissingRightParenthesisException,
FunctionCallException,
TrinaryOperationException,
TypeMismatchedException,
SyntacticException,
SemanticException
{
if(type.equals("2y"))
{
double r = psmd();
stack.add(new DecimalToken(r));
}
if(type.equals("()"))
{
double r = parent();
if(r != 2)
stack.add(new DecimalToken(r));
}
if(type.equals("-"))
{
double r = neg();
stack.add(new DecimalToken(r));
}
if(type.equals("!"))
{
String r = not();
stack.add(new BooleanToken(r));
}
if(type.equals("2b"))
{
String r = cmp();
stack.add(new BooleanToken(r));
}
if(type.equals("2g"))
{
String r = realation();
stack.add(new BooleanToken(r));
}
if(type.equals("3y"))
{
double r = trinary();
stack.add(new DecimalToken(r));
}
index = stack.size()-1;
scanner.forward();
}
/**
* 运作整个paser的方法,控制查表和shift,reduce操作
* @throws exceptions.IllegalIdentifierException 未定义字符异常
* @throws exceptions.IllegalDecimalException 数值格式异常
* @throws exceptions.IllegalSymbolException 非法字符异常
* @throws exceptions.MissingOperandException 缺少运算量异常
* @throws exceptions.MissingOperatorException 缺少运算符异常
* @throws exceptions.MissingRightParenthesisException 缺少右括号异常
* @throws exceptions.FunctionCallException 函数调用异常
* @throws exceptions.TrinaryOperationException 三元函数调用异常
* @throws exceptions.TypeMismatchedException 类型不匹配异常
* @throws exceptions.SyntacticException 语法异常(通常不抛出)
* @throws exceptions.SemanticException 语义异常(通常不抛出)
*/
public void parsing() throws
IllegalIdentifierException,
MissingOperandException,
MissingOperatorException,
MissingRightParenthesisException,
FunctionCallException,
TrinaryOperationException,
TypeMismatchedException,
SyntacticException,
SemanticException,
IllegalDecimalException,
IllegalSymbolException
{
Token temp = new DecimalToken(0);
do
{
index = stack.size()-1;
if(stack.get(index).getType().equals("Decimal"))index--;
else if(stack.get(index).getType().equals("Boolean"))index--;
if(!temp.getType().equals("$"))
temp = scanner.getNextToken();
String seaR = search(stack.get(index),temp);
if(seaR.equals("accept"))continue;
if(seaR.equals("shift"))shift(temp);
else if(seaR.equals("2y"))reduce("2y");
else if(seaR.equals("()"))reduce("()");
else if(seaR.equals("-"))reduce("-");
else if(seaR.equals("!"))reduce("!");
else if(seaR.equals("3y"))reduce("3y");
else if(seaR.equals("2b"))reduce("2b");
else if(seaR.equals("2g"))reduce("2g");
if(stack.get(index).getType().equals("Decimal"))index--;
else if(stack.get(index).getType().equals("Boolean"))index--;
}while(!(stack.get(index).getType().equals("$") && temp.getType().equals("$")));
if(search(stack.get(index),temp).equals("accept"))
{
if(stack.get(stack.size()-1).getType().equals("Decimal"))
result = ((DecimalToken)stack.get(stack.size()-1)).getResult();
else throw new TypeMismatchedException();
}
}
/**
* 获取parsing结果的方法
* @return 返回结果
*/
public double getresult()
{
return result;
}
/**
* 规约二元运算的方法
* @return 运算结果
* @throws exceptions.MissingOperandException 缺少操作量异常
* @throws exceptions.DividedByZeroException 除数为0异常
* @throws exceptions.MissingOperatorException 缺少操作符异常
* @throws exceptions.TypeMismatchedException 类型不匹配异常
*/
double psmd() throws
MissingOperandException,
DividedByZeroException,
MissingOperatorException,
TypeMismatchedException
{
double r = 0,l = 0;
Token test = stack.remove(stack.size()-1);
if(test.type.equals("Decimal"))
{
DecimalToken right = (DecimalToken)test;
r = right.getResult();
}else if(test.getType().equals("Operator"))throw new MissingOperandException();
else throw new TypeMismatchedException();
Token temp = stack.remove(stack.size()-1);
test = stack.remove(stack.size()-1);
if(test.type.equals("Decimal"))
{
DecimalToken left = (DecimalToken)test;
l = left.getResult();
}else if(test.getType().equals("Operator"))throw new MissingOperandException();
else throw new TypeMismatchedException();
if(!temp.getType().equals("Operator"))throw new MissingOperatorException();
if(temp.toString().equals("+"))return r+l;
else if(temp.toString().equals("-"))return l-r;
else if(temp.toString().equals("*"))return r*l;
else if(temp.toString().equals("/"))
{
if(r == 0)throw new DividedByZeroException();
return l/r;
}
else if(temp.toString().equals("^"))
{
return Math.pow(l, r);
}
return 0;
}
/**
* 规约括号操作,这里包括函数的规约
* @return 运算结果
* @throws exceptions.MissingLeftParenthesisException 缺少左括号异常
* @throws exceptions.MissingRightParenthesisException 缺少右括号异常
* @throws exceptions.FunctionCallException 函数调用异常
* @throws exceptions.MissingOperandException 缺少操作量异常
* @throws exceptions.TypeMismatchedException 类型不匹配异常
*/
double parent() throws
MissingLeftParenthesisException,
MissingRightParenthesisException,
FunctionCallException,
MissingOperandException,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -