All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cdc.applic.expressions.Expression Maven / Gradle / Ivy

There is a newer version: 0.13.3
Show newest version
package cdc.applic.expressions;

import java.util.ArrayList;
import java.util.List;

import cdc.applic.expressions.ast.FalseNode;
import cdc.applic.expressions.ast.ParsingNode;
import cdc.applic.expressions.ast.TrueNode;
import cdc.applic.expressions.parsing.Parser;
import cdc.applic.expressions.parsing.Recognizer;

public class Expression implements Comparable {
    /**
     * String representation of the Expression, as defined at creation time.
     */
    private String content;

    /**
     * The AST root node.
     */
    private ParsingNode root = null;

    /**
     * The formatting to use to obtain the most compact string content.
     */
    public static final Formatting COMPRESS_FORMATTING = Formatting.SHORT_NARROW;

    public static final Expression TRUE = new Expression("true");
    public static final Expression FALSE = new Expression("false");

    /**
     * Default expression pool.
     */
    public static final ExpressionPool DEFAULT_POOL = new ExpressionPool();

    /**
     * If set to {@code true}, {@link #fromString(String)} uses {@link #DEFAULT_POOL}.
     */
    public static boolean useDefaultPool = true;

    /**
     * Creates an expression and checks its syntax if required.
     *
     * @param content The expression content.
     * @param parse If {@code true}, {@code content } is parsed.
     * @throws LexicalException When this expression is lexically invalid and {@code parse} is {@code true}.
     * @throws SyntacticException When this expression is syntactically invalid and {@code parse} is {@code true}.
     */
    public Expression(String content,
                      boolean parse) {
        if (content == null || content.trim().isEmpty()) {
            this.content = "true";
        } else {
            this.content = content;
        }
        if (parse) {
            getRootNode();
        }
    }

    /**
     * Creates an expression and checks its syntax.
     *
     * @param content The expression content.
     * @throws LexicalException When this expression is lexically invalid.
     * @throws SyntacticException When this expression is syntactically invalid.
     */
    public Expression(String content) {
        this(content, true);
    }

    /**
     * Creates an expression from a node.
     *
     * @param root The root node.
     * @param formatting The optional formating used to create string representation of the expression.
     *            If {@code null}, the string representation will be created lazily using default formatting.
     */
    public Expression(ParsingNode root,
                      Formatting formatting) {
        if (formatting != null) {
            this.content = root.toInfix(formatting);
        }
        this.root = root;
    }

    /**
     * Creates an expression from a node, and creates a string representation using default formatting.
     *
     * @param root The root node.
     */
    public Expression(ParsingNode root) {
        this(root, COMPRESS_FORMATTING);
    }

    /**
     * @return The text representation of this expression, as defined at creation.
     */
    public String getContent() {
        if (content == null) {
            content = root.toInfix(COMPRESS_FORMATTING);
        }
        return content;
    }

    /**
     * @return The AST root node.
     * @throws LexicalException When this expression is lexically invalid.
     * @throws SyntacticException When this expression is syntactically invalid.
     */
    public ParsingNode getRootNode() {
        if (root == null) {
            final Parser parser = new Parser();
            root = parser.parse(content);
        }
        return root;
    }

    /**
     * @return {@code true} if this expression is syntactically valid.
     */
    public boolean isValid() {
        // If root is null, content is not null
        return root != null || isValid(content);
    }

    /**
     * Checks the validity of the expression.
     *
     * @throws LexicalException When this expression is lexically invalid.
     * @throws SyntacticException When this expression is syntactically invalid.
     */
    public void checkValidity() {
        getRootNode();
    }

    /**
     * @return {@code true} if this expression is simply true.
     */
    public boolean isTrue() {
        return getRootNode() instanceof TrueNode;
    }

    /**
     * @return {@code true} if this expression is simply false.
     */
    public boolean isFalse() {
        return getRootNode() instanceof FalseNode;
    }

    /**
     * @param expression The expression text.
     * @return {@code true} if {@code expression} can be parsed as a valid Expression.
     */
    public static boolean isValid(String expression) {
        final Recognizer recognizer = new Recognizer();
        return recognizer.isValid(expression);
    }

    /**
     * Converts a string to an Expression.
     * 

* {@link #DEFAULT_POOL} is used if {@link #useDefaultPool} is set to {@code true}. * * @param content The expression content. * @return The Expression corresponding to {@code content} or {@code null} if content is {@code null}. */ public static Expression fromString(String content) { return content == null ? null : (useDefaultPool ? DEFAULT_POOL.get(content) : new Expression(content)); } public static Expression of(String content) { return new Expression(content); } public static Expression of(String content, boolean parse) { return new Expression(content, parse); } /** * @param expression The expression. * @return The string representation of {@code expression}. */ public static String asString(Expression expression) { return expression.getContent(); } public static ParsingNode toNode(Expression expression) { return expression.getRootNode(); } public static Expression fromNode(ParsingNode node) { return new Expression(node); } public static ParsingNode[] toNodeArray(Expression... expressions) { final ParsingNode[] result = new ParsingNode[expressions.length]; for (int index = 0; index < result.length; index++) { result[index] = expressions[index].getRootNode(); } return result; } public static ParsingNode[] toNodeArray(List expressions) { final ParsingNode[] result = new ParsingNode[expressions.size()]; for (int index = 0; index < result.length; index++) { result[index] = expressions.get(index).getRootNode(); } return result; } public static List toNodeList(Expression... expressions) { final List result = new ArrayList<>(expressions.length); for (final Expression expression : expressions) { result.add(expression.getRootNode()); } return result; } public static List toNodeList(List expressions) { final List result = new ArrayList<>(expressions.size()); for (final Expression expression : expressions) { result.add(expression.getRootNode()); } return result; } public static List toExpressionList(String... expressions) { final List result = new ArrayList<>(expressions.length); for (final String expression : expressions) { result.add(new Expression(expression)); } return result; } /** * @param formatting The formatting. * @return A infix representation of this expression using {@code formatting}. */ public String toInfix(Formatting formatting) { if (content == null && (formatting == null || formatting.equals(COMPRESS_FORMATTING))) { // This expression was built from a node and null formatting. // We can computes its content. return getContent(); } else { return getRootNode().toInfix(formatting); } } /** * @return An expression equivalent to this one and whose text is compressed. * @throws LexicalException When this expression is lexically invalid. * @throws SyntacticException When this expression is syntactically invalid. */ public Expression compress() { if (content == null) { // The expression was built from a node and a null formatting // We now its text will use compress formatting return this; } else { // We build a new expression from root node and null formatting return new Expression(getRootNode(), null); } } @Override public int compareTo(Expression o) { return getContent().compareTo(o.getContent()); } @Override public int hashCode() { return getContent().hashCode(); } @Override public boolean equals(Object object) { if (this == object) { return true; } if (!(object instanceof Expression)) { return false; } final Expression other = (Expression) object; return getContent().equals(other.getContent()); } @Override public String toString() { return getContent(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy