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

📄 expressionevaluator.java

📁 eclipseme的最新版本的source,欢迎j2me程序员使用
💻 JAVA
字号:
/**
 * Copyright (c) 2003-2005 Craig Setera
 * All Rights Reserved.
 * Licensed under the Eclipse Public License - v 1.0
 * For more information see http://www.eclipse.org/legal/epl-v10.html
 */
package eclipseme.core.internal.preprocessor.directive;

import java.util.Stack;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.InfixExpression;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.PrefixExpression;
import org.eclipse.jdt.core.dom.QualifiedName;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;

import eclipseme.core.model.SymbolDefinitionSet;

/**
 * A class that is capable of evaluating a directive
 * expression for a true or false value.
 * <p />
 * Copyright (c) 2003-2005 Craig Setera<br>
 * All Rights Reserved.<br>
 * Licensed under the Eclipse Public License - v 1.0<p/>
 * <br>
 * $Revision: 1.2 $
 * <br>
 * $Date: 2006/11/12 01:11:01 $
 * <br>
 * @author Craig Setera
 */
public class ExpressionEvaluator {
	private static final String PREAMBLE =
		"public class ParseClass { " +
		"public static boolean value = ";
	private static final String POSTLUDE = "; }";
	
	// An AST visitor to find the actual expression that we are interested in
	// locating.
	private class LocateExpressionVisitor extends ASTVisitor {
		private Expression expression;
		
		/**
		 * Construct a new visitor 
		 */
		LocateExpressionVisitor() {
			super(false);
		}

		/**
		 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.VariableDeclarationExpression)
		 */
		public boolean visit(VariableDeclarationFragment node) {
			expression = node.getInitializer();
			return false;  // No need to continue searching
		}
		
		/**
		 * Return the expression located by the visitor.
		 * 
		 * @return
		 */
		public Expression getExpression() {
			return expression;
		}
	}

	private class ExpressionEvaluationVisitor extends ASTVisitor {
		private SymbolDefinitionSet identifiers;
		private Stack resultStack;
		
		/**
		 * Construct a new visitor
		 * @param identifiers 
		 */
		public ExpressionEvaluationVisitor(SymbolDefinitionSet identifiers) {
			super(false);
			this.identifiers = identifiers;
			resultStack = new Stack();
		}

		/**
		 * Return the result of the evaluation.
		 * 
		 * @return
		 */
		public boolean getResult() {
			return ((Boolean) resultStack.peek()).booleanValue();
		}

		/**
		 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.InfixExpression)
		 */
		public void endVisit(InfixExpression node) {
			InfixExpression.Operator operator = node.getOperator();

			if (operator == InfixExpression.Operator.AND) {
				pushValue(popValue() & popValue());
			} else if (operator == InfixExpression.Operator.CONDITIONAL_AND) {
				pushValue(popValue() && popValue());
			} else if (operator == InfixExpression.Operator.CONDITIONAL_OR) {
				pushValue(popValue() || popValue());
			} else if (operator == InfixExpression.Operator.XOR) {
				pushValue(popValue() ^ popValue());
			} else if (operator == InfixExpression.Operator.OR) {
				pushValue(popValue() | popValue());
			} else {
				throw new UnsupportedOperationException(operator + " unsupported");
			}
		}

		/**
		 * @see org.eclipse.jdt.core.dom.ASTVisitor#endVisit(org.eclipse.jdt.core.dom.PrefixExpression)
		 */
		public void endVisit(PrefixExpression node) {
			PrefixExpression.Operator operator = node.getOperator();

			if (operator == PrefixExpression.Operator.NOT) {
				pushValue(!popValue());
			} else {
				throw new UnsupportedOperationException(operator + " unsupported");
			}
		}

		/**
		 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.QualifiedName)
		 */
		public boolean visit(QualifiedName node) {
			visitName(node);
			return true;
		}

		/**
		 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.SimpleName)
		 */
		public boolean visit(SimpleName node) {
			visitName(node);
			return true;
		}
		
		/**
		 * Return the top boolean value on the stack.
		 * 
		 * @return
		 */
		private boolean popValue() {
			Boolean topValue = (Boolean) resultStack.pop();
			return topValue.booleanValue();
		}
		
		/**
		 * Push a new boolean value onto the stack.
		 * 
		 * @param value
		 */
		private void pushValue(boolean value) {
			resultStack.push(Boolean.valueOf(value));
		}
		
		/**
		 * Visit a name.
		 * 
		 * @param node
		 */
		private void visitName(Name node) {
			String name = node.getFullyQualifiedName();
			pushValue(identifiers.isDefined(name));
		}
	}
	
	private String expression;
	
	/**
	 * Construct a new evaluator for the specified expression.
	 * 
	 * @param expression
	 */
	public ExpressionEvaluator(String expression) {
		super();
		this.expression = expression;
	}
	
	/**
	 * Evaluate the expression and return the results of the evaluation.
	 * 
	 * @param monitor
	 * @return
	 */
	public boolean evaluate(SymbolDefinitionSet identifiers, IProgressMonitor monitor) {
		Expression expression = getExpression(monitor);
		
		ExpressionEvaluationVisitor visitor = new ExpressionEvaluationVisitor(identifiers);
		expression.accept(visitor);
		
		return visitor.getResult();
	}
	
	/**
	 * Return the expression node created for the expression.
	 * 
	 * @param monitor
	 * @return
	 */
	private Expression getExpression(IProgressMonitor monitor) {
		ASTNode compilationUnitNode = parseExpression(monitor);
		LocateExpressionVisitor visitor = new LocateExpressionVisitor();
		compilationUnitNode.accept(visitor);
		
		return visitor.getExpression();
	}
	
	/**
	 * Return the expression in a form that it may be parsed by the
	 * Eclipse AST implementation.
	 * 
	 * @return
	 */
	private String getParsableExpression() {
		StringBuffer sb = new StringBuffer(PREAMBLE);
		sb.append(expression).append(POSTLUDE);
		
		return sb.toString();
	}

	/**
	 * Return an AST compilation unit representing the 
	 * parsable expression.
	 * 
	 * @param monitor
	 * @return
	 */
	private ASTNode parseExpression(IProgressMonitor monitor) {
		ASTParser parser = ASTParser.newParser(AST.JLS3);
		String parsable = getParsableExpression();
		parser.setSource(parsable.toCharArray());
		
		return parser.createAST(monitor);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -