-1

Lets say I have a string that holds a method invocation for some c-ish language:

var codeLine = 'method1(var1, var2, method2(var3, method3(var4, var5)),var6);';

What is the easiest way to count the number of parameters being passed into the top level function (method1)?

In the example above, I would be looking for the result of 4.

I also need this solution to function properly if the method is not complete (imagine it's being typed):

method1(var1, var2, method2(var3, meth

Would return 3.

I understand there the 'proper' way to do this would be to parse the language using a tool like antlr, but I'm hoping there is a quick and easy solution for this.

If your curious, this is for a vscode extension that's providing signature help support

Update:

Took a stab at it...

function findTopLevelParamCount(s){
    //trim top level function away
    s = s.substr(s.indexOf('(')+1,s.lastIndexOf(')')-s.indexOf('(')-1);
    console.log(s);
    while(s.indexOf('(') >= 0){
       s = s.substr(0,s.indexOf('(')) + (s.indexOf(')')==-1?'':s.substr(s.lastIndexOf(')')+1));
       console.log(s);
    }
    return s.split(',').length;
}

var code = 'method1(var1, var2, method2(var3, method3(var4, var5)), var6);';
console.log(findTopLevelParamCount(code));

Doesn't work if the signature isn't complete. Also breaks with parethsis groupings like method1(var1, (var1-va2)).

NSjonas
  • 10,693
  • 9
  • 66
  • 92
  • 1
    i know my title kinda sucks... its hard to describe problems that involve programming language concepts – NSjonas Mar 22 '17 at 07:10
  • Why would this question get a downvote? The problem statement is clear and I listed great details into what I had already tried. And @DouglasDaseeco why did you delete your answer? It added to the question and someone else might find it helpful? – NSjonas Mar 24 '17 at 20:35
  • @FauChristian what are you talking about? I'm not asking for a "parser". I specifically asked for a quick and dirty way to count the number of occurrence of a very simple grammar that I have defined well enough. The question is asking how to solve a VERY specific problem. Last time I checked that was well within the guidelines for SO. Do you take this over-designing approach to all the work you do? Why is stack overflow so toxic these days? – NSjonas Mar 25 '17 at 17:34
  • also, the fact that @brandon was able to provide a complete answer is an obvious indication that the question is valid. – NSjonas Mar 25 '17 at 17:35

1 Answers1

2

/**
 * parse param count from string by specific level
 * @param  String str     string to be parsed
 * @param  Number level   function call level, default as 1(top)
 * @return Number         param count
 */
function parseParamCount(str, level){
  level = level || 1;
  var ary = str.split(',');
  var tokenLevel = 0;
  var count = 0;
  for(var i = 0, l = ary.length; i < l; i ++){
    var token = ary[i];
    // calc ')' length in token, then increase level by that
    var startBracketMatch = token.match(/\(/g);
    if(startBracketMatch){
      if(tokenLevel <= level)count++;
      tokenLevel += startBracketMatch.length;
    }else{
      if(tokenLevel === level)count ++;
    } 
    
    // calc ')' length in token, then decrease level by that
    var endBracketMatch = token.match(/\)/g);
    if(endBracketMatch){
      tokenLevel -= endBracketMatch.length;
    }
  }
  return count;
}

var test1 = 'method1(var1, var2, method2(var3, method3(var4, var5)),var6);';
var test2 = 'method1(var1, var2, method2(var3, meth';
var test3 = 'method1(method2(name), aaa)';

console.log(parseParamCount(test1));
console.log(parseParamCount(test2));
console.log(parseParamCount(test3));

Just have a try

Updated for test3.

Bandon
  • 809
  • 1
  • 6
  • 14