_p_casttype:
    INT
|
    LIST
|
    STRINGTYPE
;

_string:
    _string
    STRING
    {                                       /* catenate the new string */
        gp_stringbuf = rss_strcat(gp_stringbuf, util_string());
    }
|
    STRING
    {
        free(gp_stringbuf);                  /* free former string */
        gp_stringbuf = rss_strdup(util_string()); /* duplicate initial string */
    }
;

_func_or_var:
    function
    closepar
|
    IDENTIFIER
    {
        $$ = *p_fetchVar();
    }
;

_backtick:   
    {
        gp_parse_error = err_backtick_expected;
    }
    '`' 
;

expression:
        expression
        '='
        expression
        {
            $$ = *p_assign(&$1, &$3);
        }
    |
        expression
        '['
        expression
        ']'
        {
            $$ = *p_indexOp(&$1, &$3);
        }
    |
        expression
        MUL_IS
        expression
        {
            $$ = *p_compoundAss(&$1, &$3, p_multiply, "*=");
        }
    |
        expression
        DIV_IS
        expression
        {
            $$ = *p_compoundAss(&$1, &$3, p_divide, "/=");
        }
    |
        expression
        MOD_IS
        expression
        {
            $$ = *p_compoundAss(&$1, &$3, p_modulo, "%=");
        }
    |
        expression
        PLUS_IS
        expression
        {
            $$ = *p_compoundAss(&$1, &$3, p_addition, "+=");
        }
    |
        expression
        MINUS_IS
        expression
        {
            $$ = *p_compoundAss(&$1, &$3, p_subtract, "-=");
        }
    |
        expression
        AND_IS
        expression
        {
            $$ = *p_compoundAss(&$1, &$3, p_and, "&=");
        }
    |
        expression
        OR_IS
        expression
        {
            $$ = *p_compoundAss(&$1, &$3, p_or, "|=");
        }
    |
        expression
        XOR_IS
        expression
        {
            $$ = *p_compoundAss(&$1, &$3, p_xor, "^=");
        }
    |
        expression
        SHL_IS
        expression
        {
            $$ = *p_compoundAss(&$1, &$3, p_shl, "<<=");
        }
    |
        expression
        SHR_IS
        expression
        {
            $$ = *p_compoundAss(&$1, &$3, p_shr, ">>=");
        }
    |
        expression
        OR
        expression
        {
            $$ = *p_orBool(&$1, &$3);
        }
    |
        expression
        AND
        expression
        {
            $$ = *p_andBoolean(&$1, &$3);
        }
    |
        expression
        EQUAL
        expression
        {
            $$ = *p_equal(&$1, &$3);
        }
    |
        expression
        NOT_EQUAL
        expression
        {
            $$ = *p_unequal(&$1, &$3);
        }
    |
        expression
        '?'
        expression
        ':'
        expression
        {
            $$ = *p_ternary(&$1, &$3, &$5);
        }
    |
        expression
        '<'
        expression
        {
            $$ = *p_smaller(&$1, &$3);
        }
    |
        expression
        '>'
        expression
        {
            $$ = *p_greater(&$1, &$3);
        }
    |
        expression
        SMALLER_EQUAL
        expression
        {
            $$ = *p_smEqual(&$1, &$3);
        }
    |
        expression
        GREATER_EQUAL
        expression
        {
            $$ = *p_grEqual(&$1, &$3);
        }
    |
        expression
        '+'
        expression
        {
            $$ = *p_addition(&$1, &$3);
        }
    |
        expression
        '&'
        expression
        {
            $$ = *p_and(&$1, &$3);
        }
    |
        expression
        '|'
        expression
        {
            $$ = *p_or(&$1, &$3);
        }
    |
        expression
        '^'
        expression
        {
            $$ = *p_xor(&$1, &$3);
        }
    |
        expression
        SHL
        expression
        {
            $$ = *p_shl(&$1, &$3);
        }
    |
        expression
        SHR
        expression
        {
            $$ = *p_shr(&$1, &$3);
        }
    |
        expression
        '-'
        expression
        {
            $$ = *p_subtract(&$1, &$3);
        }
    |
        expression
        '*'
        expression
        {
            $$ = *p_multiply(&$1, &$3);
        }
    |
        expression
        YOUNGER
        expression
        {
            $$ = *p_young(&$1, &$3);
        }
    |
        expression
        OLDER
        expression
        {
            $$ = *p_old(&$1, &$3);
        }
    |
        expression
        '/'
        expression
        {
            $$ = *p_divide(&$1, &$3);
        }
    |
        expression
        '%'
        expression
        {
            $$ = *p_modulo(&$1, &$3);
        }
    |
        '-'
        expression          %prec '!'
        {
            $$ = *p_negate(&$2);
        }
    |
        INC
        expression
        {
            $$ = *p_incDec(pre_op, op_inc, &$2);
        }
    |
        expression
        INC
        {
            $$ = *p_incDec(post_op, op_inc, &$1);
        }
    |
        DEC
        expression
        {
            $$ = *p_incDec(pre_op, op_dec, &$2);
        }
    |
        expression
        DEC
        {
            $$ = *p_incDec(post_op, op_dec, &$1);
        }
    |
        '+'
        expression          %prec '!'
        {
            $$ = $2;
        }
    |
        '~'
        expression          %prec '!'
        {
            $$ = *p_not(&$2);
        }
    |
        '!'
        expression
        {
            $$ = *p_notBoolean(&$2);
        }
    |
        '('
        _p_casttype
        ')'
        expression         %prec '!'
        {
            $$ = *p_cast($2.type, &$4);
        }
    |
        _string
        {
            $$ = *p_stackFrame(e_str | e_const);
        }
    |
        NUMBER
        {
            $$ = *p_stackFrame(e_int | e_const);
        }
    |
        '('
        expression
        closepar
        {
            $$ = $2;
        }
    |
        _func_or_var
    |
        '`'
        expression
        _backtick
        {
            $$ = *p_oneArg(f_backtick, &$2);
        }
    ;
