基于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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java码界探秘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值