zoukankan      html  css  js  c++  java
  • 基于antlr的表达式解析器——函数类型验证

    package daicy.formula.evaluator;
    
    import java.util.HashMap;
    import java.util.Map;
    
    import org.antlr.runtime.ANTLRStringStream;
    import org.antlr.runtime.CommonTokenStream;
    import org.antlr.runtime.tree.BaseTree;
    
    import daicy.formula.ActiveOperand;
    import daicy.formula.FormulaLexer;
    import daicy.formula.FormulaParser;
    import daicy.formula.function.Add;
    import daicy.formula.function.FunctionException;
    import daicy.formula.function.Max;
    import daicy.formula.validator.DataTypeProvider;
    import daicy.formula.validator.FunctionTypeValidator;
    import daicy.formula.validator.TowNOneNDataTypeProvider;
    import daicy.formula.validator.ValidatorException;
    
    public class ExpressionValidator extends ExpressionEvaluator {
    
    	public ExpressionValidator(Map variables) {
    
    		super(variables); // TODO Auto-generated constructor stub
    		validators.put(new Max().getName(), new TowNOneNDataTypeProvider());
    		validators.put(new Add().getName(), new TowNOneNDataTypeProvider());
    	}
    
    	// Contains all of the validators in use.
    	private Map<String, DataTypeProvider> validators = new HashMap();
    
    	// call has two oprands ,e.g. call max 2
    	public ActiveOperand eval(String functionName, ActiveOperand[] arguments)
    			throws ValidatorException, FunctionException {
    		FunctionTypeValidator functionTypeValidator = new FunctionTypeValidator();
    		functionTypeValidator.setFunction(this.getFunction(functionName));
    		functionTypeValidator.setDataTypeProvider(this.validators
    				.get(functionName));
    		return functionTypeValidator.validate(arguments);
    
    		// stack.push(frame);
    		// asn 赋值 assign 一个操作数 栈顶元素出栈,存储于数据存储器中
    	}
    
    	public static void main(String[] args) throws Exception {
    		String[] testStr = { "max(3,max(1,2))", "2", "a + b + 3", "a - (b + 3)"
    		// "a + (b * 3",
    		// "11.1+12b+a*b",
    
    		};
    
    		for (String s : testStr) {
    			System.out.println("Input expr: " + s);
    			run(s);
    		}
    
    	}
    
    	public static void run(String expr) throws Exception {
    		ANTLRStringStream in = new ANTLRStringStream(expr);
    		// 词法分析器
    		FormulaLexer lexer = new FormulaLexer(in);
    
    		CommonTokenStream tokens = new CommonTokenStream(lexer);
    		// 语法分析器
    		FormulaParser parser = new FormulaParser(tokens);
    
    		FormulaParser.prog_return ret = parser.prog();
    
    		Map variables = new HashMap();
    		variables.put("a", Integer.valueOf(2));
    		variables.put("b", Integer.valueOf(3));
    
    		ExpressionValidator evaluator = new ExpressionValidator(variables);
    
    		System.out.println(evaluator.eval((((BaseTree) ret.getTree()))));
    		// System.out.println(((BaseTree)ret.getTree()).toStringTree());
    		// toStringTree(((BaseTree)ret.getTree()));
    	}
    }
    
    package daicy.formula.validator;
    
    import daicy.formula.ActiveOperand;
    import daicy.formula.function.Function;
    import daicy.formula.function.FunctionException;
    
    /**
     * A function that can be specified in an expression.
     */
    public class FunctionTypeValidator {
    
    	public Function function;
    
    	public DataTypeProvider dataTypeProvider;
    
    	public Function getFunction() {
    
    		return function;
    	}
    
    	public void setFunction(Function function) {
    
    		this.function = function;
    	}
    
    	public DataTypeProvider getDataTypeProvider() {
    
    		return dataTypeProvider;
    	}
    
    	public void setDataTypeProvider(DataTypeProvider dataTypeProvider) {
    
    		this.dataTypeProvider = dataTypeProvider;
    	}
    
    	/**
    	 * @Title: validate
    	 * @Description:TODO(这里用一句话描述这个方法的作用)
    	 * @param arguments
    	 * @return
    	 * @throws ValidatorException
    	 * @throws FunctionException
    	 *             ActiveOperand 返回类型
    	 * @throws
    	 * @date 2013-11-2 下午10:51:27
    	 */
    
    	public ActiveOperand validate(ActiveOperand[] arguments)
    			throws ValidatorException, FunctionException {
    		ActiveOperand[] argumentsType = this.getDataTypeProvider()
    				.getArguments();
    		ActiveOperand resultType = this.getDataTypeProvider().getResult();
    		if (null == arguments || arguments.length != argumentsType.length) {
    			throw new ValidatorException(this.getFunction().getName()
    					+ "参数个数不对!");
    		}
    		for (int i = 0; i < argumentsType.length; i++) {
    			if (!argumentsType[i].getClazz().isAssignableFrom(
    					arguments[i].getClazz())) {
    				throw new ValidatorException(this.getFunction().getName()
    						+ "的第" + (i + 1) + "个参数的类型不对!");
    			}
    		}
    		ActiveOperand result = this.getFunction().execute(arguments);
    		if (!resultType.getClazz().isAssignableFrom(result.getClazz())) {
    			throw new ValidatorException(this.getFunction().getName()
    					+ "的返回值类型不对!");
    		}
    
    		return result;
    	}
    
    }

    package daicy.formula.validator;
    
    import daicy.formula.ActiveOperand;
    import daicy.formula.function.FunctionException;
    
    /**
     * @Title: DataTypeProvider.java
     * @Package daicy.formula.validator
     * @Description: TODO(添加描述)
     * @author 代长亚
     * @date 2013-11-2 下午8:58:24
     * @version V1.0
     */
    public interface DataTypeProvider {
    	/**
    	 * @Title: getArguments
    	 * @Description:TODO(这里用一句话描述这个方法的作用)
    	 * @return
    	 * @throws FunctionException
    	 *             ActiveOperand[] 返回类型
    	 * @throws
    	 * @date 2013-11-2 下午8:50:15
    	 */
    
    	public ActiveOperand[] getArguments() throws ValidatorException;
    
    	/**
    	 * @Title: getResult
    	 * @Description:TODO(这里用一句话描述这个方法的作用)
    	 * @return
    	 * @throws ValidatorException
    	 *             ActiveOperand 返回类型
    	 * @throws
    	 * @date 2013-11-2 下午9:20:59
    	 */
    
    	public ActiveOperand getResult() throws ValidatorException;
    }
    


  • 相关阅读:
    (22)进程和线程区别
    (21)回调函数
    (20)gevent协程
    (18)ProcessPoolExecutor进程池
    (19)ThreadPoolExecutor线程池
    (17)线程队列---queue LifoQueue PriorityQueue
    (16)线程---定时器Timer
    (15)线程---Condition条件
    (14)线程- Event事件和守护线程Daemon
    IDEA快速搭建WEB项目【记录篇】
  • 原文地址:https://www.cnblogs.com/daichangya/p/12959164.html
Copyright © 2011-2022 走看看