@SuppressWarnings({"HardCodedStringLiteral"})
  private static Expression parseMacro(Lexer lexer, String expression) {
    IElementType tokenType = lexer.getTokenType();
    String token = getString(lexer, expression);
    if (tokenType == MacroTokenType.STRING_LITERAL) {
      advance(lexer);
      return new ConstantNode(parseStringLiteral(token));
    }

    if (tokenType != MacroTokenType.IDENTIFIER) {
      LOG.info("Bad macro syntax: Not identifier: " + token);
      advance(lexer);
      return new ConstantNode("");
    }

    List<Macro> macros = MacroFactory.getMacros(token);
    if (macros.isEmpty()) {
      return parseVariable(lexer, expression);
    }

    advance(lexer);
    MacroCallNode macroCallNode = new MacroCallNode(macros.get(0));
    if (lexer.getTokenType() == null) {
      return macroCallNode;
    }

    if (lexer.getTokenType() != MacroTokenType.LPAREN) {
      return macroCallNode;
    }

    advance(lexer);
    parseParameters(macroCallNode, lexer, expression);
    if (lexer.getTokenType() != MacroTokenType.RPAREN) {
      LOG.info("Bad macro syntax: ) expected: " + expression);
    }
    advance(lexer);
    return macroCallNode;
  }
@SuppressWarnings({"HardCodedStringLiteral"})
  private static Expression parseMacro(Lexer lexer, String expression)