Java仅根据功能字符串确定函数参数的量



我想确定函数的字符串表示,函数具有多少个参数(顶级)。例如:

(1) assertEquals(verify, actual);
(2) assertEquals("message", actual, verify);
(3) assertEquals(account.addMoney(19, Delivery.fast()).toString(), bank.getAccount(person.getCredentials("basic")).tally(), mock.getData().verify());

答案应为(1)= 2,(2)= 3,(3)= 3。您可以假设我有功能名称,例如断言的正则

基本上我可以计算逗号,但是我需要考虑内部功能调用的功能参数。所以

function(param1, param2.data(param3, param4, param5.getData(param6, param7));

当然,筑巢可以是任意的。

我认为正则是一个问题,但是我与他们的经历不足以解决这个问题。

请注意,我已经考虑过使用杠杆/解析器,但这对我的意图似乎有些夸张。我有一组功能作为字符串,而我的目标方法调用是断言方法。

对于这种问题,您需要词汇分析仪和解析器。

词汇分析仪将字符串分为令牌

解析将令牌构建并建立一个数据结构,通常是一棵树,它更好地表示令牌的含义。

导航该数据结构,您可以轻松找到有多少个参数。


注意:这是相同的过程,以转换由人类编写的程序,即文本文件(例如。)。


使用词汇分析仪和解析器才能正确处理以下字符串:

  • function("a,b", c)
  • function(new String[]{"a", "b"})
  • function(a(b, c))
  • function(',')

和它们的任何组成


使用Java的词汇分析仪可以是以下JFLEX。

我认为,一旦您拥有令牌,您就可以手动计算逗号和括号(现在确实是逗号和括号,而不是字符串或其他内容的一部分)

基于可能的情况,我定义了递归算法以找出函数参数的数量。请发布任何打破下面代码的角式案例:)代码适用于案件(也是递归),如Davide

所建议的
/*
 * returns the number of parameters in this function
 */
private int functionParameters(String function) {
    String fnStripped = stripTill('(', function);
    String fnStripped2 = fnStripped.substring(1);
    // find function with 0 parameters, i.e. ()
    if (removeWhiteSpace(fnStripped).length() == 2) {
        return 0;
    }
    // find function with >= 1 parameters
    return countFunctionParameters(fnStripped2);
}
/*
 * @pre: function is a string, starting from the arguments of a function, excluding the first parenthesis.
 * @pre: function has at least one parameter.
 * @post: the number of parameters of the original (top level) function.
 */
private int countFunctionParameters(String function) {
    // every function has at least one parameter
    if (function.length() == 0) {
        return 1;
    } 
    char next = function.charAt(0);
    String newString = function.substring(1);
    switch(next) {
        case ',' : return 1 + countFunctionParameters(newString);
        case '(' : newString = removeUntil(')', newString); return 0 + countFunctionParameters(newString);
        case '"' : newString = removeUntil('"', newString); return 0 + countFunctionParameters(newString);
        case ''' : newString = removeUntil(''', newString); return 0 + countFunctionParameters(newString);
        case '{' : newString = removeUntil('}', newString); return 0 + countFunctionParameters(newString);
        default : return 0 + countFunctionParameters(newString);
    }
}
private String removeUntil(char c, String str) {
    System.out.println("CURRENT: " + str);
    if (str.equals("")) {
        return str;
    }
    String newString = str.substring(1);
    if (str.charAt(0) == c) {
        return newString;
    }
    switch (str.charAt(0)) {
        case '(' : return removeUntil(c, removeUntil('(', newString));
        case '"' : return removeUntil(c, removeUntil('"', newString));
        case ''' : return removeUntil(c, removeUntil(''', newString));
        case '{' : return removeUntil(c, removeUntil('}', newString));
        case ')' : return newString;
        case '}' : return newString;
        case '\' : return removeUntil(c, newString.substring(1)); // disregard the escaped character!
        default : return removeUntil(c, newString);
    }
}
private String removeWhiteSpace(String str) {
    return str.replaceAll("\s+","");
}
private String stripTill(char c, String str) {
    while (str.charAt(0) != c) {
        str = str.substring(1);
    }
    return str;
}

最新更新