我正在为输入创建一个解析器,如下所示:
FirstName, LastName, Street, City, State, ZipCode
Mark,, 4460 Stuart Street, Marion Center, PA, 15759
----
FirstName=John
LastName=Smith
----
分隔符之前的数据为CSV格式,----
分隔符之后的数据为键值格式。因此,我有两组lexer规则,并使用ANTLR mode
在lexer规则之间切换。
问题是:在两组lexer规则中,我都需要一个用于空白的lexer规则,而ANTLR不允许在两种模式中使用相同的规则名称。因此,我在一种模式中将其命名为WS
,在另一种模式中命名为WS2
:
lexer grammar MyLexer;
COMMA : ',' ;
NL : ('r')?'n' ;
WS : [ trn]+ -> skip ;
SEPARATOR : SEP NL -> skip, pushMode(PAIRS) ;
STRING : (~[,rn])+ ;
fragment SEP : '----' ;
mode PAIRS ;
KEY : ('FirstName' | 'LastName') ;
EQ : '=' ;
NL2 : ('r')?'n' ;
WS2 : [ trn]+ -> skip ;
VALUE : (~[=rn])+ ;
换行符也是如此:NL
处于一种模式,NL2
处于另一种模式。
这很管用,但在美学上并不令人愉快。有没有一种更美观的方式来实现这一点?
两个改进建议:
1) 如果你的解析器是无模式的(只需要处理例如NL的——意识到在这个特定的例子中可能不是这样)
NL2 : ('r')?'n' -> type(NL);
2) 然后,只需要一点清理:
NL : Nl;
...
NL2 : Nl;
...
fragment Nl : ('r')?'n' -> type(NL);
总之,这主要是重新布置躺椅,但这是你能做的最多的事情。