xref: /template/strap/grammar/PageSql.g4 (revision 04fd306c7c155fa133ebb3669986875d65988276)
137748cd8SNickeau//https://github.com/antlr/grammars-v4/
237748cd8SNickeau
337748cd8SNickeaugrammar PageSql;
437748cd8SNickeau
537748cd8SNickeau
637748cd8SNickeau/**
737748cd8SNickeau Lexer (ie token)
837748cd8SNickeau https://github.com/antlr/antlr4/blob/master/doc/lexer-rules.md
937748cd8SNickeau*/
1037748cd8SNickeauSCOL:      ';';
1137748cd8SNickeauDOT:       '.';
1237748cd8SNickeauLPAREN:  '(';
1337748cd8SNickeauRPAREN: ')';
1437748cd8SNickeauLSQUARE:  '[';
1537748cd8SNickeauRSQUARE: ']';
1637748cd8SNickeauLCURLY: '{';
1737748cd8SNickeauRCURLY: '}';
1837748cd8SNickeauCOMMA:     ',';
1937748cd8SNickeauBITWISEXOR : '^';
2037748cd8SNickeauDOLLAR : '$';
2137748cd8SNickeauEQUAL:    '=';
2237748cd8SNickeauSTAR:      '*';
2337748cd8SNickeauPLUS:      '+';
2437748cd8SNickeauMINUS:     '-';
2537748cd8SNickeauTILDE:     '~';
2637748cd8SNickeauPIPE2:     '||';
2737748cd8SNickeauDIV:       '/';
2837748cd8SNickeauMOD:       '%';
2937748cd8SNickeauLT2:       '<<';
3037748cd8SNickeauGT2:       '>>';
3137748cd8SNickeauAMP:       '&';
3237748cd8SNickeauPIPE:      '|';
3337748cd8SNickeauQUESTION:  '?';
3437748cd8SNickeauLESS_THAN:        '<';
3537748cd8SNickeauLESS_THAN_OR_EQUAL:     '<=';
3637748cd8SNickeauGREATER_THAN:        '>';
3737748cd8SNickeauGREATER_THAN_OR_EQUAL:     '>=';
3837748cd8SNickeauEQ:        '==';
3937748cd8SNickeauNOT_EQUAL:   '!=';
4037748cd8SNickeauNOT_EQ2:   '<>';
4137748cd8SNickeau
4237748cd8SNickeau/**
4337748cd8SNickeau * Key word
4437748cd8SNickeau*/
4537748cd8SNickeauAND:               A N D;
4637748cd8SNickeauAS:                A S;
4737748cd8SNickeauASC:               A S C;
4837748cd8SNickeauBETWEEN:           B E T W E E N;
4937748cd8SNickeauBY:                B Y;
5037748cd8SNickeauDESC:              D E S C;
5137748cd8SNickeauESCAPE:            E S C A P E;
5237748cd8SNickeauFALSE:             F A L S E;
5337748cd8SNickeauFROM:              F R O M;
5437748cd8SNickeauGLOB:              G L O B;
5537748cd8SNickeauIN:                I N;
5637748cd8SNickeauIS:                I S;
5737748cd8SNickeauISNULL:            I S N U L L;
5837748cd8SNickeauLIKE:              L I K E;
5937748cd8SNickeauLIMIT:             L I M I T;
6037748cd8SNickeauNOT:               N O T;
6137748cd8SNickeauNOTNULL:           N O T N U L L;
6237748cd8SNickeauNOW:               N O W;
6337748cd8SNickeauNULL:              N U L L;
6437748cd8SNickeauOR:                O R;
6537748cd8SNickeauORDER:             O R D E R;
6637748cd8SNickeauSELECT:            S E L E C T;
6737748cd8SNickeauTRUE:              T R U E;
6837748cd8SNickeauWHERE:             W H E R E;
6937748cd8SNickeauRANDOM:            R A N D O M;
7037748cd8SNickeau
7137748cd8SNickeau// Function
7237748cd8SNickeauDATE:            D A T E;
7337748cd8SNickeauDATETIME:        D A T E T I M E;
7437748cd8SNickeaufunctionNames: DATE | DATETIME;
7537748cd8SNickeau
7637748cd8SNickeau// Tables
7737748cd8SNickeauPAGES:            P A G E S;
7837748cd8SNickeauBACKLINKS:        B A C K L I N K S;
79*04fd306cSNickeauDESCENDANTS:       D E S C E N D A N T S;
80*04fd306cSNickeautableNames: PAGES | BACKLINKS | DESCENDANTS;
8137748cd8SNickeau
8237748cd8SNickeau// LITERALS
8337748cd8SNickeaufragment Letter : 'a'..'z' | 'A'..'Z';
8437748cd8SNickeau
8537748cd8SNickeaufragment HexDigit : 'a'..'f' | 'A'..'F';
8637748cd8SNickeau
8737748cd8SNickeaufragment Digit : '0'..'9' ;
8837748cd8SNickeau
8937748cd8SNickeaufragment Exponent : ('e' | 'E') ( PLUS|MINUS )? (Digit)+;
9037748cd8SNickeau
9137748cd8SNickeaufragment RegexComponent :
9237748cd8SNickeau    'a'..'z' | 'A'..'Z' | '0'..'9' | '_'
9337748cd8SNickeau    | PLUS | STAR | QUESTION | MINUS | DOT
9437748cd8SNickeau    | LPAREN | RPAREN | LSQUARE | RSQUARE | LCURLY | RCURLY
9537748cd8SNickeau    | BITWISEXOR | PIPE | DOLLAR | '!'
9637748cd8SNickeau    ;
9737748cd8SNickeau
9837748cd8SNickeau// https://www.sqlite.org/lang_expr.html
9937748cd8SNickeau// A string constant is formed by enclosing the string in single quotes ('). A single quote within the string can be encoded by putting two single quotes in a row - as in Pascal. C-style escapes using the backslash character are not supported because they are not standard SQL.
10037748cd8SNickeauStringLiteral :
10137748cd8SNickeau    ( '\'' ( ~'\'' | '\'\'')* '\''
10237748cd8SNickeau    | '"' ( ~('"') )* '"'
10337748cd8SNickeau    )+
10437748cd8SNickeau    ;
10537748cd8SNickeau
10637748cd8SNickeauCharSetLiteral
10737748cd8SNickeau    : StringLiteral
10837748cd8SNickeau    | '0' 'X' (HexDigit|Digit)+
10937748cd8SNickeau    ;
11037748cd8SNickeau
11137748cd8SNickeauIntegralLiteral
11237748cd8SNickeau    : (Digit)+ ('L' | 'S' | 'Y')
11337748cd8SNickeau    ;
11437748cd8SNickeau
11537748cd8SNickeauNumber
11637748cd8SNickeau    : (Digit)+ ( DOT (Digit)* (Exponent)? | Exponent)?
11737748cd8SNickeau    ;
11837748cd8SNickeau
11937748cd8SNickeauNumberLiteral
12037748cd8SNickeau    : Number ('D' | 'B' 'D')
12137748cd8SNickeau    ;
12237748cd8SNickeau
12337748cd8SNickeauByteLengthLiteral
12437748cd8SNickeau    : (Digit)+ ('b' | 'B' | 'k' | 'K' | 'm' | 'M' | 'g' | 'G')
12537748cd8SNickeau    ;
12637748cd8SNickeau
12737748cd8SNickeau
12837748cd8SNickeau/**
12937748cd8SNickeau * Sql also does not permit
13037748cd8SNickeau * to start with a number
13137748cd8SNickeau * (just ot have no conflict with a NUMERIC_LITERAL)
13237748cd8SNickeau*/
13337748cd8SNickeauSqlName: (Letter | Digit) (Letter | Digit | '_')*;
13437748cd8SNickeau
13537748cd8SNickeau
13637748cd8SNickeau/**
13737748cd8SNickeau* Space are for human (discard)
13837748cd8SNickeau*/
13937748cd8SNickeauSPACES: [ \u000B\t\r\n] -> channel(HIDDEN);
14037748cd8SNickeau
14137748cd8SNickeau
14237748cd8SNickeau
14337748cd8SNickeau/**
14437748cd8SNickeau * Fragment rules does not result in tokens visible to the parser.
14537748cd8SNickeau * They aid in the recognition of tokens.
14637748cd8SNickeau*/
14737748cd8SNickeau
14837748cd8SNickeaufragment HEX_DIGIT: [0-9a-fA-F];
14937748cd8SNickeaufragment INTEGER_LITERAL: Digit+;
15037748cd8SNickeaufragment NUMERIC_LITERAL: Digit+ ('.' Digit*)?;
15137748cd8SNickeaufragment ALL_LITERAL_VALUE: StringLiteral | INTEGER_LITERAL | NUMERIC_LITERAL | NULL | TRUE
15237748cd8SNickeau   | FALSE
15337748cd8SNickeau   | NOW;
15437748cd8SNickeau
15537748cd8SNickeau
15637748cd8SNickeaufragment ANY_NAME: SqlName | StringLiteral | LPAREN ANY_NAME RPAREN;
15737748cd8SNickeaufragment A: [aA];
15837748cd8SNickeaufragment B: [bB];
15937748cd8SNickeaufragment C: [cC];
16037748cd8SNickeaufragment D: [dD];
16137748cd8SNickeaufragment E: [eE];
16237748cd8SNickeaufragment F: [fF];
16337748cd8SNickeaufragment G: [gG];
16437748cd8SNickeaufragment H: [hH];
16537748cd8SNickeaufragment I: [iI];
16637748cd8SNickeaufragment J: [jJ];
16737748cd8SNickeaufragment K: [kK];
16837748cd8SNickeaufragment L: [lL];
16937748cd8SNickeaufragment M: [mM];
17037748cd8SNickeaufragment N: [nN];
17137748cd8SNickeaufragment O: [oO];
17237748cd8SNickeaufragment P: [pP];
17337748cd8SNickeaufragment Q: [qQ];
17437748cd8SNickeaufragment R: [rR];
17537748cd8SNickeaufragment S: [sS];
17637748cd8SNickeaufragment T: [tT];
17737748cd8SNickeaufragment U: [uU];
17837748cd8SNickeaufragment V: [vV];
17937748cd8SNickeaufragment W: [wW];
18037748cd8SNickeaufragment X: [xX];
18137748cd8SNickeaufragment Y: [yY];
18237748cd8SNickeaufragment Z: [zZ];
18337748cd8SNickeau
18437748cd8SNickeau/**
18537748cd8SNickeau * Parser (ie structure)
18637748cd8SNickeau * https://github.com/antlr/antlr4/blob/master/doc/parser-rules.md
18737748cd8SNickeau*/
18837748cd8SNickeau
18937748cd8SNickeausqlNames : SqlName|Number;
19037748cd8SNickeau
19137748cd8SNickeaucolumn: sqlNames (DOT sqlNames)? (AS (sqlNames|StringLiteral))?;
19237748cd8SNickeau
19337748cd8SNickeaupattern: (StringLiteral|NumberLiteral);
19437748cd8SNickeau
19537748cd8SNickeau
19637748cd8SNickeauexpression:
19737748cd8SNickeau    (SqlName|StringLiteral|NumberLiteral|Number)
19837748cd8SNickeau    | functionNames LPAREN expression? ( COMMA expression)* RPAREN
19937748cd8SNickeau;
20037748cd8SNickeau
20137748cd8SNickeaupredicate: sqlNames
20237748cd8SNickeau    (
20337748cd8SNickeau        (( LESS_THAN | LESS_THAN_OR_EQUAL | GREATER_THAN | GREATER_THAN_OR_EQUAL | NOT_EQUAL | EQUAL) expression)
20437748cd8SNickeau        |
20537748cd8SNickeau        (
20637748cd8SNickeau            NOT?
20737748cd8SNickeau            (LIKE pattern (ESCAPE StringLiteral)?)
20837748cd8SNickeau            |
20937748cd8SNickeau            (GLOB pattern)
21037748cd8SNickeau        )
21137748cd8SNickeau        |
21237748cd8SNickeau        (NOT? BETWEEN expression AND expression)
21337748cd8SNickeau        |
21437748cd8SNickeau        (NOT? IN LPAREN (expression ( COMMA expression)*)? RPAREN)
21537748cd8SNickeau    );
21637748cd8SNickeau
21737748cd8SNickeaucolumns: column (COMMA column)*;
21837748cd8SNickeau
219*04fd306cSNickeaupredicateGroup: LPAREN predicate ((AND|OR) predicate)* RPAREN;
220*04fd306cSNickeau
221*04fd306cSNickeaupredicates: WHERE (predicate|predicateGroup) ((AND|OR) (predicate|predicateGroup))*;
22237748cd8SNickeau
22337748cd8SNickeautables: FROM tableNames;
22437748cd8SNickeau
22537748cd8SNickeau/**
22637748cd8SNickeau * The type of the literal value is
22737748cd8SNickeau * checked afterwards on tree traversing
22837748cd8SNickeau * otherwise there is conflict between token
22937748cd8SNickeau*/
23037748cd8SNickeaulimit: LIMIT Number;
23137748cd8SNickeau
232*04fd306cSNickeauorderBys: ORDER (RANDOM|BY orderByDef (COMMA orderByDef)*) ;
23337748cd8SNickeau
23437748cd8SNickeauorderByDef: SqlName (ASC | DESC)? ;
23537748cd8SNickeau
23637748cd8SNickeau/**
23737748cd8SNickeau* The main/root rule
23837748cd8SNickeau*/
23937748cd8SNickeaupageSql:
24037748cd8SNickeau        SELECT
24137748cd8SNickeau        RANDOM?
2421fa8c418SNickeau        (STAR|columns)?
24337748cd8SNickeau        tables?
24437748cd8SNickeau        predicates?
24537748cd8SNickeau        orderBys?
24637748cd8SNickeau        limit?
24737748cd8SNickeau;
248