Package adams.parser

Class ReportMathExpression

  • All Implemented Interfaces:
    Destroyable, GlobalInfoSupporter, LoggingLevelHandler, LoggingSupporter, OptionHandler, SizeOfHandler, GrammarSupplier, Serializable

    public class ReportMathExpression
    extends AbstractExpressionEvaluator<Double>
    implements GrammarSupplier
    Evaluates mathematical expressions on report values.

    The following grammar is used:

    expr_list ::= '=' expr_list expr_part | expr_part ;
    expr_part ::= expr ;

    expr ::= ( expr )

    # data types
    | number
    | string
    | boolean
    | date

    # constants
    | true
    | false
    | pi
    | e
    | now()
    | today()

    # negating numeric value
    | -expr

    # comparisons
    | expr < expr
    | expr <= expr
    | expr > expr
    | expr >= expr
    | expr = expr
    | expr != expr (or: expr <> expr)

    # boolean operations
    | ! expr (or: not expr)
    | expr & expr (or: expr and expr)
    | expr | expr (or: expr or expr)
    | if[else] ( expr , expr (if true) , expr (if false) )
    | ifmissing ( variable , expr (default value if variable is missing) )
    | has ( variable )
    | isNaN ( expr )

    # arithmetics
    | expr + expr
    | expr - expr
    | expr * expr
    | expr / expr
    | expr ^ expr (power of)
    | expr % expr (modulo)
    ;

    # numeric functions
    | abs ( expr )
    | sqrt ( expr )
    | cbrt ( expr )
    | log ( expr )
    | log10 ( expr )
    | exp ( expr )
    | sin ( expr )
    | sinh ( expr )
    | cos ( expr )
    | cosh ( expr )
    | tan ( expr )
    | tanh ( expr )
    | atan ( expr )
    | atan2 ( exprY , exprX )
    | hypot ( exprX , exprY )
    | signum ( expr )
    | rint ( expr )
    | floor ( expr )
    | pow[er] ( expr , expr )
    | ceil ( expr )
    | min ( expr1 , expr2 )
    | max ( expr1 , expr2 )
    | rand () (unseeded double, 0-1)
    | rand ( seed ) (seeded double, 0-1)
    | randint ( bound ) (unseeded int from 0 to bound-1)
    | randint ( seed, bound ) (seeded int from 0 to bound-1)
    | year ( expr )
    | month ( expr )
    | day ( expr )
    | hour ( expr )
    | minute ( expr )
    | second ( expr )
    | weekday ( expr )
    | weeknum ( expr )

    # string functions
    | substr ( expr , start [, end] )
    | left ( expr , len )
    | mid ( expr , start , len )
    | right ( expr , len )
    | rept ( expr , count )
    | concatenate ( expr1 , expr2 [, expr3-5] )
    | lower[case] ( expr )
    | upper[case] ( expr )
    | trim ( expr )
    | matches ( expr , regexp )
    | trim ( expr )
    | len[gth] ( str )
    | find ( search , expr [, pos] ) (find 'search' in 'expr', return 1-based position)
    | contains ( str , find ) (checks whether 'str' string contains 'find' string)
    | startswith ( str , find ) (checks whether 'str' string starts with 'find' string)
    | endswith ( str , find ) (checks whether 'str' string ends with 'find' string)
    | replace ( str , pos , len , newstr )
    | replaceall ( str , regexp , replace ) (applies regular expression to 'str' and replaces all matches with 'replace')
    | substitute ( str , find , replace [, occurrences] )
    | str ( expr )
    | str ( expr , numdecimals )
    | str ( expr , decimalformat )
    | ext ( file_str ) (extracts extension from file)
    | replaceext ( file_str, ext_str ) (replaces the extension of the file with the new one)
    ;

    Notes:
    - Variables are either all alphanumeric and _, starting with uppercase letter (e.g., "ABc_12"),
    any character apart from "]" enclosed by "[" and "]" (e.g., "[Hello World]") or
    enclosed by single quotes (e.g., "'Hello World'").
    - 'start' and 'end' for function 'substr' are indices that start at 1.
    - Index 'end' for function 'substr' is excluded (like Java's 'String.substring(int,int)' method)
    - Line comments start with '#'.
    - Semi-colons (';') or commas (',') can be used as separator in the formulas,
    e.g., 'pow(2,2)' is equivalent to 'pow(2;2)'
    - dates have to be of format 'yyyy-MM-dd' or 'yyyy-MM-dd HH:mm:ss'
    - times have to be of format 'HH:mm:ss' or 'yyyy-MM-dd HH:mm:ss'
    - the characters in square brackets in function names are optional:
    e.g. 'len("abc")' is the same as 'length("abc")'
    - 'str' uses java.text.DecimalFormat when supplying a format string

    A lot of the functions have been modeled after LibreOffice:
    https://help.libreoffice.org/Calc/Functions_by_Category

    Additional functions:
    - env(String): String
       First argument is the name of the environment variable to retrieve.
       The result is the value of the environment variable.

    Additional procedures:
    - println(...)
       One or more arguments are printed as comma-separated list to stdout.
       If no argument is provided, a simple line feed is output.


    Variables are either all upper case letters (e.g., "ABC") or any character apart from "]" enclosed by "[" and "]" (e.g., "[Hello World]").

    Code example 1:
     String expr = "pow(BASE,EXPONENT)*MULT";
     HashMap symbols = new HashMap();
     symbols.put("BASE", 2.0);
     symbols.put("EXPONENT", 9.0);
     symbols.put("MULT", 0.1);
     double result = ReportMathExpression.evaluate(expr, symbols);
     System.out.println(expr + " and " + symbols + " = " + result);
     
    Code Example 2 (uses the "ifelse" construct):
     String expr = "ifelse(I<0,pow(BASE,I*0.5),pow(BASE,I))";
     ReportMathExpression.TreeNode tree = ReportMathExpression.parse(expr);
     HashMap symbols = new HashMap();
     symbols.put("BASE", 2.0);
     for (int i = -10; i <= 10; i++) {
       symbols.put("I", (double) i);
       double result = ReportMathExpression.evaluate(expr, symbols);
       System.out.println(expr + " and " + symbols + " = " + result);
     }
     
    -logging-level <OFF|SEVERE|WARNING|INFO|CONFIG|FINE|FINER|FINEST> (property: loggingLevel)
        The logging level for outputting errors and debugging output.
        default: WARNING
        min-user-mode: Expert
     
    -env <java.lang.String> (property: environment)
        The class to use for determining the environment.
        default: adams.env.Environment
     
    -expression <java.lang.String> (property: expression)
        The mathematical expression, including report fields, to evaluate (must 
        evaluate to a double).
        default: 42
     
    Author:
    FracPete (fracpete at waikato dot ac dot nz)
    See Also:
    Serialized Form
    • Field Detail

      • m_Report

        protected Report m_Report
        the report to use as basis.
    • Constructor Detail

      • ReportMathExpression

        public ReportMathExpression()
    • Method Detail

      • getGrammar

        public String getGrammar()
        Returns a string representation of the grammar.
        Specified by:
        getGrammar in interface GrammarSupplier
        Returns:
        the grammar, null if not available
      • setReport

        public void setReport​(Report value)
        Sets the report to use for evaluation.
        Parameters:
        value - the report
      • getReport

        public Report getReport()
        Returns the report to use for evaluation.
        Returns:
        the report
      • evaluate

        public static double evaluate​(String expr,
                                      Report report)
                               throws Exception
        Parses and evaluates the given expression. Returns the result of the mathematical expression, based on the given values of the symbols.
        Parameters:
        expr - the expression to evaluate
        report - the report
        Returns:
        the evaluated result
        Throws:
        Exception - if something goes wrong
      • main

        public static void main​(String[] args)
        Runs the evaluator from command-line.
        Parameters:
        args - the command-line options, use "-help" to list them