Skip to content

Commit

Permalink
feat(YQL): add tokenize method for YQL (#205)
Browse files Browse the repository at this point in the history
* feat(YQL): add tokenize method for yql

* feat(YQL): code review

* ci: add eslint rule
  • Loading branch information
itwillwork authored Jul 23, 2024
1 parent 82d75a2 commit 8c2f69a
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 1 deletion.
1 change: 1 addition & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"consistent-return": "off",
"no-negated-condition": "off",
"@typescript-eslint/explicit-function-return-type": "error",
"@typescript-eslint/array-type": ["error", { "default": "array" }],
"object-shorthand": "error",
"no-implicit-globals": "off",
"camelcase": "off",
Expand Down
8 changes: 7 additions & 1 deletion src/autocomplete/databases/yql/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import {CursorPosition} from '../../shared/autocomplete-types';
import {yqlAutocompleteData, yqlAutocompleteDataYQ} from './yql-autocomplete';
import {parseQuery, parseQueryWithoutCursor} from '../../shared/autocomplete';
import {separateQueryAndCursor} from '../../shared/parse-query-with-cursor';
import {YqlAutocompleteResult} from './types';
import {YqlAutocompleteResult, YqlTokenizeResult} from './types';
import {tokenize} from '../../shared/tokenize';
import {YQLLexer} from './generated/YQLLexer';

export type {YqlAutocompleteResult};

Expand Down Expand Up @@ -63,3 +65,7 @@ export function parseYqlQueryWithCursor(queryWithCursor: string): YqlAutocomplet
export function parseYqQueryWithCursor(queryWithCursor: string): YqlAutocompleteResult {
return parseYqQuery(...separateQueryAndCursor(queryWithCursor));
}

export function tokenizeYqlQuery(query: string): YqlTokenizeResult {
return tokenize(YQLLexer, YQLLexer.symbolicNames, query);
}
3 changes: 3 additions & 0 deletions src/autocomplete/databases/yql/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {AutocompleteResultBase, TableIndexSuggestion} from '../../shared/autocomplete-types';
import {TokenizeResult} from '../../shared/tokenize';

export type EntitySuggestion =
| 'suggestObject'
Expand Down Expand Up @@ -58,3 +59,5 @@ export interface YqlAutocompleteResult extends AutocompleteResultBase {
suggestTableHints?: string;
suggestEntitySettings?: YQLEntity;
}

export interface YqlTokenizeResult extends TokenizeResult {}
5 changes: 5 additions & 0 deletions src/autocomplete/shared/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,8 @@ export function createParser<L extends LexerType, P extends ParserType>(

return parser;
}

export function createLexer<L extends LexerType>(Lexer: LexerConstructor<L>, query: string): L {
const inputStream = CharStream.fromString(query);
return new Lexer(inputStream);
}
52 changes: 52 additions & 0 deletions src/autocomplete/shared/tokenize.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import {LexerConstructor, ParserSyntaxError} from './autocomplete-types';
import {Lexer as LexerType} from 'antlr4ng';
import {createLexer} from './query';
import {SqlErrorListener} from './sql-error-listener';
import {tokenDictionary} from '../databases/yql/helpers';

export type Token = {
ruleName: string;
startIndex: number;
};

export type TokenizeResult = {
tokens: Token[];
errors: ParserSyntaxError[];
};

const EOF = -1;

export function tokenize<L extends LexerType>(
Lexer: LexerConstructor<L>,
symbolicNames: (string | null)[],
query: string,
): TokenizeResult {
const lexer = createLexer(Lexer, query);
const errorListener = new SqlErrorListener(tokenDictionary.SPACE);

lexer.removeErrorListeners();
lexer.addErrorListener(errorListener);

const tokens: Token[] = [];

let done = false;
do {
const token = lexer.nextToken();
if (token === null || token.type === EOF) {
done = true;
} else {
const tokenName = symbolicNames[token.type];
if (tokenName) {
tokens.push({
ruleName: tokenName,
startIndex: token.column,
});
}
}
} while (!done);

return {
tokens,
errors: errorListener.errors,
};
}

0 comments on commit 8c2f69a

Please sign in to comment.