如何识别表达式是否为'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;
}
考虑下面的方法调用表达式:
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;
}