_decimal:
    DECIMAL
    {
        $$ = d_matched;
    }
;

_interval:
    _decimal
    {
        $$ = Interval::exact($1);
    }
|
    _decimal ',' _decimal
    {
        $$ = Interval::range($1, $3);
    }
|
    _decimal ','
    {
        $$ = Interval::lowerBound($1);
    }
;

_single_char:
    CHAR
|
    combi_chars
;

_open_paren:
    '('
    {
        ++d_parentheses;
    }
;

_close_paren:
    ')'
    {
        --d_parentheses;
    }
;

_open_curly:
    '{'
    {
        d_scanner.acceptMulti();
    }
;

_unit:
    '^'
    {
        $$ = boln();
    }
|
    '$'
    {
        $$ = dollar();
    }
|
    DOLLAR
    {
        $$ = eolnDollar();
    }
|
    STRING
    {
        $$ = str();
    }
|
    RAWSTRING
    {
        $$ = rawText(d_scanner.rawStringContent());
    }
|
    QUOTES
    {                                                   
        $$ = quotes();
    }
|
    ESCAPE_SEQUENCE
    {
        $$ = escape();
    }
|
    '.'
    {
        $$ = Pattern::dot(d_states);
    }
|
    _single_char
    {
        $$ = rawText();
    }
|
    characterclass
    {
        $$ = Pattern::characterClass(d_states, $1);
    }
;

_quantifier:
    '*'
|
    '+'
|
    '?'
;

_regex_unit:
    _unit
    {
        Options::regexCall("unit");
        $$ = $1;    //FBB
    }
|
    _regex_unit _open_curly _interval '}'
    {
        $$ = interval($1, $3);
    }
|
    _regex_unit _quantifier
    {
        $$ = Pattern::quantifier(d_states, $1, d_matched[0]);
    }
|
    _open_paren _regex _close_paren
    {
        $$ = $2;
    }
|
    _regex_unit _regex_unit                     %prec CHAR
    {
        $$ = Pattern::concatenate(d_states, $1, $2);
    }
;

    // a regex is a regex, possibly with LA operator
    // the handler must verify whether the regex contains ^ and $ symbols
    // within the regex, for which a warning must be issue: ^, $ treated as
    // normal characters
    // regex returns a Pattern, embedded in a spSemUnion
_regex:
    _regex_unit
    {
        Options::regexCall("regex-unit");
        $$ = $1;
    }
|
    _regex '|' _regex
    { 
        $$ = Pattern::alternatives(d_states, $1, $3);
    }
|
    _regex '/' _regex
    {
        $$ = lookahead($1, $3);
    }
;

regexOrEOF:
    _regex
    {
        $$ = $1;
    }
|
    EOF_PATTERN
    {
        $$ = Pattern::eof(d_states);
    }
;
