【问题标题】:How to identify if an expression is 'method invocation'?如何识别表达式是否为“方法调用”?
【发布时间】:2017-06-14 05:32:10
【问题描述】:

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

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

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

【问题讨论】:

  • 我认为您可以通过查找标识符和打开的括号来判断表达式的开头——尽管您会在 cmets 或字符串中遇到“代码”问题。而且您将无法找到表达式的结尾,至少不容易。所以真正的答案是,你需要一个解析器。但是如果你问如何写一个,这个问题太宽泛了,如果你要求我们提供一个链接,作为对外部资源的请求,这是题外话。无论哪种方式,这个问题对我来说似乎都过时了。您还可以编译 Java 并检查字节码。
  • a.bar().field 是方法调用吗?
  • 我已经在使用 ANTLR 开发解析器。我已经到了需要在作为参数传递时提取 method-invocation 表达式的地步,但是 Java8 语法不知何故不允许我这样做。我可以正常找到 method-invocation 表达式,但在作为参数传递给另一个方法时却找不到。 @yshavit
  • 是的。好的例子 ! @saka1029
  • @saka1029 但请确保不要将 "a.bar().field" 解析为一个!

标签: java regex parsing antlr


【解决方案1】:

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

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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-11
    • 2012-02-29
    • 1970-01-01
    相关资源
    最近更新 更多