Я пытаюсь создать простой препроцессор в ANTLR. Моя грамматика выглядит следующим образом:Простой препроцессор ANTLR
grammar simple_preprocessor;
ifdef_statement : POUND_IFDEF IDENTIFIER ;
else_statement : POUND_ELSE ;
endif_statement : POUND_ENDIF ;
preprocessor_statement :
ifdef_statement
code_block
else_statement
code_block
endif_statement
;
code_file : (preprocessor_statement | code_block)+ EOF ;
code_block : TEXT ;
POUND_IFDEF : '#IFDEF';
POUND_ELSE : '#ELSE';
POUND_ENDIF : '#ENDIF';
IDENTIFIER : ID_START ID_CONTINUE* ;
TEXT : ~[\u000C]+ ;
fragment ID_START : '_' | [A-Z] | [a-z] ;
fragment ID_CONTINUE : ID_START | [0-9] ;
WS : [ \t\r\n\u000C]+ -> channel(HIDDEN) ;
Затем я анализирую следующее с помощью code_file() правило:
#IFDEF one
print "1"
#ELSE
print "2"
#ENDIF
Строка дерева выглядит следующим образом:
(code_file (code_block \n#IFDEF one\n print "1"\n#ELSE\n print "2"\n#ENDIF\n) <EOF>)
Не то, что я хочу , поскольку токены препроцессора обрабатываются как текст и соответствуют правилу code_block.
Я прочитал «Остров в потоке» главы в книге ANTLR, и пример XML имеет смысл, но она опирается на TEXT, не содержащее два специальных символов:
TEXT : ~[<&]+ ;
Если я действительно должен, Я полагаю, я мог бы исключить символ #:
TEXT : ~[#]+ ;
Но я надеюсь, что есть лучший способ сказать ANTLR, чтобы исключить мои препроцессора маркеры, чтобы он мог отличить их от общего кода.
Спасибо за любую помощь.
Спасибо, режимы выглядят как правильный подход. Я пробовал это вчера, но он не работал так, как мне было нужно - скорее всего, я делал неправильно. Спасибо за отправку примера - это будет полезно! – RedTailedHawk
Hi @GRose, ваше определение PTEXT не включает \ r \ n, но что, если вам нужны те внутри текста, содержащиеся в токенах препроцессора? – RedTailedHawk
Спасибо @GRose, я ценю обновление! – RedTailedHawk