ANTLR4:两个通道,一个用于 CSV 格式的数据,一个用于 key/value-formatted 数据——不起作用
ANTLR4: Two channels, one for CSV-formatted data, one for key/value-formatted data -- does not work
下面的词法分析器语法包含两组规则:(1) 对 CSV 格式输入进行分词的规则,以及 (2) 对 key/value-formatted 输入进行分词的规则。对于 (1),我将令牌放在通道 (0) 上。对于 (2),我将代币放在通道 (1) 上。你看到我的词法分析器语法有什么问题吗?
下面还有一个解析器语法,它还包含两组规则:(1) 将 CSV 标记构造成解析树的规则,以及 (2) 将 key/value 标记构造成解析树的规则树。你看到我的解析器语法有什么问题吗?
当我将 ANTLR 应用于语法文件时,编译,然后 运行 使用此 CSV 输入的测试装置(带有 -gui 标志):
FirstName, LastName, Street, City, State, ZipCode
Mark,, 4460 Stuart Street, Marion Center, PA, 15759
解析树完全错误 - 该树不包含任何数据。我不知道为什么解析树是错误的。有什么建议么?我已经分别测试了每个部分(从词法分析器和解析器语法中删除了 key/value 规则,并使用 CSV 输入删除了 运行,从词法分析器和解析器语法中删除了 CSV 规则,并使用 运行 key/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 解析器需要对令牌流进行随机访问,因此不允许上下文敏感的词法分析。
我建议将两个词法分析器语法放入单独的语法中。将它们与通用解析器语法一起使用可能会变得棘手。如果是这样 - 也拆分解析器语法。
下面的词法分析器语法包含两组规则:(1) 对 CSV 格式输入进行分词的规则,以及 (2) 对 key/value-formatted 输入进行分词的规则。对于 (1),我将令牌放在通道 (0) 上。对于 (2),我将代币放在通道 (1) 上。你看到我的词法分析器语法有什么问题吗?
下面还有一个解析器语法,它还包含两组规则:(1) 将 CSV 标记构造成解析树的规则,以及 (2) 将 key/value 标记构造成解析树的规则树。你看到我的解析器语法有什么问题吗?
当我将 ANTLR 应用于语法文件时,编译,然后 运行 使用此 CSV 输入的测试装置(带有 -gui 标志):
FirstName, LastName, Street, City, State, ZipCode
Mark,, 4460 Stuart Street, Marion Center, PA, 15759
解析树完全错误 - 该树不包含任何数据。我不知道为什么解析树是错误的。有什么建议么?我已经分别测试了每个部分(从词法分析器和解析器语法中删除了 key/value 规则,并使用 CSV 输入删除了 运行,从词法分析器和解析器语法中删除了 CSV 规则,并使用 运行 key/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 解析器需要对令牌流进行随机访问,因此不允许上下文敏感的词法分析。
我建议将两个词法分析器语法放入单独的语法中。将它们与通用解析器语法一起使用可能会变得棘手。如果是这样 - 也拆分解析器语法。