字符串匹配哪个规则?

Which rule does the string match?

我正在使用 https://github.com/antlr/grammars-v4/tree/master/java/java

中定义的 Java 语法

我的用户可以自由输入任何东西,例如

assert image != null;

,

public Color[][] smooth(Color[][] image, int neighberhoodSize)
{   
    ...
}

,

package myapplication.mylibrary;

,以及

import static java.lang.System.out; //'out' is a static field in java.lang.System
import static screen.ColorName.*;

我的程序应该告诉输入匹配的语法。

我目前的情况是

var stream = CharStreams.fromString(input);
ITokenSource lexer = new JavaLexer(stream);

ITokenStream tokens = new CommonTokenStream(lexer);
Parser parser = new JavaParser(tokens);
parser.ErrorHandler = new BailErrorStrategy();

try
{
    var tree = parser.statement();
    Console.WriteLine("The input is a statement");
}
catch (Exception e)
{
    Console.WriteLine("The input is not a statement");
}

是否有更好的方法来检查输入匹配 100 条规则中的任何一条?

不,除了反复试验别无他法。请注意,您生成的解析器具有 属性:

public static final String[] ruleNames

您可以将其与反射结合使用以自动调用所有解析器规则,而无需手动尝试。

此外,尝试 parser.statement() 可能还不够:输入 String s = "mu"; FUBAR 可以被 parser.statement() 正确解析并留下尾随 IdentifierFUBAR ) 在令牌流中。毕竟,statement 规则可能不会以 EOF 标记结束,迫使解析器使用所有标记。在确定输入已被特定解析器规则成功解析之前,您可能必须手动检查是否所有令牌都已使用。另请参阅此问答:

除非你真的意味着你的用户可以输入任何东西(我怀疑,经过一些思考,这并不是真正的例)

您可以添加一个解析器规则,其中包含您的用户可以输入的每个构造的备选方案。您可能需要稍微注意一下订单。

由于解析器规则是递归下降评估的,如果您的新规则没有被任何其他规则引用,它不会对语法的其余部分产生影响。

值得一试。