2016-04-08 3 views
-1

У меня проблема с ANTLR4 при попытке проанализировать файл. Он работал в первую очередь, но после того, добавив следующую строку в моей грамматики я получаю сообщение об ошибке (см ниже):ANTLR несоответствующий вход «NUM» ожидается {...., 'NUM'}

TYPE_NUM: 'NUM'; 

mismatched input 'NUM' expecting {'LOAD', '\n', 'HEAR', 'NUM', 'STRING', 'COORD', 'BOOL', 'VOID', 'LIST'} 

«NUM» ключевое слово в моем языке в следующем правиле:

typePrefix: type=('NUM' | 'BOOL' | 'STRING' | 'COORD' | 'LIST'); 

У меня также есть те же проблемы со всеми остальными моими типами префиксов, но я предполагаю, что это одно и то же решение для всех из них.

Я попытался заменить все опции правила typePrefix на TYPE_NUM, TYPE_BOOL и т. Д., Но это, похоже, не сработало.

EDIT: По запросу в комментариях я разместил часть моей грамматики, где я использую «NUM»:

prog 
    : roboDcl loads roboBodyDcl; 
loads 
    : recursion=loads 'LOAD' '(' load_id=StringLit ')' '\n' 
    | //lambda 
    ; 
memberDcl 
    : dcl=fieldDcl 
    | met_dcl=methodDcl 
    | '\n' 
    ; 
roboDcl 
    : id=Identifier':''\n' 
    ; 
roboBodyDcl 
    : recursion=roboBodyDcl dcl=memberDcl 
    | dcl=memberDcl 
    ; 
fieldDcl 
    : t=typePrefix dcl_list=variableDclList '\n'; 
typePrefix 
    : type=('NUM' | 'BOOL' | 'STRING' | 'COORD' | 'LIST'); 
variableDclList 
    : single=variableDcl 
    | list=variableDclList ',' single=variableDcl 
    ; 
variableDcl 
    : var_init=variableInitializer 
    | id=Identifier '=' list_init=listInitializer 
    ; 
variableInitializer 
    : expr=assignmentExpression 
    ; 
TYPE_NUM: 'NUM'; 
TYPE_STRING: 'STRING'; 
TYPE_COORD: 'COORD'; 
TYPE_BOOL: 'BOOL'; 
TYPE_VOID: 'VOID'; 
TYPE_LIST: 'LIST'; 

И как было сказано ранее, я пытался заменить правило typePrefix со следующим:

typePrefix 
    : type=(TYPE_NUM | TYPE_BOOL | TYPE_STRING | TYPE_COORD | TYPE_LIST); 

Надеюсь, этого хватит и спасибо заранее!

+1

Опубликовать больше информации пожалуйста, вся грамматика, если возможно. Правильно ли я понимаю, что вы дважды указали буква «NUM»? Как только TYPE_NUM, а затем в typePrefix? – Divisadero

+0

Благодарим вас за ответ. Да, это правильно, что он указан дважды, но, как я писал, он ничего не меняет, если я заменю «NUM» в typePrefix на TYPE_NUM. Грамматика долго, чтобы быть в курсе, но я обеспечу декларацию-часть, которая, надеюсь, хватит: \ п 'fieldDcl \t: \t т = typePrefix dcl_list = variableDclList«\ п»; variableDclList \t: \t single = variableDcl \t | \t list = variableDclList ',' single = variableDcl \t; variableDcl \t: \t var_init = variableInitializer \t; variableInitializer \t: \t выр = ВыражениеПрисваивании \t; ' –

+0

Вы говорите, что это слишком долго, чтобы быть в курсе, но добавили его в комментариях, что трудно читать. Пожалуйста, отредактируйте свой вопрос. Если это действительно так долго, вы можете включить github/dropbox и поделиться ссылкой – cantSleepNow

ответ

0

Я понял проблему и постараюсь дать объяснение в случае, если кто-то окажется в той же ситуации.

Как указано в «Определяющем Antlr 4 Reference» ANTLR разрешает двусмысленности в правилах лексера, выбирая сначала определенное правило. И заявляет «Это означает, что ваше правило ID должен быть определен после того, как все ваши ключевые правила ...»

В моем случае я определил мою грамматику следующим образом:

fragment NameStartChar 
    :  'A'..'Z' | 'a'..'z'; 
fragment NameChar 
    :  NameStartChar 
    |  Num 
    |  '_' 
    ; 
fragment Num 
    :  '0'..'9'; 
Identifier 
    : NameStartChar NameChar*; 
TYPE_NUM: 'NUM'; 

Это в конечном итоге сопоставляя все мои ключевые слова «NUM», «BOOL» и т. д.

Таким образом, решением было определено правило Идентификатор в качестве последнего из правил лексера. Пример можно посмотреть ниже:

fragment NameStartChar 
    :  'A'..'Z' | 'a'..'z'; 
fragment NameChar 
    :  NameStartChar 
    |  Num 
    |  '_' 
    ; 
fragment Num 
    :  '0'..'9'; 
TYPE_NUM: 'NUM'; 
//All other keyword definitions ('BOOL', 'STRING' and so alike) 
Identifier 
    : NameStartChar NameChar* 
Смежные вопросы