下面的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和解析器语法中删除了键/值规则并使用CSV输入运行它,从lexer或解析器语法中移除了CSV规则并使用键/值输入运行它),它运行得很好。
Lexer语法
lexer grammar MyLexer;
COMMA : ',' -> channel(0) ;
NL : ('r')?'n' -> channel(0) ;
WS : [ trn]+ -> skip, channel(0) ;
STRING : (~[,rn])+ -> channel(0) ;
KEY : ('FirstName' | 'LastName') -> channel(1) ;
EQ : '=' -> channel(1) ;
NL2 : ('r')?'n' -> channel(1) ;
WS2 : [ trn]+ -> skip, channel(1) ;
VALUE : (~[=rn])+ -> 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语法分别放在不同的语法中。也许将它们与通用语法分析器一起使用会变得棘手。如果是,那么也拆分语法分析器。