我想确定函数的字符串表示,函数具有多少个参数(顶级)。例如:
(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;
}