mrs_plugin/grammar/MRSLexer.g4 (310 lines of code) (raw):
/*
* Copyright (c) 2023, 2025, Oracle and/or its affiliates.
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License, version 2.0, as published by the Free Software Foundation.
*
* This program is designed to work with certain software (including but not limited to OpenSSL)
* that is licensed under separate terms, as designated in a particular file or component or in
* included license documentation. The authors of MySQL hereby grant you an additional permission to
* link the program and your derivative works with the separately licensed software that they have
* included with MySQL. This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License along with this program; if
* not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
lexer grammar MRSLexer; // MySQL REST Service (MRS) Grammar Definition
CREATE_SYMBOL: C R E A T E;
OR_SYMBOL: O R;
REPLACE_SYMBOL: R E P L A C E;
ALTER_SYMBOL: A L T E R;
SHOW_SYMBOL: S H O W;
STATUS_SYMBOL: S T A T U S;
NEW_SYMBOL: N E W;
ON_SYMBOL: O N;
FROM_SYMBOL: F R O M;
IN_SYMBOL: I N;
DATABASES_SYMBOL: D A T A B A S E S;
DATABASE_SYMBOL: D A T A B A S E;
SCHEMAS_SYMBOL: S C H E M A S -> type(DATABASES_SYMBOL);
SCHEMA_SYMBOL: S C H E M A -> type(DATABASE_SYMBOL);
JSON_SYMBOL: J S O N;
VIEW_SYMBOL: V I E W;
PROCEDURE_SYMBOL: P R O C E D U R E;
FUNCTION_SYMBOL: F U N C T I O N;
DROP_SYMBOL: D R O P;
USE_SYMBOL: U S E;
AS_SYMBOL: A S;
FILTER_SYMBOL: F I L T E R;
AUTHENTICATION_SYMBOL: A U T H E N T I C A T I O N;
PATH_SYMBOL: P A T H;
VALIDATION_SYMBOL: V A L I D A T I O N;
DEFAULT_SYMBOL: D E F A U L T;
USER_SYMBOL: U S E R;
OPTIONS_SYMBOL: O P T I O N S;
IF_SYMBOL: I F;
NOT_SYMBOL: N O T;
EXISTS_SYMBOL: E X I S T S;
PAGE_SYMBOL: P A G E;
HOST_SYMBOL: H O S T;
TYPE_SYMBOL: T Y P E;
FORMAT_SYMBOL: F O R M A T;
FORCE_SYMBOL: F O R C E;
UPDATE_SYMBOL: U P D A T E;
NULL_SYMBOL: N U L L;
TRUE_SYMBOL: T R U E;
FALSE_SYMBOL: F A L S E;
SET_SYMBOL: S E T;
IDENTIFIED_SYMBOL: I D E N T I F I E D;
BY_SYMBOL: B Y;
ROLE_SYMBOL: R O L E;
TO_SYMBOL: T O;
IGNORE_SYMBOL: I G N O R E;
CLONE_SYMBOL: C L O N E;
FILE_SYMBOL: F I L E;
BINARY_SYMBOL: B I N A R Y;
DATA_SYMBOL: D A T A;
LOAD_SYMBOL: L O A D;
GRANT_SYMBOL: G R A N T;
READ_SYMBOL: R E A D;
DELETE_SYMBOL: D E L E T E;
GROUP_SYMBOL: G R O U P;
REVOKE_SYMBOL: R E V O K E;
ACCOUNT_SYMBOL: A C C O U N T;
LOCK_SYMBOL: L O C K;
UNLOCK_SYMBOL: U N L O C K;
GRANTS_SYMBOL: G R A N T S;
FOR_SYMBOL: F O R;
LEVEL_SYMBOL: L E V E L;
ANY_SYMBOL: A N Y;
CLIENT_SYMBOL: C L I E N T;
URL_SYMBOL: U R L;
NAME_SYMBOL: N A M E;
DO_SYMBOL: D O;
ALL_SYMBOL: A L L;
PARAMETERS_SYMBOL: P A R A M E T E R S;
ADD_SYMBOL: A D D;
REMOVE_SYMBOL: R E M O V E;
MERGE_SYMBOL: M E R G E;
COMMENT_SYMBOL: C O M M E N T;
DYNAMIC_SYMBOL: D Y N A M I C;
SQL_SYMBOL: S Q L;
AND_SYMBOL: A N D;
// Used for auto merging this grammar and the standard MySQL grammar.
/* START OF MERGE PART */
CONFIGURE_SYMBOL: C O N F I G U R E;
REST_SYMBOL: R E S T;
METADATA_SYMBOL: M E T A D A T A;
SERVICES_SYMBOL: S E R V I C E S;
SERVICE_SYMBOL: S E R V I C E;
VIEWS_SYMBOL: V I E W S;
PROCEDURES_SYMBOL: P R O C E D U R E S;
FUNCTIONS_SYMBOL: F U N C T I O N S;
RESULT_SYMBOL: R E S U L T;
ENABLED_SYMBOL: E N A B L E D;
PUBLISHED_SYMBOL: P U B L I S H E D;
DISABLED_SYMBOL: D I S A B L E D;
PRIVATE_SYMBOL: P R I V A T E;
UNPUBLISHED_SYMBOL: U N P U B L I S H E D;
PROTOCOL_SYMBOL: P R O T O C O L;
HTTP_SYMBOL: H T T P;
HTTPS_SYMBOL: H T T P S;
REQUEST_SYMBOL: R E Q U E S T;
REDIRECTION_SYMBOL: R E D I R E C T I O N;
MANAGEMENT_SYMBOL: M A N A G E M E N T;
AVAILABLE_SYMBOL: A V A I L A B L E;
REQUIRED_SYMBOL: R E Q U I R E D;
ITEMS_SYMBOL: I T E M S;
PER_SYMBOL: P E R;
CONTENT_SYMBOL: C O N T E N T;
MEDIA_SYMBOL: M E D I A;
AUTODETECT_SYMBOL: A U T O D E T E C T;
FEED_SYMBOL: F E E D;
ITEM_SYMBOL: I T E M;
SETS_SYMBOL: S E T S;
FILES_SYMBOL: F I L E S;
AUTH_SYMBOL: A U T H;
APPS_SYMBOL: A P P S;
APP_SYMBOL: A P P;
ID_SYMBOL: I D;
SECRET_SYMBOL: S E C R E T;
VENDOR_SYMBOL: V E N D O R;
MRS_SYMBOL: M R S;
MYSQL_SYMBOL: M Y S Q L;
USERS_SYMBOL: U S E R S;
ALLOW_SYMBOL: A L L O W;
REGISTER_SYMBOL: R E G I S T E R;
CLASS_SYMBOL: C L A S S;
DEVELOPMENT_SYMBOL: D E V E L O P M E N T;
SCRIPTS_SYMBOL: S C R I P T S;
MAPPING_SYMBOL: M A P P I N G;
TYPESCRIPT_SYMBOL: T Y P E S C R I P T;
ROLES_SYMBOL: R O L E S;
EXTENDS_SYMBOL: E X T E N D S;
OBJECT_SYMBOL: O B J E C T;
HIERARCHY_SYMBOL: H I E R A R C H Y;
INCLUDE_SYMBOL: I N C L U D E;
INCLUDING_SYMBOL: I N C L U D I N G;
ENDPOINTS_SYMBOL: E N D P O I N T S;
OBJECTS_SYMBOL: O B J E C T S;
DUMP_SYMBOL: D U M P;
ZIP_SYMBOL: Z I P;
SCRIPT_SYMBOL: S C R I P T;
STATIC_SYMBOL: S T A T I C;
//----------------- GraphQL --------------------------------------------------------------------------------------------
AT_INOUT_SYMBOL: AT_SIGN_SYMBOL I N O U T;
AT_IN_SYMBOL: AT_SIGN_SYMBOL I N;
AT_OUT_SYMBOL: AT_SIGN_SYMBOL O U T;
AT_CHECK_SYMBOL: AT_SIGN_SYMBOL C H E C K;
AT_NOCHECK_SYMBOL: AT_SIGN_SYMBOL N O C H E C K;
AT_NOUPDATE_SYMBOL: AT_SIGN_SYMBOL N O U P D A T E;
AT_SORTABLE_SYMBOL: AT_SIGN_SYMBOL S O R T A B L E;
AT_NOFILTERING_SYMBOL: AT_SIGN_SYMBOL N O F I L T E R I N G;
AT_ROWOWNERSHIP_SYMBOL: AT_SIGN_SYMBOL R O W O W N E R S H I P;
AT_UNNEST_SYMBOL: AT_SIGN_SYMBOL U N N E S T;
AT_DATATYPE_SYMBOL: AT_SIGN_SYMBOL D A T A T Y P E;
AT_SELECT_SYMBOL: AT_SIGN_SYMBOL S E L E C T;
AT_NOSELECT_SYMBOL: AT_SIGN_SYMBOL N O S E L E C T;
AT_INSERT_SYMBOL: AT_SIGN_SYMBOL I N S E R T;
AT_NOINSERT_SYMBOL: AT_SIGN_SYMBOL N O I N S E R T;
AT_UPDATE_SYMBOL: AT_SIGN_SYMBOL U P D A T E;
AT_DELETE_SYMBOL: AT_SIGN_SYMBOL D E L E T E;
AT_NODELETE_SYMBOL: AT_SIGN_SYMBOL N O D E L E T E;
AT_KEY_SYMBOL: AT_SIGN_SYMBOL K E Y;
REST_REQUEST_PATH:
(DIV_OPERATOR IDENTIFIER)+;
/* END OF MERGE PART */
//-------------------------------------------------------------------------------------------------
// Operators
EQUAL_OPERATOR: '='; // Also assign.
ASSIGN_OPERATOR: ':=';
NULL_SAFE_EQUAL_OPERATOR: '<=>';
GREATER_OR_EQUAL_OPERATOR: '>=';
GREATER_THAN_OPERATOR: '>';
LESS_OR_EQUAL_OPERATOR: '<=';
LESS_THAN_OPERATOR: '<';
NOT_EQUAL_OPERATOR: '!=';
NOT_EQUAL2_OPERATOR: '<>' -> type(NOT_EQUAL_OPERATOR);
PLUS_OPERATOR: '+';
MINUS_OPERATOR: '-';
MULT_OPERATOR: '*';
DIV_OPERATOR: '/';
MOD_OPERATOR: '%';
LOGICAL_NOT_OPERATOR: '!';
BITWISE_NOT_OPERATOR: '~';
SHIFT_LEFT_OPERATOR: '<<';
SHIFT_RIGHT_OPERATOR: '>>';
LOGICAL_AND_OPERATOR: '&&';
BITWISE_AND_OPERATOR: '&';
BITWISE_XOR_OPERATOR: '^';
LOGICAL_OR_OPERATOR: '||';
BITWISE_OR_OPERATOR: '|';
DOT_SYMBOL: '.';
COMMA_SYMBOL: ',';
SEMICOLON_SYMBOL: ';';
COLON_SYMBOL: ':';
OPEN_PAR_SYMBOL: '(';
CLOSE_PAR_SYMBOL: ')';
OPEN_CURLY_SYMBOL: '{';
CLOSE_CURLY_SYMBOL: '}';
UNDERLINE_SYMBOL: '_';
OPEN_SQUARE_SYMBOL: '[';
CLOSE_SQUARE_SYMBOL: ']';
JSON_SEPARATOR_SYMBOL: '->';
JSON_UNQUOTED_SEPARATOR_SYMBOL: '->>';
// The MySQL server parser uses custom code in its lexer to allow base alphanum chars (and ._$) as
// variable name. For this it handles user variables in 2 different ways and we have to model this
// to match that behavior.
AT_SIGN_SYMBOL: '@';
AT_TEXT_SUFFIX: '@' SIMPLE_IDENTIFIER;
AT_AT_SIGN_SYMBOL: '@@';
NULL2_SYMBOL: '\\N';
PARAM_MARKER: '?';
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 DIGIT: [0-9];
fragment DIGITS: DIGIT+;
fragment HEXDIGIT: [0-9a-fA-F];
// Only lower case 'x' and 'b' count for hex + bin numbers. Otherwise it's an identifier.
HEX_NUMBER: ('0x' HEXDIGIT+) | ('x\'' HEXDIGIT+ '\'');
BIN_NUMBER: ('0b' [01]+) | ('b\'' [01]+ '\'');
INT_NUMBER: DIGITS;
// Float types must be handled first or the DOT_IDENTIIFER rule will make them to identifiers (if
// there is no leading digit before the dot).
DECIMAL_NUMBER: DIGITS? DOT_SYMBOL DIGITS;
FLOAT_NUMBER: (DIGITS? DOT_SYMBOL)? DIGITS [eE] ( MINUS_OPERATOR | PLUS_OPERATOR)? DIGITS;
// White space handling
WHITESPACE: [ \t\f\r\n] -> channel(HIDDEN); // Ignore whitespaces.
// Input not covered elsewhere (unless quoted).
INVALID_INPUT:
[\u0001-\u0008] // Control codes.
| '\u000B' // Line tabulation.
| '\u000C' // Form feed.
| [\u000E-\u001F] // More control codes.
;
// String and text types.
// Identifiers might start with a digit, even though it is discouraged, and may not consist entirely
// of digits only. All keywords above are automatically excluded.
IDENTIFIER:
DIGITS+ [eE] (LETTER_WHEN_UNQUOTED_NO_DIGIT LETTER_WHEN_UNQUOTED*)? // Have to exclude float pattern, as this rule matches more.
| DIGITS+ LETTER_WITHOUT_FLOAT_PART LETTER_WHEN_UNQUOTED*
| LETTER_WHEN_UNQUOTED_NO_DIGIT LETTER_WHEN_UNQUOTED*
;
// INT_NUMBER matches first if there are only digits.
NCHAR_TEXT: [nN] SINGLE_QUOTED_TEXT;
// MySQL supports automatic concatenation of multiple single and double quoted strings if they
// follow each other as separate tokens. This is reflected in the `textLiteral` parser rule. Here we
// handle duplication of quotation chars only (which must be replaced by a single char in the target
// code).
fragment BACK_TICK: '`';
fragment SINGLE_QUOTE: '\'';
fragment DOUBLE_QUOTE: '"';
BACK_TICK_QUOTED_ID:
BACK_TICK (({!this.isSqlModeActive(SqlMode.NoBackslashEscapes)}? '\\')? .)*? BACK_TICK;
DOUBLE_QUOTED_TEXT: (
DOUBLE_QUOTE (({!this.isSqlModeActive(SqlMode.NoBackslashEscapes)}? '\\')? .)*? DOUBLE_QUOTE
)+;
SINGLE_QUOTED_TEXT: (
SINGLE_QUOTE (({!this.isSqlModeActive(SqlMode.NoBackslashEscapes)}? '\\')? .)*? SINGLE_QUOTE
)+;
BLOCK_COMMENT: ('/**/' | '/*' ~[!] .*? '*/') -> channel(HIDDEN);
POUND_COMMENT: '#' ~([\n\r])* -> channel(HIDDEN);
DASHDASH_COMMENT: DOUBLE_DASH ([ \t] (~[\n\r])* | LINEBREAK | EOF) -> channel(HIDDEN);
fragment DOUBLE_DASH: '--';
fragment LINEBREAK: [\n\r];
fragment SIMPLE_IDENTIFIER: (DIGIT | [a-zA-Z_$] | DOT_SYMBOL)+;
fragment ML_COMMENT_HEAD: '/*';
fragment ML_COMMENT_END: '*/';
// As defined in https://dev.mysql.com/doc/refman/8.0/en/identifiers.html.
fragment LETTER_WHEN_UNQUOTED: DIGIT | LETTER_WHEN_UNQUOTED_NO_DIGIT;
fragment LETTER_WHEN_UNQUOTED_NO_DIGIT: [a-zA-Z_$\u0080-\uffff];
// Any letter but without e/E and digits (which are used to match a decimal number).
fragment LETTER_WITHOUT_FLOAT_PART: [a-df-zA-DF-Z_$\u0080-\uffff];
WS: [ \t\n\r]+ -> skip;