在您的语法中,您明确指出“新行”必须结束行。这里的问题是:该语言的message
部分末尾是否有“新行”?同样的问题出现在空白处。他们是语言的一部分吗?如果没有,你可以跳过它们:
WS: (' ' | '\t') -> skip;
NL: '\r'? '\n' -> skip;
然后,您可以简化message
规则:
message: timestamp id;
如果你真的需要保留行的末尾:
NL: '\r'? '\n';
而且您在message
规则的末尾添加此代币作为可选项:
message: timestamp id NL?;
这将与你的榜样工作,但会失败:
123 1231
123 1312
的两条线之间的\n
将产生错误。这似乎是最有希望的解决方案是第一个(跳过NL
和WS
与简化message
规则),但该条目将被匹配为OK:
123 1231 123 1312
这将产生两个message
规则环境。
总结一下,在您的示例中,为了给您提供构建语法的最佳方式,我们必须知道输入语言的约束条件。
<编辑>
关于你的评论,有两个解决方案。要么你确定你的文件格式良好,并且想法是无限制地提取文件的信息,或者你必须确保输入文件符合语法(为了还要删除“坏文件“)。
我很确定你在第一种情况下(就像你说你正在执行逆向工程),所以你可能想从你的文件中创建一个CST来提取信息。在这种情况下,考虑到您的输入文件总是完好无损的,您不需要费心检查在messages
的末尾是否存在NL
(通过构建,文件总是有一行message
)。在这种情况下,你可以跳过你不需要的一切。语法变成:
grammar TestGrammar;
testfile : message+ EOF;
message : timestamp id;
timestamp : NumericLiteral;
id : NumericLiteral;
NumericLiteral : INTEGER | DECIMAL;
INTEGER : [+-]? [0-9]+;
DECIMAL : [+-]? [0-9]* '.' [0-9]+;
EXPONENT : [eE] [+-]? [0-9]+;
WS: (' ' | '\t')+ -> skip;
NL: '\r'? '\n' -> skip;
此语法将认识
123 1231
123 1312
以及
123 1231
(as many as \n you want between them)
123 1312
而且
123 1231 123 1312 (-> this will produce two messages as expected)
但是,如果你的输入文件可能不形成良好,用这个语法,y你将无法排除它们。
grammar TestGrammar;
testfile : (message? NL)* message EOF;
message : timestamp id;
timestamp : NumericLiteral;
id : NumericLiteral;
WS: [\t ]+ -> skip;
NL: '\r'? '\n';
NumericLiteral : INTEGER | DECIMAL;
INTEGER : [+-]? [0-9]+;
DECIMAL : [+-]? [0-9]* '.' [0-9]+;
EXPONENT : [eE] [+-]? [0-9]+;
有了这个语法:
123 1231
(as many as \n you want between them)
123 1312
将
如果您需要确保只有一个消息是存在的线,你应该提出拉兹FRIMAN这里的语法稍加修改的版本,请被识别出来:
123 1231 123 1312
会引发错误。
感谢您的回应文森特。我以为我试过“ - >跳过”,但遇到了另一个错误消息。我会再试一次,并确认。你是对的,我们不需要保留NL字符,只是说明它们会发生。 你知道为什么我的语法报告它的错误吗?我的理解是,解析器有效地说:“错误:发现EOF,期待EOF或NL” – Anthony
我刚刚意识到你在最后要求了解关于该语言的更多细节你的建议答案; 我们正在对数据格式进行逆向工程,所以我会诚实地说,我们并不真正知道约束条件会是什么! 我们目前的理解是: 每个消息必须在其自己的行 允许将邮件 之间的空行不要求在 我们已经看到了以下的模式,所以我们的文件证据文件的末尾新行知道他们是有效的输入。 – Anthony
说实话,我不知道为什么你弹出的错误(不管'EOF'标记表达两次)。我知道在某些情况下,ANTLR会添加'EOF'标记(例如,当规则不完全匹配时),并且在某些情况下,我记得看到'EOF'标记经典标号为'-1',而其他编号为'-2'。对此缺乏细节感到抱歉:\。关于你的语言细节,我将编辑我的文章给你更多的细节。 –