private FormulaNode primary() { switch (lexer.peek().getType()) { case SYMBOL: if(lexer.peek().getString().matches("t\\d{10}")) { return enumLiteral(); } else { return symbolOrCall(); } case NUMBER: return number(); case BOOLEAN_LITERAL: return booleanLiteral(); case STRING_LITERAL: return stringLiteral(); case PAREN_START: Token openToken = lexer.next(); FormulaNode e = expression(); Token closeToken = expect(TokenType.PAREN_END); return new GroupNode(e, new SourceRange(openToken, closeToken)); default: throw new FormulaSyntaxException(new SourceRange(lexer.peek()), "Expected a symbol, a number, a string, or '('"); } }