考虑下面的方法调用表达式:
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
。
另外,正如其中一条评论所述,我想澄清一下,唯一的输入是表达式而不是其他内容,而不是源代码(因此,没有评论或我应忽略的其他内容)。
答案 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;
}