У меня проблема с посторонним вводом в моем файле примера.Я получил следующий лексер:
lexer grammar CtoLexer;
ENUM: 'enum';
NAMESPACE: 'namespace';
LBRACE: '{';
RBRACE: '}';
DOT: '.';
VAR: 'o ';
IDENTIFIER: LetterOrDigit+;
fragment LetterOrDigit
: [a-zA-Z$_] | [0-9];
WS: [ \t\r\n\u000C]+ -> skip;
... и парсер:
parser grammar CtoParser;
options { tokenVocab=CtoLexer; }
modelUnit
: namespaceDeclaration enumDeclaration* EOF;
namespaceDeclaration
: NAMESPACE IDENTIFIER ('.' IDENTIFIER)*;
enumDeclaration
: ENUM IDENTIFIER '{' enumConstant* '}';
enumConstant
: VAR IDENTIFIER;
Это мой пример файла cto:
namespace org.basic.sample
enum FooType {
o FOO
}
enum BarType {
o BAR
}
enum BazType {
o BAZ
}
Дерево для этогоПример файла выглядит следующим образом:
(modelUnit
(namespaceDeclaration namespace org . basic . sample)
(enumDeclaration enum FooType { (enumConstant o FOO) })
(enumDeclaration enum BarType { (enumConstant o BAR) })
(enumDeclaration enum BazType { (enumConstant o BAZ) })
<EOF>)
Когда я меняю первое перечисление в образце на что-то другое, скажем, от enum до enumi, почти все дерево испорчено.Парсер распознает только пространство имен, а остальное кажется ИДЕНТИФИКАТОРОМ.
(modelUnit
(namespaceDeclaration namespace org . basic . sample)
enumi FooType { o FOO }
enum BarType { o BAR }
enum BazType { o BAZ })
Однако, когда я делаю то же самое со вторым перечислением, как-то только это недействительное перечисление не распознается, а остальное в порядке.
(modelUnit
(namespaceDeclaration namespace org . basic . sample)
(enumDeclaration enum FooType { (enumConstant o FOO) })
enumi BarType { o BAR }
(enumDeclaration enum BazType { (enumConstant o BAZ) }) <EOF>)
Что я могу сделать, чтобы первый ошибочный ввод был пропущен, а остальная часть была распознана?Я пробовал с новыми строковыми токенами, но это вызывает проблемы, когда я хочу ввести новое объявление после пространства имен.