Parsing ANTLR4:两个通道,一个用于CSV格式的数据,一个用于键/值格式的数据——不工作

Parsing ANTLR4:两个通道,一个用于CSV格式的数据,一个用于键/值格式的数据——不工作,parsing,csv,antlr,antlr4,lexical-analysis,Parsing,Csv,Antlr,Antlr4,Lexical Analysis,下面的lexer语法包含两组规则:(1)用于标记CSV格式输入的规则,以及(2)用于标记键/值格式输入的规则。对于(1),我将令牌放在通道(0)上。对于(2),我将令牌放在通道(1)上。你觉得我的词法语法有什么问题吗 下面还有一个解析器语法,它还包含两组规则:(1)用于将CSV标记结构化为解析树的规则,以及(2)用于将键/值标记结构化为解析树的规则。你觉得我的语法分析器有什么问题吗 当我将ANTLR应用于语法文件时,使用以下CSV输入编译并运行测试装备(带有-gui标志): FirstName,

下面的lexer语法包含两组规则:(1)用于标记CSV格式输入的规则,以及(2)用于标记键/值格式输入的规则。对于(1),我将令牌放在通道(0)上。对于(2),我将令牌放在通道(1)上。你觉得我的词法语法有什么问题吗

下面还有一个解析器语法,它还包含两组规则:(1)用于将CSV标记结构化为解析树的规则,以及(2)用于将键/值标记结构化为解析树的规则。你觉得我的语法分析器有什么问题吗

当我将ANTLR应用于语法文件时,使用以下CSV输入编译并运行测试装备(带有-gui标志):

FirstName, LastName, Street, City, State, ZipCode
Mark,, 4460 Stuart Street, Marion Center, PA, 15759
解析树完全错误-该树不包含任何数据。我不知道为什么解析树是错误的。有什么建议吗?我分别测试了每个部分(从lexer和parser语法中删除了键/值规则,并使用CSV输入运行它,从lexer和parser语法中删除了CSV规则,并使用键/值输入运行它),它工作得很好

词汇语法

lexer grammar MyLexer;      

COMMA  : ','            -> channel(0) ;
NL     : ('\r')?'\n'    -> channel(0) ;
WS     : [ \t\r\n]+     -> skip, channel(0) ;
STRING : (~[,\r\n])+     -> channel(0) ;            

KEY       : ('FirstName' | 'LastName')  -> channel(1) ;
EQ        : '='                         -> channel(1) ;
NL2       : ('\r')?'\n'                 -> channel(1) ;
WS2       : [ \t\r\n]+                  -> skip, channel(1) ;
VALUE     : (~[=\r\n])+                  -> channel(1) ;
parser grammar MyParser;                

options { tokenVocab=MyLexer; }         

csv       : (header rows)+ EOF ;
header    : field (COMMA field)* NL ;
rows      : (row)* ;    
row       : field (COMMA field)* NL ;
field     : STRING | ;

keyValue  : pairs EOF ;
pairs     : (pair)+ ;
pair      : key EQ value NL2;
key       : KEY ;
value     : VALUE ; 
语法分析器

lexer grammar MyLexer;      

COMMA  : ','            -> channel(0) ;
NL     : ('\r')?'\n'    -> channel(0) ;
WS     : [ \t\r\n]+     -> skip, channel(0) ;
STRING : (~[,\r\n])+     -> channel(0) ;            

KEY       : ('FirstName' | 'LastName')  -> channel(1) ;
EQ        : '='                         -> channel(1) ;
NL2       : ('\r')?'\n'                 -> channel(1) ;
WS2       : [ \t\r\n]+                  -> skip, channel(1) ;
VALUE     : (~[=\r\n])+                  -> channel(1) ;
parser grammar MyParser;                

options { tokenVocab=MyLexer; }         

csv       : (header rows)+ EOF ;
header    : field (COMMA field)* NL ;
rows      : (row)* ;    
row       : field (COMMA field)* NL ;
field     : STRING | ;

keyValue  : pairs EOF ;
pairs     : (pair)+ ;
pair      : key EQ value NL2;
key       : KEY ;
value     : VALUE ; 

最长的令牌匹配获胜,如果两个匹配大小相等,则第一个匹配。这意味着:

STRING
包含
KEY
EQ
VALUE
,您将永远无法获得后一种类型的令牌

ANTLR解析器需要对令牌流进行随机访问,因此不允许上下文敏感的词法分析


我建议将两个lexer语法放在单独的语法中。也许将它们与通用语法分析器一起使用会变得很棘手。如果是的话,也要拆分解析器语法。

为什么要在lexer语法中使用通道?