Я пытаюсь написать некоторые инструменты (проверка / возможно автозаполнение) для языка запросов SQL-esk. Однако синтаксический анализатор разбивает токены на недопустимые / неполные входные данные таким образом, что затрудняет работу с ним.
Я сократил свой сценарий до его самой простой воспроизводимой формы. Вот моя минимизированная грамматика:
grammar SOQL;
WHITE_SPACE : ( ' '|'\r'|'\t'|'\n' ) -> channel(HIDDEN) ;
FROM : 'FROM' ;
SELECT : 'SELECT' ;
/********** SYMBOLS **********/
COMMA : ',' ;
ID: ( 'A'..'Z' | 'a'..'z' | '_' | '$') ( 'A'..'Z' | 'a'..'z' | '_' | '$' | '0'..'9' )* ;
soql_query: select_clause from_clause;
select_clause: SELECT field ( COMMA field )*;
from_clause: FROM table;
field : ID;
table : ID;
Когда я запускаю следующий код (используя antlr4ts , но он должен быть похож на любой другой порт):
const input = 'SELECT ID, Name, Website, Contact, FROM Account'; //invalid trailing ,
let inputStream = new ANTLRInputStream(input);
let lexer = new SOQLLexer(inputStream);
let tokenStream = new CommonTokenStream(lexer);
let parser = new SOQLParser(tokenStream);
let qry = parser.soql_query();
let select = qry.select_clause();
console.log('FIELDS: ', select.field().map(field => field.text));
console.log('FROM: ', qry.from_clause().text);
Журнал консоли
line 1:35 extraneous input 'FROM' expecting ID
line 1:47 mismatched input '<EOF>' expecting 'FROM'
FIELDS: Array(5) ["ID", "Name", "Website", "Contact", "FROMAccount"]
FROM:
Я получаю ошибки (что ожидается), но я надеялся, что он все равно сможет правильно выбрать предложение FROM
.
Это было мое понимание, поскольку FROM
- это идентификатор, это недопустимое поле в select_clause
(может быть, я просто неправильно понимаю)?
Есть ли способ настроить грамматику или синтаксический анализатор так, чтобы он продолжал правильно определять предложение FROM
в этом сценарии (и другие общие состояния запроса WIP).