mirror of
https://github.com/neilotoole/sq.git
synced 2024-12-18 05:31:38 +03:00
184 lines
3.1 KiB
ANTLR
184 lines
3.1 KiB
ANTLR
grammar SLQ;
|
|
|
|
// "@mysql_db1 | .user, .address | join(.user.uid == .address.uid) | .[0:3] | .uid, .username, .country"
|
|
|
|
stmtList
|
|
: ';'* query ( ';'+ query )* ';'*
|
|
;
|
|
|
|
query: segment ('|' segment)* ;
|
|
|
|
segment: (element) (',' element)* ;
|
|
|
|
element: dsTblElement | dsElement | selElement | join | group | rowRange | fn | expr;
|
|
|
|
cmpr: LT_EQ | LT | GT_EQ | GT | EQ | NEQ ;
|
|
|
|
|
|
//whereExpr
|
|
// : expr
|
|
// ;
|
|
|
|
fn: fnName '(' ( expr ( ',' expr )* | '*' )? ')';
|
|
|
|
|
|
|
|
join
|
|
: ('join'|'JOIN'|'j')
|
|
'(' joinConstraint ')'
|
|
;
|
|
|
|
|
|
joinConstraint
|
|
: SEL cmpr SEL // .user.uid == .address.userid
|
|
| SEL // .uid
|
|
;
|
|
|
|
|
|
group
|
|
: ('group'|'GROUP'|'g')
|
|
'(' SEL (',' SEL)* ')'
|
|
;
|
|
|
|
|
|
selElement: SEL;
|
|
|
|
dsTblElement: DATASOURCE SEL; // data source table element, e.g. @my1.user
|
|
|
|
dsElement: DATASOURCE; // data source element, e.g. @my1
|
|
|
|
|
|
// [] select all rows
|
|
// [10] select row 10
|
|
// [10:15] select rows 10 thru 15
|
|
// [0:15] select rows 0 thru 15
|
|
// [:15] same as above (0 thru 15)
|
|
// [10:] select all rows from 10 onwards
|
|
rowRange
|
|
: '.['
|
|
( NN COLON NN // [10:15]
|
|
| NN COLON // [10:]
|
|
| COLON NN // [:15]
|
|
| NN // [10]
|
|
)? ']'
|
|
;
|
|
|
|
|
|
fnName
|
|
: 'sum' | 'SUM'
|
|
| 'avg' | 'AVG'
|
|
| 'count' | 'COUNT'
|
|
| 'where' | 'WHERE'
|
|
;
|
|
|
|
|
|
expr
|
|
: SEL
|
|
| literal
|
|
| unaryOperator expr
|
|
| expr '||' expr
|
|
| expr ( '*' | '/' | '%' ) expr
|
|
| expr ( '+' | '-' ) expr
|
|
| expr ( '<<' | '>>' | '&' ) expr
|
|
| expr ( '<' | '<=' | '>' | '>=' ) expr
|
|
| expr ( '==' | '!=' | ) expr
|
|
| expr '&&' expr
|
|
| fn
|
|
// | fnName '(' ( expr ( ',' expr )* | '*' )? ')'
|
|
;
|
|
|
|
|
|
|
|
literal
|
|
: NN
|
|
| NUMBER
|
|
| STRING
|
|
| NULL
|
|
;
|
|
|
|
|
|
unaryOperator
|
|
: '-'
|
|
| '+'
|
|
| '~'
|
|
| '!'
|
|
;
|
|
|
|
|
|
ID: [a-zA-Z_][a-zA-Z0-9_]* ;
|
|
WS : [ \t\r\n]+ -> skip ;
|
|
LPAR : '(' ;
|
|
RPAR: ')';
|
|
LBRA: '[' ;
|
|
RBRA: ']';
|
|
COMMA: ',';
|
|
PIPE: '|' ;
|
|
COLON: ':';
|
|
NULL: 'null' | 'NULL';
|
|
|
|
|
|
NN: INTF; // NN: Natural Number {0,1,2,3, ...}
|
|
|
|
NUMBER
|
|
: NN
|
|
| '-'? INTF '.' [0-9]+ EXP? // 1.35, 1.35E-9, 0.3, -4.5
|
|
| '-'? INTF EXP // 1e10 -3e4
|
|
| '-'? INTF // -3, 45
|
|
;
|
|
fragment INTF : '0' | [1-9] [0-9]* ; // no leading zeros
|
|
fragment EXP : [Ee] [+\-]? INTF ; // \- since - means "range" inside [...]
|
|
|
|
|
|
LT_EQ : '<=';
|
|
LT : '<';
|
|
GT_EQ : '>=';
|
|
GT : '>';
|
|
NEQ : '!=';
|
|
EQ : '==';
|
|
|
|
SEL: '.' ID ('.' ID)*; // SEL can be .THING or .THING.OTHERTHING etc.
|
|
DATASOURCE: '@' ID; // DS (Data Source): @mydb1 or @postgres_db2 etc.
|
|
|
|
|
|
STRING : '"' (ESC | ~["\\])* '"' ;
|
|
fragment ESC : '\\' (["\\/bfnrt] | UNICODE) ;
|
|
fragment UNICODE : 'u' HEX HEX HEX HEX ;
|
|
fragment HEX : [0-9a-fA-F] ;
|
|
|
|
//NUMERIC_LITERAL
|
|
// : DIGIT+ ( '.' DIGIT* )? ( E [-+]? DIGIT+ )?
|
|
// | '.' DIGIT+ ( E [-+]? DIGIT+ )?
|
|
// ;
|
|
|
|
|
|
|
|
fragment DIGIT : [0-9];
|
|
|
|
fragment A : [aA];
|
|
fragment B : [bB];
|
|
fragment C : [cC];
|
|
fragment D : [dD];
|
|
fragment E : [eE];
|
|
fragment F : [fF];
|
|
fragment G : [gG];
|
|
fragment H : [hH];
|
|
fragment I : [iI];
|
|
fragment J : [jJ];
|
|
fragment K : [kK];
|
|
fragment L : [lL];
|
|
fragment M : [mM];
|
|
fragment N : [nN];
|
|
fragment O : [oO];
|
|
fragment P : [pP];
|
|
fragment Q : [qQ];
|
|
fragment R : [rR];
|
|
fragment S : [sS];
|
|
fragment T : [tT];
|
|
fragment U : [uU];
|
|
fragment V : [vV];
|
|
fragment W : [wW];
|
|
fragment X : [xX];
|
|
fragment Y : [yY];
|
|
fragment Z : [zZ];
|
|
|
|
LINECOMMENT: '//' .*? '\n' -> skip ; |