grammar Calculator;

expression
    : functionCall                                  #expr_call
    | operatorPrefix great=expression               #expr_pref
    | expression operatorSuffix                     #expr_suff
    | SYMBOL_LB expression SYMBOL_RB                #expr_bracket
    | a=expression operator1 b=expression           #expr_1
    | first=expression operator2 second=expression  #expr_2
    | second=expression operator3 first=expression  #expr_3
    | number                                        #expr_number
    ;

functionCall
    : NAME SYMBOL_LB args=functionArguments SYMBOL_RB
    ;

functionArguments
    : functionArgument (SYMBOL_COM functionArgument)*
    ;

functionArgument
    : expression
    ;

operatorPrefix
    : operatorNegate
    ;

operatorSuffix
    : operatorFactorial
    ;

operator1
    : operatorPow
    | operatorOr
    | operatorAnd
    ;

operator2
    : operatorMul #opmul
    | operatorDiv #opdiv
    ;

operator3
    : operatorAdd
    | operatorSub
    ;

operatorNegate : SYMBOL_SUB;
operatorFactorial : SYMBOL_FACT;
operatorPow : SYMBOL_POW;
operatorOr : SYMBOL_OR;
operatorAnd : SYMBOL_AND;
operatorMul : SYMBOL_MUL;
operatorDiv : SYMBOL_DIV;
operatorAdd : SYMBOL_ADD;
operatorSub : SYMBOL_SUB;

number
    : numberInt
    | numberReal
    ;

numberInt: NUMBER_INT;

numberReal: NUMBER_REAL;

NUMBER_REAL : [0-9]* '.' [0-9]*;

NUMBER_INT : [0-9]+ ;

NAME : [a-z]+ ;

SYMBOL_LB : '(' ;
SYMBOL_RB : ')' ;
SYMBOL_COM : ',' ;
SYMBOL_LT : '<' ;
SYMBOL_GT : '>' ;

SYMBOL_FACT: '!' ;
SYMBOL_POW : '^' ;
SYMBOL_OR : '|' ;
SYMBOL_AND : '&' ;
SYMBOL_MUL : '*' ;
SYMBOL_DIV : '/' ;
SYMBOL_ADD : '+' ;
SYMBOL_SUB : '-' ;

SYMBOL_ASK : '?' ;

WS :  [ \t\r\n]+ -> skip ;