Created
September 29, 2020 14:27
-
-
Save abyss7/5d51f7d40c8177bc3905451c2a65298c to your computer and use it in GitHub Desktop.
Buggy grammar
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
grammar test; | |
queryStmt: query (SEMICOLON | EOF) | insertStmt; | |
query | |
: alterStmt | |
| analyzeStmt | |
| createStmt | |
| optimizeStmt | |
| selectUnionStmt | |
| showStmt | |
; | |
// ALTER statement | |
alterStmt: ALTER TABLE tableIdentifier alterTableClause (COMMA alterTableClause)*; | |
alterTableClause: ADD COLUMN (IF NOT EXISTS)? tableColumnDfnt (AFTER nestedIdentifier)?; | |
// ANALYZE statement | |
analyzeStmt: ANALYZE queryStmt; | |
// CREATE statement | |
createStmt | |
: (ATTACH | CREATE) DATABASE (IF NOT EXISTS)? databaseIdentifier engineExpr? | |
| (ATTACH | CREATE) MATERIALIZED VIEW (IF NOT EXISTS)? tableIdentifier schemaClause? destinationClause? engineClause? POPULATE? subqueryClause | |
| (ATTACH | CREATE) TEMPORARY? TABLE (IF NOT EXISTS)? tableIdentifier schemaClause? engineClause? subqueryClause? | |
| (ATTACH | CREATE) VIEW (IF NOT EXISTS)? tableIdentifier subqueryClause | |
; | |
destinationClause: TO tableIdentifier; | |
subqueryClause: AS selectUnionStmt; | |
schemaClause: LPAREN tableElementExpr (COMMA tableElementExpr)* RPAREN; | |
engineClause: | |
engineExpr | |
( orderByClause | |
| partitionByClause | |
| primaryKeyClause | |
| sampleByClause | |
)* | |
; | |
partitionByClause: PARTITION BY columnExpr; | |
primaryKeyClause: PRIMARY KEY columnExpr; | |
sampleByClause: SAMPLE BY columnExpr; | |
engineExpr: ENGINE EQ_SINGLE? identifier (LPAREN columnExprList? RPAREN)?; | |
tableElementExpr: tableColumnDfnt; | |
tableColumnDfnt | |
: nestedIdentifier columnTypeExpr tableColumnPropertyExpr? (COMMENT STRING_LITERAL)? (TTL columnExpr)? | |
| nestedIdentifier columnTypeExpr? tableColumnPropertyExpr (COMMENT STRING_LITERAL)? (TTL columnExpr)? | |
; | |
tableColumnPropertyExpr: (DEFAULT | MATERIALIZED | ALIAS) columnExpr; | |
// INSERT statement | |
insertStmt: INSERT INTO TABLE? (tableIdentifier | FUNCTION tableFunctionExpr) columnsClause? dataClause; | |
columnsClause: LPAREN nestedIdentifier (COMMA nestedIdentifier)* RPAREN; | |
dataClause | |
: FORMAT identifier | |
| VALUES | |
| selectUnionStmt | |
; | |
// OPTIMIZE statement | |
optimizeStmt: OPTIMIZE TABLE tableIdentifier partitionClause? FINAL? DEDUPLICATE?; | |
partitionClause | |
: PARTITION columnExpr | |
| PARTITION ID STRING_LITERAL | |
; | |
// SELECT statement | |
selectUnionStmt: selectStmtWithParens (UNION ALL selectStmtWithParens)*; | |
selectStmtWithParens: selectStmt | LPAREN selectUnionStmt RPAREN; | |
selectStmt: | |
withClause? | |
SELECT DISTINCT? columnExprList | |
fromClause? | |
arrayJoinClause? | |
prewhereClause? | |
whereClause? | |
groupByClause? | |
havingClause? | |
orderByClause? | |
; | |
withClause: WITH columnExprList; | |
fromClause: FROM joinExpr FINAL?; | |
arrayJoinClause: LEFT? ARRAY JOIN columnExprList; | |
prewhereClause: PREWHERE columnExpr; | |
whereClause: WHERE columnExpr; | |
groupByClause: GROUP BY columnExprList (WITH TOTALS)?; | |
havingClause: HAVING columnExpr; | |
orderByClause: ORDER BY orderExprList; | |
joinExpr | |
: LPAREN joinExpr RPAREN | |
| joinExpr (GLOBAL|LOCAL)? joinOp? JOIN joinExpr joinConstraintClause | |
| joinExpr joinOpCross joinExpr | |
| tableExpr | |
; | |
joinOp | |
: (ANY? INNER | INNER ANY?) | |
| ((OUTER | SEMI | ANTI | ANY | ASOF)? (LEFT | RIGHT) | (LEFT | RIGHT) (OUTER | SEMI | ANTI | ANY | ASOF)?) | |
| ((OUTER | ANY)? FULL | FULL (OUTER | ANY)?) | |
; | |
joinOpCross | |
: (GLOBAL|LOCAL)? CROSS JOIN | |
| COMMA | |
; | |
joinConstraintClause | |
: ON columnExprList | |
| USING LPAREN columnExprList RPAREN | |
| USING columnExprList | |
; | |
orderExprList: orderExpr (COMMA orderExpr)*; | |
orderExpr: columnExpr (ASCENDING | DESCENDING | DESC)? (NULLS (FIRST | LAST))? (COLLATE STRING_LITERAL)?; | |
// SHOW statements | |
showStmt | |
: SHOW CREATE DATABASE databaseIdentifier | |
| SHOW CREATE TEMPORARY? TABLE? tableIdentifier | |
| SHOW TEMPORARY? TABLES ((FROM | IN) databaseIdentifier)? (LIKE STRING_LITERAL | whereClause)? | |
| SHOW DATABASES | |
; | |
// Columns | |
columnTypeExpr | |
: identifier | |
| identifier LPAREN columnExprList RPAREN | |
| identifier LPAREN columnTypeExpr (COMMA columnTypeExpr)* RPAREN | |
| identifier LPAREN identifier columnTypeExpr (COMMA identifier columnTypeExpr)* RPAREN | |
; | |
columnExprList: columnExpr (COMMA columnExpr)*; | |
columnExpr | |
: CAST LPAREN columnExpr AS identifier RPAREN | |
| identifier (LPAREN columnExprList? RPAREN)? LPAREN columnExprList? RPAREN | |
| columnExpr AS? identifier | |
| columnIdentifier | |
| literal | |
; | |
columnIdentifier: (tableIdentifier DOT)? nestedIdentifier; | |
nestedIdentifier: identifier (DOT identifier)?; | |
// Tables | |
tableExpr | |
: tableIdentifier | |
| tableFunctionExpr | |
| LPAREN selectUnionStmt RPAREN | |
| tableExpr AS? identifier | |
; | |
tableFunctionExpr: identifier LPAREN tableArgList? RPAREN; | |
tableIdentifier: (databaseIdentifier DOT)? identifier; | |
tableArgList: tableArgExpr (COMMA tableArgExpr)*; | |
tableArgExpr | |
: tableExpr | |
| literal | |
; | |
// Databases | |
databaseIdentifier: identifier; | |
// Basics | |
literal: STRING_LITERAL; | |
identifier: IDENTIFIER; | |
// Keywords | |
ADD: A D D; | |
AFTER: A F T E R; | |
ALIAS: A L I A S; | |
ALL: A L L; | |
ALTER: A L T E R; | |
ANALYZE: A N A L Y Z E; | |
ANTI: A N T I; | |
ANY: A N Y; | |
ARRAY: A R R A Y; | |
AS: A S; | |
ASCENDING: A S C | A S C E N D I N G; | |
ASOF: A S O F; | |
ATTACH: A T T A C H; | |
BY: B Y; | |
CAST: C A S T; | |
CLEAR: C L E A R; | |
COLLATE: C O L L A T E; | |
COLUMN: C O L U M N; | |
COMMENT: C O M M E N T; | |
CREATE: C R E A T E; | |
CROSS: C R O S S; | |
DATABASE: D A T A B A S E; | |
DATABASES: D A T A B A S E S; | |
DEDUPLICATE: D E D U P L I C A T E; | |
DEFAULT: D E F A U L T; | |
DELETE: D E L E T E; | |
DESC: D E S C; | |
DESCENDING: D E S C E N D I N G; | |
DETACH: D E T A C H; | |
DISK: D I S K; | |
DISTINCT: D I S T I N C T; | |
DROP: D R O P; | |
ENGINE: E N G I N E; | |
EXISTS: E X I S T S; | |
FINAL: F I N A L; | |
FIRST: F I R S T; | |
FORMAT: F O R M A T; | |
FROM: F R O M; | |
FULL: F U L L; | |
FUNCTION: F U N C T I O N; | |
GLOBAL: G L O B A L; | |
GROUP: G R O U P; | |
HAVING: H A V I N G; | |
ID: I D; | |
IF: I F; | |
IN: I N; | |
INNER: I N N E R; | |
INSERT: I N S E R T; | |
INTO: I N T O; | |
JOIN: J O I N; | |
KEY: K E Y; | |
LAST: L A S T; | |
LEFT: L E F T; | |
LIKE: L I K E; | |
LIMIT: L I M I T; | |
LOCAL: L O C A L; | |
MATERIALIZED: M A T E R I A L I Z E D; | |
MODIFY: M O D I F Y; | |
NOT: N O T; | |
NULLS: N U L L S; | |
ON: O N; | |
OPTIMIZE: O P T I M I Z E; | |
ORDER: O R D E R; | |
OUTER: O U T E R; | |
PARTITION: P A R T I T I O N; | |
POPULATE: P O P U L A T E; | |
PREWHERE: P R E W H E R E; | |
PRIMARY: P R I M A R Y; | |
RIGHT: R I G H T; | |
SAMPLE: S A M P L E; | |
SELECT: S E L E C T; | |
SEMI: S E M I; | |
SHOW: S H O W; | |
TABLE: T A B L E; | |
TABLES: T A B L E S; | |
TEMPORARY: T E M P O R A R Y; | |
TO: T O; | |
TOTALS: T O T A L S; | |
TTL: T T L; | |
UNION: U N I O N; | |
USING: U S I N G; | |
VALUES: V A L U E S; | |
VIEW: V I E W; | |
WHERE: W H E R E; | |
WITH: W I T H; | |
// Tokens | |
IDENTIFIER: LETTER+; | |
// It's important that quote-symbol is a single character. | |
STRING_LITERAL: QUOTE_SINGLE ( ~([\\']) | (BACKSLASH .) | (QUOTE_SINGLE QUOTE_SINGLE) )* QUOTE_SINGLE; | |
// Alphabet and allowed symbols | |
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]; | |
fragment LETTER: [a-zA-Z]; | |
BACKSLASH: '\\'; | |
COMMA: ','; | |
DOT: '.'; | |
EQ_SINGLE: '='; | |
LPAREN: '('; | |
QUOTE_SINGLE: '\''; | |
RPAREN: ')'; | |
SEMICOLON: ';'; | |
WHITESPACE: [ \u000B\u000C\t\r\n] -> skip; // '\n' can be part of multiline single query |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment