⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.java

📁 Java编写的表达式计算器, 即可以像我们书写表达式那样直接输入计算表达式, 程序自动进行运算, 支持加减乘除幂运算以及判断表达式如A?B C, 程序包含完整的Document和测试运行环境
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
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 + -