Я пишу SQL-подобный язык. Предположим, что правильный синтаксис являетсяxtext как переносить ошибку синтаксического анализа?
USE foo;
SELECT * FROM bar;
но я набираю его
US foo;
SELECT * FROM bar;
По умолчанию поведение Antlr остановит синтаксический анализ, и я потерял синтаксис hightlighting и вид контура. Сообщение об ошибке: Missing EOF at 'US'
. Я пересвязать IParser к моему пользовательского анализатора в RuntimeModule
@Override
public Class<? extends org.eclipse.xtext.parser.IParser> bindIParser() {
return CustomCqlParser.class;
}
Override метод createParser
в Parser
@Override
protected InternalCqlParser createParser(XtextTokenStream stream) {
return new CustomInternalCqlParser(stream, getGrammarAccess());
}
и переопределить метод обработки этой части recoverFromMismatchedToken
потреблять все маркеры до запятой
@Override
protected Object recoverFromMismatchedToken(IntStream input, int ttype, BitSet follow) throws RecognitionException {
Object out = super.recoverFromMismatchedToken(input, ttype, follow);
if (out == null) {
beginResync();
consumeUntil(input, RULE_T_SEMICOLON);
input.consume();
endResync();
Object matchedSymbol = getCurrentInputSymbol(input);
System.out.println(matchedSymbol);
return matchedSymbol;
}
return out;
}
после этого matchedSymbol
- SELECT
, но подсветка синтаксиса по-прежнему остается e и antlr прекратить разбор. Как я мог достичь своей цели?
============ ==================================================================================================================================================== =
Я копирую super.recoverFromMismatchToken
в свой пользовательский класс и добавляю это из исходного кода.
if (ttype != EOF) {
beginResync();
consumeUntil(input, RULE_T_SEMICOLON);
input.consume();
endResync();
Object matchedSymbol = getCurrentInputSymbol(input);
input.consume(); // move past ttype token as if all were ok
return matchedSymbol;
}
Если маркер ошибка происходит не в начале и не no viable alternative
исключения, это будет держать подсветку синтаксиса собирается. Но он все равно будет считать, что он по-прежнему использует одни и те же правила синтаксического анализа, а не запускает новый. Кроме того, если я набрал неправильный токен в начале, то ожидаемым токеном будет EOF
. Который заставит мои «потреблять все токены до тех пор, пока точка с запятой» тоже не сработает.
===================== ========================================================================================================================================== ===============================
tracing InternalCqlParser.java
, я узнал, произошла ли опечатка в первом ключевом слове операторов, она получит ID
и вернется. После этого я добавляю фрагмент кода
if (LA1_0 == RULE_IDENT) {
beginResync();
consumeUntil(input, RULE_T_SEMICOLON);
input.consume();
endResync();
continue;
}
Разбор продолжается и подсветка синтаксиса остается после утверждения ошибки. Однако в строке ошибки не будет никакого маркера ошибки, и я потерял контент, помог после этой строки. Класс для запуска поддержки контента - Statement
, но он больше не будет работать.
Я полагаю, вы говорите о Кассандре CQL - Вы пытаетесь сделать парсер на самом деле принять что-то вроде «США mykeyspace;» как действительный оператор USE или вы просто пытаетесь улучшить сообщение об ошибке, чтобы он не говорил об EOF и не хотел отклонять утверждение в конце? –
Привет, я больше не работаю над этим проектом. В то время я хочу сохранить подсветку синтаксиса и другие возможности IDE, но с маркером ошибки в неправильном выражении. В исходной ситуации, если я сделал одиночную опечатку, область редактирования всего текста станет серой из-за неудачного разбора. –