Added element comments to all classes of the expression parser.

Also fixed some id() implementations.
This commit is contained in:
TomyLobo 2011-10-29 17:24:11 +02:00
parent e70446e82e
commit 8797d8ac3c
25 changed files with 153 additions and 3 deletions

View File

@ -32,6 +32,30 @@ import com.sk89q.worldedit.expression.runtime.EvaluationException;
import com.sk89q.worldedit.expression.runtime.RValue;
import com.sk89q.worldedit.expression.runtime.Variable;
/**
* Compiles and evaluates expressions.
*
* Supported operators:
* Logical: &&, ||, ! (unary)
* Bitwise: ~ (unary), >>, <<
* Arithmetic: +, -, *, /, % (modulo), ^ (power), - (unary), --, ++ (prefix only)
* Comparison: <=, >=, >, <, ==, !=, ~= (near)
*
* Supported functions: abs, acos, asin, atan, atan2, cbrt, ceil, cos, cosh, exp, floor, ln, log, log10, max, max, min, min, rint, round, sin, sinh, sqrt, tan, tanh
*
* Constants: e, pi
*
* To compile an equation, run <code>Expression.compile("expression here", "var1", "var2"...)</code>
* If you wish to run the equation multiple times, you can then optimize it, by calling myExpression.optimize();
* You can then run the equation as many times as you want by calling myExpression.evaluate(var1, var2...)
* You do not need to pass values for all variables specified while compiling.
* To query variables after evaluation, you can use myExpression.getVariable("variable name").
* To get a value out of these, use myVariable.getValue()
*
* Variables are also supported and can be set either by passing values to <code>evaluate</code>
*
* @author TomyLobo
*/
public class Expression {
private final Map<String, RValue> variables = new HashMap<String, RValue>();
private final String[] variableNames;

View File

@ -19,6 +19,11 @@
package com.sk89q.worldedit.expression;
/**
* Thrown when there's a problem during any stage of the expression compilation or evaluation.
*
* @author TomyLobo
*/
public class ExpressionException extends Exception {
private static final long serialVersionUID = 1L;

View File

@ -19,6 +19,11 @@
package com.sk89q.worldedit.expression;
/**
* A common superinterface for everything passed to parser processors.
*
* @author TomyLobo
*/
public interface Identifiable {
/**
* Returns a character that helps identify the token, pseudo-token or invokable in question.

View File

@ -31,6 +31,13 @@ import java.util.regex.Pattern;
import com.sk89q.worldedit.expression.lexer.tokens.*;
/**
* Processes a string into a list of tokens.
*
* Tokens can be numbers, identifiers, operators and assorted other characters.
*
* @author TomyLobo
*/
public class Lexer {
private final String expression;
private int position = 0;

View File

@ -21,6 +21,11 @@ package com.sk89q.worldedit.expression.lexer;
import com.sk89q.worldedit.expression.ExpressionException;
/**
* Thrown when the lexer encounters a problem.
*
* @author TomyLobo
*/
public class LexerException extends ExpressionException {
private static final long serialVersionUID = 1L;

View File

@ -19,6 +19,11 @@
package com.sk89q.worldedit.expression.lexer.tokens;
/**
* A single character that doesn't fit any of the other token categories.
*
* @author TomyLobo
*/
public class CharacterToken extends Token {
public final char character;

View File

@ -19,6 +19,11 @@
package com.sk89q.worldedit.expression.lexer.tokens;
/**
* An identifier
*
* @author TomyLobo
*/
public class IdentifierToken extends Token {
public final String value;

View File

@ -19,6 +19,11 @@
package com.sk89q.worldedit.expression.lexer.tokens;
/**
* A keyword
*
* @author TomyLobo
*/
public class KeywordToken extends Token {
public final String value;
@ -29,7 +34,7 @@ public class KeywordToken extends Token {
@Override
public char id() {
return 'i';
return 'k';
}
@Override

View File

@ -19,6 +19,11 @@
package com.sk89q.worldedit.expression.lexer.tokens;
/**
* A number
*
* @author TomyLobo
*/
public class NumberToken extends Token {
public final double value;

View File

@ -19,6 +19,11 @@
package com.sk89q.worldedit.expression.lexer.tokens;
/**
* A unary or binary operator.
*
* @author TomyLobo
*/
public class OperatorToken extends Token {
public final String operator;

View File

@ -21,6 +21,11 @@ package com.sk89q.worldedit.expression.lexer.tokens;
import com.sk89q.worldedit.expression.Identifiable;
/**
* A token. The lexer generates these to make the parser's job easier.
*
* @author TomyLobo
*/
public abstract class Token implements Identifiable {
private final int position;

View File

@ -34,6 +34,13 @@ import com.sk89q.worldedit.expression.runtime.Constant;
import com.sk89q.worldedit.expression.runtime.Functions;
import com.sk89q.worldedit.expression.runtime.RValue;
/**
* Processes a list of tokens into an executable tree.
*
* Tokens can be numbers, identifiers, operators and assorted other characters.
*
* @author TomyLobo
*/
public class Parser {
private final class NullToken extends Token {
private NullToken(int position) {

View File

@ -21,6 +21,11 @@ package com.sk89q.worldedit.expression.parser;
import com.sk89q.worldedit.expression.ExpressionException;
/**
* Thrown when the parser encounters a problem.
*
* @author TomyLobo
*/
public class ParserException extends ExpressionException {
private static final long serialVersionUID = 1L;

View File

@ -13,6 +13,11 @@ import com.sk89q.worldedit.expression.runtime.RValue;
import com.sk89q.worldedit.expression.runtime.Operators;
import com.sk89q.worldedit.expression.runtime.Sequence;
/**
* Helper classfor Parser. Contains processors for statements and operators.
*
* @author TomyLobo
*/
public final class ParserProcessors {
private static final Map<String, String> unaryOpMap = new HashMap<String, String>();

View File

@ -2,6 +2,11 @@ package com.sk89q.worldedit.expression.parser;
import com.sk89q.worldedit.expression.lexer.tokens.OperatorToken;
/**
* The parser uses this pseudo-token to mark operators as prefix operators.
*
* @author TomyLobo
*/
public class PrefixOperator extends PseudoToken {
final String operator;

View File

@ -21,6 +21,11 @@ package com.sk89q.worldedit.expression.parser;
import com.sk89q.worldedit.expression.Identifiable;
/**
* A pseudo-token, inserted by the parser instead of the lexer.
*
* @author TomyLobo
*/
public abstract class PseudoToken implements Identifiable {
private final int position;

View File

@ -19,6 +19,11 @@
package com.sk89q.worldedit.expression.runtime;
/**
* A constant.
*
* @author TomyLobo
*/
public final class Constant extends RValue {
private final double value;

View File

@ -2,6 +2,11 @@ package com.sk89q.worldedit.expression.runtime;
import com.sk89q.worldedit.expression.ExpressionException;
/**
* Thrown when there's a problem during expression evaluation.
*
* @author TomyLobo
*/
public class EvaluationException extends ExpressionException {
private static final long serialVersionUID = 1L;

View File

@ -24,7 +24,15 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* Wrapper for a Java method and its arguments (other Invokables)
*
* @author TomyLobo
*/
public class Function extends RValue {
/**
* Add this annotation on functions that don't always return the same value for the same inputs.
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface Dynamic { }

View File

@ -21,6 +21,11 @@ package com.sk89q.worldedit.expression.runtime;
import java.util.Arrays;
/**
* Contains all functions that can be used in expressions.
*
* @author TomyLobo
*/
public final class Functions {
public static final Function getFunction(int position, String name, RValue... args) throws NoSuchMethodException {
final Class<?>[] parameterTypes = (Class<?>[]) new Class[args.length];

View File

@ -19,6 +19,11 @@
package com.sk89q.worldedit.expression.runtime;
/**
* A value that can be used on the left side of an assignment.
*
* @author TomyLobo
*/
public abstract class LValue extends RValue {
public LValue(int position) {
super(position);

View File

@ -19,6 +19,11 @@
package com.sk89q.worldedit.expression.runtime;
/**
* Contains all unary and binary operators.
*
* @author TomyLobo
*/
public final class Operators {
public static final Function getOperator(int position, String name, RValue lhs, RValue rhs) throws NoSuchMethodException {
if (lhs instanceof LValue) {

View File

@ -21,6 +21,11 @@ package com.sk89q.worldedit.expression.runtime;
import com.sk89q.worldedit.expression.Identifiable;
/**
* A value that can be used on the right side of an assignment.
*
* @author TomyLobo
*/
public abstract class RValue implements Identifiable {
private final int position;

View File

@ -22,6 +22,11 @@ package com.sk89q.worldedit.expression.runtime;
import java.util.ArrayList;
import java.util.List;
/**
* A sequence of operations, usually separated by semicolons in the input stream.
*
* @author TomyLobo
*/
public class Sequence extends RValue {
private final RValue[] sequence;
@ -33,8 +38,7 @@ public class Sequence extends RValue {
@Override
public char id() {
// TODO Auto-generated method stub
return 0;
return 's';
}
@Override

View File

@ -19,6 +19,11 @@
package com.sk89q.worldedit.expression.runtime;
/**
* A variable.
*
* @author TomyLobo
*/
public final class Variable extends LValue {
public double value;