如何根据ANTLR4中的关键字跳过输入
我是antlr4的新手,不知道它是否能满足我的需求。以下是一个输入示例:如何根据ANTLR4中的关键字跳过输入,antlr4,grammar,keyword,skip,Antlr4,Grammar,Keyword,Skip,我是antlr4的新手,不知道它是否能满足我的需求。以下是一个输入示例: There is a lot of text in this file that i do not care about Lithium 20 g/ml Bor that should be skipped Potassium 300g/ml ... 和代码: SempredParser.g4 parser grammar SempredParser; options { tokenVocab=SempredLex
There is a lot of text
in this file that i do not care
about
Lithium 20 g/ml
Bor that should be skipped
Potassium 300g/ml
...
和代码:
SempredParser.g4
parser grammar SempredParser;
options { tokenVocab=SempredLexer ;}
file : line+ EOF;
line : KEYWORD (NUM UNIT)+ '\n'+;
SempredLexer.g4:
lexer grammar SempredLexer;
//lexer rules
KEYWORD : ('Lithium' | 'Potassium' ) ;
NL : '\n';
NUM : [0-9]+ ('.'[0-9]+)? ;
UNIT : 'g/ml';
UNKNOWN : . -> skip ;
我想跳过所有不包含关键字的行(我有大约100个关键字)。请注意,我在这里仅使用“\n”作为分隔符,理想情况下不会将其解析为输出
我在《权威指南》中读到了有关岛屿语法的内容,也尝试过使用lexer模式,但无法做到这一点。非常感谢您的任何提示和帮助。您已经非常接近了,请避免定义两次换行标记。此语法适合我(我将其放入一个组合语法文件): 您的输入为我提供了以下解析树:
另外请注意:您无法避免输出中的NL标记,因为您决定基于
行
解析规则行,这需要换行标记。我将首先将输入拆分为行,并过滤掉包含任何关键字的行,甚至不使用ANTLR。之后,您可以将找到的行提供给解析器以获取详细信息。我想这应该会限制解析所需的输入,甚至可以在不匿名跳过任何内容的情况下工作。实际上,我以前就是这样做的,使用正则表达式而不是ANTLR。我很好奇,难道岛屿语法不完全满足我的要求吗?“…岛屿语言,其句子中有许多有趣的部分,这些部分被我们不关心的东西包围着。”是的,这是一个解决方案,但它能更快地去除不必要的赘肉,而不是通过lexer+解析器免费提供。当然取决于有用/全部输入的比率。但是,除非无用的东西非常小,否则我总是只通过解析管道发送带有有趣输入的行。减少CPU周期的浪费,我明白你的意思。对我来说,这更多的是关于ANTLR的学习经验,而不是现在的效率。谢谢你告诉我我走在了正确的轨道上。现在,这个示例工作了,我开始使用真实输入。我一直在努力解决的一件事是,显然所有找到的标记都需要被解析器使用。我最初认为我可以挑选我感兴趣的。顺便说一句,你是怎么做这个很棒的解析树的?是的,lexer必须使用所有的输入,如果它看到一些不存在规则的东西,它会给你一个错误。这就是为什么我不喜欢使用lexer跳过不需要的输入的原因之一。解析树可视化是由我的Visual Studio代码扩展为ANTL4:生成的。
grammar IslandTest;
start: NL+ line+ EOF;
line: KEYWORD (NUM UNIT)+ NL+;
KEYWORD: ('Lithium' | 'Potassium');
NUM: [0-9]+ ('.' [0-9]+)?;
UNIT: 'g/ml';
NL: '\n';
UNKNOWN: . -> skip;