如何识别表达式是否为“方法调用”?

时间:2017-06-14 05:32:10

标签: java regex parsing antlr

考虑下面的方法调用表达式:

foo(1, 2, bar())

函数foo有三个参数,其中第三个参数是函数bar返回的值。现在假设,我需要找出括号内的表达式是否是方法调用。对于上述情况,我应该报告bar()

对于这种情况,

foo(1, foobar(0, 1), A.staticMethod(1)),

我应该报告foobar(0, 1)A.staticMethod(1),其中A是具有静态函数的类staticMethod(int)。是否存在适用于此情况的任何方法或自动防故障正则表达式?

以下是应该报告的其他案例:

new A().foo()
a.foo()        // A a = new A();
a.bar().field  // bar() returns an object here

我也愿意使用任何解析API,例如ANTLR

另外,正如其中一条评论所述,我想澄清一下,唯一的输入是表达式而不是其他内容,而不是源代码(因此,没有评论或我应忽略的其他内容)。

1 个答案:

答案 0 :(得分:0)

假设输入中没有语法错误,您可以简单地将方法调用定义为标识符([A-Za-z_]\w*),后跟带括号的参数集,并添加条件,前面没有te关键字new(因为您的语法支持实例创建)。

public static List<String> methodCalls(String input) {
    List<String> matches = new ArrayList<>();

    Pattern p = Pattern.compile("\\s*[A-Za-z_]\\w*\\s*\\(");
    Matcher m = p.matcher(input);
    while (m.find()) {
        int start = m.start();
        int end = m.end();

        if (start == 3 && input.startsWith("new") 
            || start > 3 && input.substring(start-4, start).matches("\\Wnew")) {
            // if it is preceded by the word new, it is not a method call
            continue;
        }

        int pairs = 1;
        while (end < input.length() && pairs > 0) {
            // can't just stop at the next ')'
            // since parentheses may be nested
            char c = input.charAt(end);
            if (c == '(') pairs++;
            else if (c == ')') pairs--;
            end++;
        }

        matches.add(input.substring(start, end));
    }

    return matches;
}