複数行の#define文を扱うことができる前処理を行うレクサーを作成しようとしています。例えば、複数行の定義は、後続の空行(ただしホワイトスペースを含んでいてもよい)によって破壊され、次の入力、第一のステップは、ここで任意の定義については、入力ストリームをトークン化することであるantlr4で複数行の定義文をレキシングする
aa(bb);
#define XX pqr
#define YY pqr \
+abc
class p(XX,YY,zz);
endclass
値は1つの文字列トークンとして取得されます。たとえば、YYの場合、文字列値として "pqr + abc"を取得しようとしています。私は、トークン化のために、次のレクサーを書かれている:
DEF: '#define' -> pushMode(def_mode);
ID: Letter (Letter | DecDigit)* ;
COMMENT : '/*' .*? '*/' -> channel(HIDDEN) ;
LINE_COMMENT : '//' ~('\n'|'\r')* NL -> channel(HIDDEN);
WS: (' ' |'\t' | NL)+ -> channel(HIDDEN) ;
SEMICOLN: ';' ;
COMMA: ',' ;
OB: '(' ;
CB: ')' ;
PLUS: '+' ;
fragment NL : '\r'? '\n' ;
fragment DecDigit: '0'..'9' ;
fragment Letter: 'A'..'Z' | 'a'..'z' | '_' ;
mode def_mode;
STR2: '\r'? '\n' -> popMode;
STR1: ~('\n'|'\r')* '\r'? '\n' ;
上記レクサーはの#define行のため、次のトークンを提供します:
[@10,26:32='#define',<2>,6:0]
[@11,33:42=' YY pqr \\n',<13>,6:7]
[@12,43:51=' +abc\n',<13>,7:0]
[@13,52:52='\n',<12>,8:0]
[@14,53:57='class',<3>,9:0]
以上のトークンが「空」の行がある場合のみ得られているが#define行の後ろに。その行に空白がある場合、つまり空ではない場合、モードは終了しません。行に空白がある場合のトークンは次のとおりです。
[@10,26:32='#define',<2>,6:0]
[@11,33:42=' YY pqr \\n',<13>,6:7]
[@12,43:51=' +abc\n',<13>,7:0]
[@13,52:55=' \n',<13>,8:0]
[@14,56:74='class p(XX,YY,zz);\n',<13>,9:0]
[@15,75:83='endclass\n',<13>,10:0]
[@16,84:84='\n',<12>,11:0]
[@17,85:84='<EOF>',<-1>,12:0]
また、レクサーは2行を結合していません。これらのエラーを修正するには?
空白行が表示されるまで入力を手動でスキャンするコードを追加して、モードを終了できますか? – R71