1//https://github.com/antlr/grammars-v4/ 2 3grammar PageSql; 4 5 6/** 7 Lexer (ie token) 8 https://github.com/antlr/antlr4/blob/master/doc/lexer-rules.md 9*/ 10SCOL: ';'; 11DOT: '.'; 12LPAREN: '('; 13RPAREN: ')'; 14LSQUARE: '['; 15RSQUARE: ']'; 16LCURLY: '{'; 17RCURLY: '}'; 18COMMA: ','; 19BITWISEXOR : '^'; 20DOLLAR : '$'; 21EQUAL: '='; 22STAR: '*'; 23PLUS: '+'; 24MINUS: '-'; 25TILDE: '~'; 26PIPE2: '||'; 27DIV: '/'; 28MOD: '%'; 29LT2: '<<'; 30GT2: '>>'; 31AMP: '&'; 32PIPE: '|'; 33QUESTION: '?'; 34LESS_THAN: '<'; 35LESS_THAN_OR_EQUAL: '<='; 36GREATER_THAN: '>'; 37GREATER_THAN_OR_EQUAL: '>='; 38EQ: '=='; 39NOT_EQUAL: '!='; 40NOT_EQ2: '<>'; 41 42/** 43 * Key word 44*/ 45AND: A N D; 46AS: A S; 47ASC: A S C; 48BETWEEN: B E T W E E N; 49BY: B Y; 50DESC: D E S C; 51ESCAPE: E S C A P E; 52FALSE: F A L S E; 53FROM: F R O M; 54GLOB: G L O B; 55IN: I N; 56IS: I S; 57ISNULL: I S N U L L; 58LIKE: L I K E; 59LIMIT: L I M I T; 60NOT: N O T; 61NOTNULL: N O T N U L L; 62NOW: N O W; 63NULL: N U L L; 64OR: O R; 65ORDER: O R D E R; 66SELECT: S E L E C T; 67TRUE: T R U E; 68WHERE: W H E R E; 69RANDOM: R A N D O M; 70 71// Function 72DATE: D A T E; 73DATETIME: D A T E T I M E; 74functionNames: DATE | DATETIME; 75 76// constant 77constantNames: NOW; 78 79// Tables 80PAGES: P A G E S; 81BACKLINKS: B A C K L I N K S; 82DESCENDANTS: D E S C E N D A N T S; 83tableNames: PAGES | BACKLINKS | DESCENDANTS; 84 85// LITERALS 86fragment Letter : 'a'..'z' | 'A'..'Z'; 87 88fragment HexDigit : 'a'..'f' | 'A'..'F'; 89 90fragment Digit : '0'..'9' ; 91 92fragment Exponent : ('e' | 'E') ( PLUS|MINUS )? (Digit)+; 93 94fragment RegexComponent : 95 'a'..'z' | 'A'..'Z' | '0'..'9' | '_' 96 | PLUS | STAR | QUESTION | MINUS | DOT 97 | LPAREN | RPAREN | LSQUARE | RSQUARE | LCURLY | RCURLY 98 | BITWISEXOR | PIPE | DOLLAR | '!' 99 ; 100 101// https://www.sqlite.org/lang_expr.html 102// 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. 103StringLiteral : 104 ( '\'' ( ~'\'' | '\'\'')* '\'' 105 | '"' ( ~('"') )* '"' 106 )+ 107 ; 108 109CharSetLiteral 110 : StringLiteral 111 | '0' 'X' (HexDigit|Digit)+ 112 ; 113 114IntegralLiteral 115 : (Digit)+ ('L' | 'S' | 'Y') 116 ; 117 118Number 119 : (Digit)+ ( DOT (Digit)* (Exponent)? | Exponent)? 120 ; 121 122NumberLiteral 123 : Number ('D' | 'B' 'D') 124 ; 125 126ByteLengthLiteral 127 : (Digit)+ ('b' | 'B' | 'k' | 'K' | 'm' | 'M' | 'g' | 'G') 128 ; 129 130 131/** 132 * Sql also does not permit 133 * to start with a number 134 * (just ot have no conflict with a NUMERIC_LITERAL) 135*/ 136SqlName: (Letter | Digit) (Letter | Digit | '_')*; 137 138 139/** 140* Space are for human (discard) 141*/ 142SPACES: [ \u000B\t\r\n] -> channel(HIDDEN); 143 144 145 146/** 147 * Fragment rules does not result in tokens visible to the parser. 148 * They aid in the recognition of tokens. 149*/ 150 151fragment HEX_DIGIT: [0-9a-fA-F]; 152fragment INTEGER_LITERAL: Digit+; 153fragment NUMERIC_LITERAL: Digit+ ('.' Digit*)?; 154fragment ALL_LITERAL_VALUE: StringLiteral | INTEGER_LITERAL | NUMERIC_LITERAL | NULL | TRUE 155 | FALSE 156 | NOW; 157 158 159fragment ANY_NAME: SqlName | StringLiteral | LPAREN ANY_NAME RPAREN; 160fragment A: [aA]; 161fragment B: [bB]; 162fragment C: [cC]; 163fragment D: [dD]; 164fragment E: [eE]; 165fragment F: [fF]; 166fragment G: [gG]; 167fragment H: [hH]; 168fragment I: [iI]; 169fragment J: [jJ]; 170fragment K: [kK]; 171fragment L: [lL]; 172fragment M: [mM]; 173fragment N: [nN]; 174fragment O: [oO]; 175fragment P: [pP]; 176fragment Q: [qQ]; 177fragment R: [rR]; 178fragment S: [sS]; 179fragment T: [tT]; 180fragment U: [uU]; 181fragment V: [vV]; 182fragment W: [wW]; 183fragment X: [xX]; 184fragment Y: [yY]; 185fragment Z: [zZ]; 186 187/** 188 * Parser (ie structure) 189 * https://github.com/antlr/antlr4/blob/master/doc/parser-rules.md 190*/ 191 192sqlNames : SqlName|Number; 193 194column: sqlNames (DOT sqlNames)? (AS (sqlNames|StringLiteral))?; 195 196pattern: (StringLiteral|NumberLiteral); 197 198 199expression: 200 (SqlName|StringLiteral|NumberLiteral|Number|constantNames) 201 | functionNames LPAREN expression? ( COMMA expression)* RPAREN 202; 203 204predicate: sqlNames 205 ( 206 (( LESS_THAN | LESS_THAN_OR_EQUAL | GREATER_THAN | GREATER_THAN_OR_EQUAL | NOT_EQUAL | EQUAL) expression) 207 | 208 ( 209 NOT? 210 (LIKE pattern (ESCAPE StringLiteral)?) 211 | 212 (GLOB pattern) 213 ) 214 | 215 (NOT? BETWEEN expression AND expression) 216 | 217 (NOT? IN LPAREN (expression ( COMMA expression)*)? RPAREN) 218 ); 219 220columns: column (COMMA column)*; 221 222predicateGroup: LPAREN predicate ((AND|OR) predicate)* RPAREN; 223 224predicates: WHERE (predicate|predicateGroup) ((AND|OR) (predicate|predicateGroup))*; 225 226tables: FROM tableNames; 227 228/** 229 * The type of the literal value is 230 * checked afterwards on tree traversing 231 * otherwise there is conflict between token 232*/ 233limit: LIMIT Number; 234 235orderBys: ORDER (RANDOM|BY orderByDef (COMMA orderByDef)*) ; 236 237orderByDef: SqlName (ASC | DESC)? ; 238 239/** 240* The main/root rule 241*/ 242pageSql: 243 SELECT 244 RANDOM? 245 (STAR|columns)? 246 tables? 247 predicates? 248 orderBys? 249 limit? 250; 251