protected Expression atom() {
        if (tokenizer.current().isSymbol("-")) {
            tokenizer.consume();
            BinaryOperation result = new BinaryOperation(BinaryOperation.Op.SUBTRACT, new Constant(0d), atom());
            result.seal();
            return result;
        }
        if (tokenizer.current().isSymbol("+") && tokenizer.next().isSymbol("(")) {
            // Support for brackets with a leading + like "+(2.2)" in this case we simply ignore the
            // + sign
            tokenizer.consume();
        }
        if (tokenizer.current().isSymbol("(")) {
            tokenizer.consume();
            Expression result = expression();
            if (result instanceof BinaryOperation) {
                ((BinaryOperation) result).seal();
            }
            expect(Token.TokenType.SYMBOL, ")");
            return result;
        }
        if (tokenizer.current().isSymbol("|")) {
            tokenizer.consume();
            FunctionCall call = new FunctionCall();
            call.addParameter(expression());
            call.setFunction(Functions.ABS);
            expect(Token.TokenType.SYMBOL, "|");
            return call;
        }
        if (tokenizer.current().isIdentifier()) {
            if (tokenizer.next().isSymbol("(")) {
                return functionCall();
            }
            Token variableName = tokenizer.consume();
            try {
                return new VariableReference(scope.getVariable(variableName.getContents()));
            } catch (@SuppressWarnings("UnusedCatchParameter") IllegalArgumentException e) {
                errors.add(ParseError.error(variableName,
                                            String.format("Unknown variable: '%s'", variableName.getContents())));
                return new Constant(0);
            }
        }
        return literalAtom();
    }
protected Expression atom ( ) { if ( tokenizer . current ( ) . isSymbol ( "-" ) ) { tokenizer . consume ( ) ; BinaryOperation result = new BinaryOperation ( BinaryOperation . Op . SUBTRACT , new Constant ( 0d ) , atom ( ) ) ; result . seal ( ) ; return result ; } if ( tokenizer . current ( ) . isSymbol ( "+" ) && tokenizer . next ( ) . isSymbol ( "(" ) ) { tokenizer . consume ( ) ; } if ( tokenizer . current ( ) . isSymbol ( "(" ) ) { tokenizer . consume ( ) ; Expression result = expression ( ) ; if ( result instanceof BinaryOperation ) { ( ( BinaryOperation ) result ) . seal ( ) ; } expect ( Token . TokenType . SYMBOL , ")" ) ; return result ; } if ( tokenizer . current ( ) . isSymbol ( "|" ) ) { tokenizer . consume ( ) ; FunctionCall call = new FunctionCall ( ) ; call . addParameter ( expression ( ) ) ; call . setFunction ( Functions . ABS ) ; expect ( Token . TokenType . SYMBOL , "|" ) ; return call ; } if ( tokenizer . current ( ) . isIdentifier ( ) ) { if ( tokenizer . next ( ) . isSymbol ( "(" ) ) { return functionCall ( ) ; } Token variableName = tokenizer . consume ( ) ; try { return new VariableReference ( scope . getVariable ( variableName . getContents ( ) ) ) ; } catch ( @ SuppressWarnings ( "UnusedCatchParameter" ) IllegalArgumentException e ) { errors . add ( ParseError . error ( variableName , String . format ( "Unknown variable: '%s'" , variableName . getContents ( ) ) ) ) ; return new Constant ( 0 ) ; } } return literalAtom ( ) ; }
Parser rule for parsing an atom.
<p>
An atom is either a numeric constant, an <tt>expression</tt> in brackets, an <tt>expression</tt> surrounded by
| to signal the absolute function, an identifier to signal a variable reference or an identifier followed by a
bracket to signal a function call.

@return an atom parsed from the given input