Ошибка анализатора Antlr 4.5 во время выполнения

Я строю простую грамматику для программирования laguange для обучения.

Я сталкиваюсь с странной ошибкой, которая не имеет для меня никакого смысла.

line 1:0 missing {'void', 'int', 'bool', 'string', 'union'} at 'void' 

Я использую prequild lexer и parser из этой грамматики:

 grammar ProgrammingLanguage; function_definition : type_specifier IDENTIFIER '(' parameter_list_opt ')' compound_statement ; type_specifier : VOID | INT | BOOL | STRING | UNION ; compound_statement : '{' declaration_list statement_list '}' ; statement_list : statement | statement statement_list | ; statement : compound_statement | selection_statement | while_statement | jump_statement | expression_statement | comment_statement ; comment_statement : COMMENT_START COMMENT ; selection_statement : IF '(' expression ')' compound_statement | IF '(' expression ')' compound_statement ELSE compound_statement | SWITCH '(' expression ')' compound_statement ; expression_statement : ';' | expression ';' ; jump_statement : BREAK ';' | CONTINUE ';' ; while_statement : WHILE '(' expression ')' compound_statement ; primary_expression : IDENTIFIER | CONSTANT | '(' expression ')' | IDENTIFIER '(' primary_expression_list ')' ; primary_expression_list : primary_expression | primary_expression primary_expression_list | ; expression : logical_or_expression | additive_expression ; logical_or_expression : logical_and_expression | logical_or_expression '||' logical_and_expression ; logical_and_expression : compare_expression | logical_and_expression '&&' compare_expression ; compare_expression : primary_expression compare_op primary_expression | primary_expression ; compare_op : '' | '==' | '!=' | '=' ; additive_expression : multiplicative_expression | additive_expression '+' multiplicative_expression | additive_expression '-' multiplicative_expression ; multiplicative_expression : primary_expression | multiplicative_expression '*' primary_expression | multiplicative_expression '/' primary_expression | multiplicative_expression '%' primary_expression ; assignment_expression : IDENTIFIER '=' expression ; id_list : IDENTIFIER | IDENTIFIER ',' id_list ; declaration : type_specifier id_list ';' ; parameter_list_opt : parameter_list | ; parameter_list : type_specifier IDENTIFIER | type_specifier IDENTIFIER ',' parameter_list ; declaration_list : declaration | declaration declaration_list | ; /**------------------------------------------------------------------ * LEXER RULES *------------------------------------------------------------------ */ WHILE : 'while' ; BREAK : 'break' ; CONTINUE : 'continue' ; SWITCH : 'switch' ; IF : 'if' ; ELSE : 'else' ; COMMENT_START : '//' ; IDENTIFIER : ('a'..'z'|'A'..'Z')('0'..'9'|'a'..'z'|'A'..'Z')*; CONSTANT : FALSE|TRUE|STRING_VALUE|INT_VALUE; STRING_VALUE : '"'COMMENT'"'; COMMENT : ('0'..'9'|'a'..'z'|'A'..'Z')*; INT_VALUE : ('0'..'9')+; FALSE : 'false'; TRUE : 'true'; VOID : 'void'; INT : 'int'; BOOL : 'bool'; STRING : 'string'; UNION : 'union'; WS : (' '|'\t'|'\n'|'\r')+ -> skip; 

И я разбираюсь в этом java-коде:

 import org.antlr.v4.runtime.*; import org.antlr.v4.runtime.tree.ParseTree; import org.antlr.v4.runtime.tree.ParseTreeWalker; import java.io.IOException; public class Main { public static void main(String[] args) throws IOException { ProgrammingLanguageLexer lexer = new ProgrammingLanguageLexer(new ANTLRFileStream("input.txt")); ProgrammingLanguageParser parser = new ProgrammingLanguageParser(new CommonTokenStream(lexer)); ParseTree tree = parser.function_definition(); ParseTreeWalker.DEFAULT.walk(new ProgrammingLanguageBaseListener(), tree); } } 

И, наконец, строка, которую я пытаюсь разобрать:

 void power () {} 

Сообщение об ошибке означает, что ожидаемый тип токена, содержащий значение «void», не соответствует фактическому тику токена, создаваемому путем потребления строки «void» из ввода. Глядя на ваши правила lexer, вы можете предположить, что входная строка «void» потребляется правилом IDENTIFIER, создавая маркер типа IDENTIFIER, а не VOID.

В общем случае выигрывает правило lexer, которое соответствует самой длинной входной строке. Для двух (или более) правил с одинаковой длиной совпадения первые перечисленные выигрыши. Переместите все правила ключевых слов выше правила IDENTIFIER.

Полезная модульная тестовая форма сбрасывает токены lex’d и показывает соответствующие типы токенов. Что-то вроде:

 CommonTokenStream tokens = ... tokens.fill(); StringBuilder sb = new StringBuilder(); for (Token token : tokens.getTokens()) { sb.append(((YourCustomTokenType) token).toString()); } System.out.print(sb.toString()); 

Метод Token.toString () обычно достаточно хорош. Переопределите в подclassе токена, чтобы он соответствовал вашим потребностям.

  • Лучший алгоритм для оценки математического выражения?
  • JavaScriptSerializer.Deserialize - как изменить имена полей
  • Разбор аргументов командной строки в сценариях R
  • Почему DateTime.ParseExact () не может анализировать «9/1/2009» с использованием «M / d / yyyy»
  • Почему чтение записей структурных полей из std :: istream завершается неудачно, и как я могу это исправить?
  • Есть ли альтернатива для гибких / бизонов, которые можно использовать в 8-битных встроенных системах?
  • Разбор JSON с инструментами Unix
  • Как анализировать файл ini с помощью Boost
  • Разбор массива JSON в java.util.List с Gson
  • Можно ли корректно проанализировать XML, используя синтаксис jQuery $ (responseXML)?
  • Разбор строки с разделителями-запятыми std :: string
  • Давайте будем гением компьютера.