如何识别表达式是否为'method invocation'?

How to identify if an expression is 'method invocation'?

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

foo(1, 2, bar())

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

对于这种情况,

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

我应该报告 foobar(0, 1)A.staticMethod(1),其中 A 是具有静态函数 staticMethod(int) 的 class。有什么方法或故障安全正则表达式适用于这种情况吗?

以下是其他应报告的情况:

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

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

此外,正如其中一条评论中提到的,我想澄清的是唯一的输入是表达式而不是其他任何东西,而不是源代码(因此,没有评论或其他我应该忽略的东西)。

假设输入中没有语法错误,您可以简单地将方法调用定义为标识符 ([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;
}