sq/grammar/SLQ.g4
2016-10-30 16:35:56 -06:00

87 lines
1.9 KiB
ANTLR
Executable File

grammar SLQ;
// "@mysql_db1 | .user, .address | join(.user.uid == .address.uid) | .[0:3] | .uid, .username, .country"
query: segment (PIPE segment)* ;
segment: (element) (COMMA element)* ;
element: dsTblElement | dsElement | selElement | join | rowRange;
cmpr: LT_EQ | LT | GT_EQ | GT | EQ | NEQ ;
//fn: fnJoin ;
args: ( arg (COMMA arg)* )? ;
arg: SEL | ID ;
join
: ('join'|'JOIN'|'j')
LPAR joinConstraint RPAR
;
//fnJoinCond: SEL cmpr SEL ;
//fnJoinExpr: fnJoinCond | SEL;
joinConstraint
: SEL cmpr SEL // .user.uid == .address.userid
| SEL // .uid
;
selElement: SEL;
dsTblElement: DATASOURCE SEL; // datasource table element, e.g. @my1.user
dsElement: DATASOURCE; // datasource element, e.g. @my1
// []
// [1] select row[1]
// [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: '.[' (( INT COLON INT) | (INT COLON) | (COLON INT) | INT | ) ']'; // [1] [10:15] [0:15] [:15] [10:]
ID: [a-zA-Z_][a-zA-Z0-9_]* ;
WS : [ \t\r\n]+ -> skip ;
LPAR : '(' ;
RPAR: ')';
LBRA: '[' ;
RBRA: ']';
COMMA: ',';
PIPE: '|' ;
COLON: ':';
NULL: 'null' | 'NULL';
STRING : '"' (ESC | ~["\\])* '"' ;
fragment ESC : '\\' (["\\/bfnrt] | UNICODE) ;
fragment UNICODE : 'u' HEX HEX HEX HEX ;
fragment HEX : [0-9a-fA-F] ;
INT: [0-9] [0-9]*;
NUMBER
: '-'? 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 is Datasource
DOT: '.' ;
VAL: STRING | NUMBER | NULL | SEL;
LINECOMMENT: '//' .*? '\n' -> skip ;