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// Tables 77PAGES: P A G E S; 78BACKLINKS: B A C K L I N K S; 79tableNames: PAGES | BACKLINKS; 80 81// LITERALS 82fragment Letter : 'a'..'z' | 'A'..'Z'; 83 84fragment HexDigit : 'a'..'f' | 'A'..'F'; 85 86fragment Digit : '0'..'9' ; 87 88fragment Exponent : ('e' | 'E') ( PLUS|MINUS )? (Digit)+; 89 90fragment RegexComponent : 91 'a'..'z' | 'A'..'Z' | '0'..'9' | '_' 92 | PLUS | STAR | QUESTION | MINUS | DOT 93 | LPAREN | RPAREN | LSQUARE | RSQUARE | LCURLY | RCURLY 94 | BITWISEXOR | PIPE | DOLLAR | '!' 95 ; 96 97// https://www.sqlite.org/lang_expr.html 98// 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. 99StringLiteral : 100 ( '\'' ( ~'\'' | '\'\'')* '\'' 101 | '"' ( ~('"') )* '"' 102 )+ 103 ; 104 105CharSetLiteral 106 : StringLiteral 107 | '0' 'X' (HexDigit|Digit)+ 108 ; 109 110IntegralLiteral 111 : (Digit)+ ('L' | 'S' | 'Y') 112 ; 113 114Number 115 : (Digit)+ ( DOT (Digit)* (Exponent)? | Exponent)? 116 ; 117 118NumberLiteral 119 : Number ('D' | 'B' 'D') 120 ; 121 122ByteLengthLiteral 123 : (Digit)+ ('b' | 'B' | 'k' | 'K' | 'm' | 'M' | 'g' | 'G') 124 ; 125 126 127/** 128 * Sql also does not permit 129 * to start with a number 130 * (just ot have no conflict with a NUMERIC_LITERAL) 131*/ 132SqlName: (Letter | Digit) (Letter | Digit | '_')*; 133 134 135/** 136* Space are for human (discard) 137*/ 138SPACES: [ \u000B\t\r\n] -> channel(HIDDEN); 139 140 141 142/** 143 * Fragment rules does not result in tokens visible to the parser. 144 * They aid in the recognition of tokens. 145*/ 146 147fragment HEX_DIGIT: [0-9a-fA-F]; 148fragment INTEGER_LITERAL: Digit+; 149fragment NUMERIC_LITERAL: Digit+ ('.' Digit*)?; 150fragment ALL_LITERAL_VALUE: StringLiteral | INTEGER_LITERAL | NUMERIC_LITERAL | NULL | TRUE 151 | FALSE 152 | NOW; 153 154 155fragment ANY_NAME: SqlName | StringLiteral | LPAREN ANY_NAME RPAREN; 156fragment A: [aA]; 157fragment B: [bB]; 158fragment C: [cC]; 159fragment D: [dD]; 160fragment E: [eE]; 161fragment F: [fF]; 162fragment G: [gG]; 163fragment H: [hH]; 164fragment I: [iI]; 165fragment J: [jJ]; 166fragment K: [kK]; 167fragment L: [lL]; 168fragment M: [mM]; 169fragment N: [nN]; 170fragment O: [oO]; 171fragment P: [pP]; 172fragment Q: [qQ]; 173fragment R: [rR]; 174fragment S: [sS]; 175fragment T: [tT]; 176fragment U: [uU]; 177fragment V: [vV]; 178fragment W: [wW]; 179fragment X: [xX]; 180fragment Y: [yY]; 181fragment Z: [zZ]; 182 183/** 184 * Parser (ie structure) 185 * https://github.com/antlr/antlr4/blob/master/doc/parser-rules.md 186*/ 187 188sqlNames : SqlName|Number; 189 190column: sqlNames (DOT sqlNames)? (AS (sqlNames|StringLiteral))?; 191 192pattern: (StringLiteral|NumberLiteral); 193 194 195expression: 196 (SqlName|StringLiteral|NumberLiteral|Number) 197 | functionNames LPAREN expression? ( COMMA expression)* RPAREN 198; 199 200predicate: sqlNames 201 ( 202 (( LESS_THAN | LESS_THAN_OR_EQUAL | GREATER_THAN | GREATER_THAN_OR_EQUAL | NOT_EQUAL | EQUAL) expression) 203 | 204 ( 205 NOT? 206 (LIKE pattern (ESCAPE StringLiteral)?) 207 | 208 (GLOB pattern) 209 ) 210 | 211 (NOT? BETWEEN expression AND expression) 212 | 213 (NOT? IN LPAREN (expression ( COMMA expression)*)? RPAREN) 214 ); 215 216columns: column (COMMA column)*; 217 218predicates: WHERE predicate ((AND|OR) predicate)*; 219 220tables: FROM tableNames; 221 222/** 223 * The type of the literal value is 224 * checked afterwards on tree traversing 225 * otherwise there is conflict between token 226*/ 227limit: LIMIT Number; 228 229orderBys: ORDER BY orderByDef (COMMA orderByDef)* ; 230 231orderByDef: SqlName (ASC | DESC)? ; 232 233/** 234* The main/root rule 235*/ 236pageSql: 237 SELECT 238 RANDOM? 239 (STAR|columns)? 240 tables? 241 predicates? 242 orderBys? 243 limit? 244; 245