ANTLR 制作负面测试用例

问题描述

我是 ANTLR 的新手,正在尝试了解如何使用它做一些事情。当语句缺少分号或结束括号时,我需要它来抛出错误。我正在解决的问题集将其称为负面测试用例。

例如,下面的代码返回true,这是正确的。

val program = """
1 + 2;
"""

recognize(program)

然而,该代码也返回 true,尽管它在末尾缺少分号。它应该返回 false([PARSER error at line=1]: missing ';' at '')。

val program = """
1 + 2
""".trimIndent()

recognize(program)

语法如下:

program: (expression ';')* | EOF;

expression: INT PLUS INT | OPENBRAC INT PLUS INT CLOSEBRAC | QUOTE IDENT QUOTE PLUS QUOTE IDENT QUOTE;

IDENT: [A-Za-z0-9]+;
INT: [-][0-9]+ | ('0'..'9')+;
PLUS: '+';
OPENBRAC: '(';
CLOSEBRAC: ')';
QUOTE: '"';

解决方法

program: (expression ';')* | EOF;

这意味着程序可以是零个或多个 expression ';' 实例,后跟输入流中的任何其他内容它可以为空。由于 (expression ';')* 本身已经可以匹配空输入,因此 | EOF 只是多余的。

你想要的是program: (expression ';')* EOF,这意味着一个程序由零个或多个expression ';'实例组成,后面跟着输入的结尾,意味着必须没有任何东西之后留在输入中。