Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: basic Redis grammar, parseRedisQueryWithoutCursor function, tests #207

Merged
merged 9 commits into from
Aug 7, 2024
48 changes: 48 additions & 0 deletions src/autocomplete/databases/redis/grammar/RedisLexer.g4
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// $antlr-format alignTrailingComments true, columnLimit 500, maxEmptyLinesToKeep 1, reflowComments false, useTab false
// $antlr-format allowShortRulesOnASingleLine true, allowShortBlocksOnASingleLine true, minEmptyLines 0, alignSemicolons ownLine
// $antlr-format alignColons trailing, singleLineOverrulesHangingColon true, alignLexerCommands true, alignLabels true, alignTrailers true

lexer grammar RedisLexer;

options {
caseInsensitive = true;
}

// Spaces

SPACE : [ \t]+ -> channel (HIDDEN);
NEWLINE : ('\r' '\n'? | '\n') -> channel (HIDDEN);

// Keywords

SET : 'SET';
GET : 'GET';
INCR : 'INCR';
DECR : 'DECR';
NX : 'NX';
XX : 'XX';
EX : 'EX';
PX : 'PX';
EXAT : 'EXAT';
PXAT : 'PXAT';
KEEPTTL : 'KEEPTTL';

// Constructors symbols

SINGLE_QUOTE : '\'';
DOUBLE_QUOTE : '"';

// Literal Primitives

fragment DECIMAL_DIGIT: [0-9];

DECIMAL_LITERAL: DECIMAL_DIGIT+;

// Identifiers
// Should be at the very bottom, for it is the most general token

fragment DOUBLE_QUOTE_STRING : '"' ( '\\' . | ~('"' | '\\' | '\n' | '\r'))* '"';
fragment SINGLE_QUOTE_STRING : '\'' ('\\' . | ~('\'' | '\\' | '\n' | '\r'))* '\'';
fragment BASE_IDENTIFIER : ~(' ' | '\t' | '\'' | '"' | '\n' | '\r')+;

IDENTIFIER: BASE_IDENTIFIER | DOUBLE_QUOTE_STRING | SINGLE_QUOTE_STRING;
59 changes: 59 additions & 0 deletions src/autocomplete/databases/redis/grammar/RedisParser.g4
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// $antlr-format columnLimit 500, minEmptyLines 1, maxEmptyLinesToKeep 1, useTab false, reflowComments false, breakBeforeBraces false
// $antlr-format keepEmptyLinesAtTheStartOfBlocks false, allowShortRulesOnASingleLine false, alignSemicolons hanging, alignColons hanging
// $antlr-format alignTrailingComments true

parser grammar RedisParser;

options {
tokenVocab = RedisLexer;
}

root
: commands? EOF
;

// We can omit newline only if it's the last statement
commands
: command NEWLINE?
| command NEWLINE commands
;

command
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure we should call it command, and not statement? Statements is a common name afaik

Copy link
Contributor Author

@roberthovsepyan roberthovsepyan Aug 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's the way they call it everywhere in regards to Redis (including official docs), so I thought we better stick to conventional naming
Screenshot 2024-08-07 at 17 06 51

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice one!

: setCommand
| getCommand
| incrementCommand
| decrementCommand
;

setCommand
: SET keyName identifier (NX | XX)? GET? expirationClause?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is NX | XX? Let's move it to a separate rule for improved reliability?

;

expirationClause
: EX DECIMAL_LITERAL
| PX DECIMAL_LITERAL
| EXAT DECIMAL_LITERAL
| PXAT DECIMAL_LITERAL
| KEEPTTL
;

getCommand
: GET keyName
;

incrementCommand
: INCR keyName
;

decrementCommand
: DECR keyName
;

identifier
: IDENTIFIER
| DECIMAL_LITERAL
;

keyName
: identifier
;