我正在为这样的输入创建一个解析器:
FirstName, LastName, Street, City, State, ZipCode
Mark,, 4460 Stuart Street, Marion Center, PA, 15759
----
FirstName=John
LastName=Smith
----
分隔符之前的数据是CSV格式,----
分隔符之后的数据是键/值格式。所以我有两套词法分析器规则,我使用ANTLR mode
在词法分析器规则之间切换。
问题在于:我需要两个词法分析器规则中的空格的词法分析器规则,并且ANTLR在两种模式下都不允许相同的规则名称。所以我在一种模式下使用WS
,在另一种模式下使用WS2
:
lexer grammar MyLexer;
COMMA : ',' ;
NL : ('\r')?'\n' ;
WS : [ \t\r\n]+ -> skip ;
SEPARATOR : SEP NL -> skip, pushMode(PAIRS) ;
STRING : (~[,\r\n])+ ;
fragment SEP : '----' ;
mode PAIRS ;
KEY : ('FirstName' | 'LastName') ;
EQ : '=' ;
NL2 : ('\r')?'\n' ;
WS2 : [ \t\r\n]+ -> skip ;
VALUE : (~[=\r\n])+ ;
同样适用换行符:NL
在一种模式下,NL2
在另一种模式下。
虽然有效,但在美学上并不令人愉悦。有没有更美观的方式来实现这个?
答案 0 :(得分:2)
建议两个改进:
1)如果您的解析器是无模式的(只需处理例如NL' s - 意识到在这个具体示例中可能不是这种情况)
NL2 : ('\r')?'\n' -> type(NL);
2)然后,只需要进行一些清理:
NL : Nl;
...
NL2 : Nl;
...
fragment Nl : ('\r')?'\n' -> type(NL);
总的来说,这主要是重新安排躺椅,但它是你能做的最多的。