Я работаю над грамматикой antlr, у которой есть правило типа operation : REGISTER '=' OPERATION TYPE OPERATOR ',' OPERATOR
. Тип определяется следующим образом: TYPE : 'int' NUMBER '*'?
. Теперь я создал базового c посетителя, который переопределяет visitOperation
и все работает нормально.
На данный момент я хотел бы иметь возможность определить, был ли тип указателем или нет в зависимости от присутствия из *. Я пытался использовать locals
, @parser
и @lexer
, но ни один из них не позволяет мне что-то делать ctx->TYPE()->isPointer()
. Я заметил, что TYPE
- это TerminalNode
, поэтому это может быть невозможно.
Что вы рекомендуете тогда? Просто создайте локальный HashMap и сохраните там какой-нибудь идентификатор?
РЕДАКТИРОВАТЬ:
Я упростил грамматику, чтобы лучше описать мой вариант использования. Я хотел бы иметь возможность разобрать инструкции, такие как:
r4 = add int32* a,b
r5 = add int8 c,d
Я использую грамматику:
grammar G;
prog: (expr NEWLINE)+;
expr : operation
;
operation : REGISTER '=' 'add' TYPE WORD ',' WORD
;
REGISTER : 'r' NUMBER
;
TYPE : 'int' NUMBER '*'?
;
WORD : (LETTER)+
;
NEWLINE : [\r\n]+ ;
WS: [ \t\n\r]+ -> skip ;
INT : [0-9] ;
LETTER : [a-z] ;
NUMBER : (INT)+
;
Кажется, все работает нормально:
grun G expr -tokens main.txt
[@0,0:1='r4',<REGISTER>,1:0]
[@1,3:3='=',<'='>,1:3]
[@2,5:7='add',<'add'>,1:5]
[@3,9:14='int32*',<TYPE>,1:9]
[@4,16:16='a',<WORD>,1:16]
[@5,17:17=',',<','>,1:17]
[@6,18:18='b',<WORD>,1:18]
[@7,19:19='\n',<NEWLINE>,1:19]
[@8,20:21='r5',<REGISTER>,2:0]
[@9,23:23='=',<'='>,2:3]
[@10,25:27='add',<'add'>,2:5]
[@11,29:33='int8*',<TYPE>,2:9]
[@12,35:35='c',<WORD>,2:15]
[@13,36:36=',',<','>,2:16]
[@14,37:37='d',<WORD>,2:17]
[@15,38:38='\n',<NEWLINE>,2:18]
[@16,39:38='<EOF>',<EOF>,3:0]
К сожалению, сейчас я не знаю, как что-то получить ctx->TYPE()->isAPointer()
.
Спасибо