原始
这是我第一次就stackoverflow提出问题,所以我希望解决方案不会太明显。我正试图使用antlr解析xml文件中的数据,为我在eclipse中创建的java程序生成可用的令牌。我只有在antlrworks IDE中使用antlr来生成我需要合并的java代码的经验。问题是,我的xml文件非常大且复杂,因此首先,我只对一次查看几个属性感兴趣。为了让事情对我来说更简单,我尝试使用filter选项来筛选并只获取与我的令牌定义匹配的数据。我意识到,只有当你分别定义解析器和lexer语法时,才能使用filter选项,但当我试图调整我的组合语法时,我突然开始出现一个又一个错误,抱怨丢失或不需要的令牌,我一直在努力理解为什么一个有效,而另一个无效。我将它们保存在同一个文件中,删除options语句并不能解决问题。
这是我的组合语法,然后是我的改编语法,如果有人能给我任何帮助或指导,我将不胜感激。
组合:
grammar dataExtract;
prog : .*;
SOF : ('<posts>');
Tag_string : ('<')(.~'>')+('>');
Tag : ('Tags="')Tag_string+('"');
WS : ( ' '
| 't'
| 'r'
| 'n'
) {$channel=HIDDEN;}
;
EOF : '</posts>';
分离:
parser grammar dataExtract;
prog : .*;
lexer grammar dataExtract
SOF : ('<posts>');
options{filter=true};
Tag_string : ('<')(.~'>')+('>');
Tag : ('Tags="')Tag_string+('"');
WS : ( ' '
| 't'
| 'r'
| 'n'
) {$channel=HIDDEN;}
;
EOF : '</posts>';
更新
谢谢你的回答,这对我来说很有意义,我离语法工作更近了,我似乎只剩下一个问题了。解析器语法似乎运行得很好,antlrworks甚至生成了一个Java类而没有抱怨,然而,当我将lexer定义保存在它自己的.g文件中时,lexer规则似乎仍然会中断,即使我定义的唯一规则是All:.*;,我收到EarlyExitException。此外,如果我理解正确,tokenVocab选项会从lexer语法中搜索令牌文件,但由于我遇到了一个错误,并且它没有生成任何代码,因此还没有创建令牌文件,因此我认为如果没有它,解析器就不应该正确生成。你知道发生了什么吗?我尝试过搜索类似的问题,但很多材料似乎断言,当在输入中没有找到符合规则的令牌时,就会导致这个错误,但由于我甚至还没有到给它输入的地步,所以不可能是这样。
在分离lexer语法和解析器语法时,ANTLR不会在生成的.java源文件的名称后附加"Lexer"
或"Parser"
。因此,在这种情况下,您应该使用唯一的名称:
解析器
parser grammar DataExtractParser;
options {
tokenVocab=DataExtractLexer;
}
...
双工器
lexer grammar DataExtractLexer;
...
此外,正如前面所提到的,明确指出解析器应该通过tokenVocab=LEXER_GRAMMAR_NAME;
选项使用什么令牌(lexer规则)。
您需要告诉解析器要使用哪个令牌集。
parser grammar dataExtract;
options
{
tokenVocab=dataExtract; // Looks for dataExtract.tokens file
}
prog : .*;