1

I want to work out the number of statements inside a block of javascript code. This is to evaluate how short the code is for a programming challenge (if there's a better/easier way to evaluate code, I'm interested in hearing that too).

For the purposes of this evaluation, I would like to assume a statement is anything that is capable of performing an operation within it, for example:

let values = ['test 1', 'test 2'];
for(let i in values) {
    let object = {
        a: i%3,
        b: Math.floor(i/3),
        c: i*2
    };
    let another = {test: 0 || 4};
    let something = values[i];
    let otherSomething = getSomeValues(object[a], object[b]);
    setSomeValues(object[a], object[c]);
    for(let j = 0; j < 5; i++) if(i < j) break;
}

There's quite a lot of syntax to cover so ideally I would like to do this with a library if one is available - my Googling was unable to find anything very suitable.

I tried writing a regex to match all possible breaks between statements, but this is getting messy quickly:

[\n;]|\)[ \w]|[{,][\s\w]+:\s*|[{}]

Here's a link to the regexr I've been using. Breaking this down:

  • [\n;] - matches a newline or semicolon, the normal ways to start a new statement
  • \)[ \w] - matches statements following a closing bracket, e.g. if (something) return;
  • [{,][\s\w]+:\s* - matches the key of a key-value pair in an object
  • [{}] - matches opening and closing brackets of blocks

I also remove any zero-length matches as statements cannot be empty.

As I've said, ideally I would prefer a library but I wanted to ask for some opinions on my approach and if I've got most of the edge cases.

Peter Gordon
  • 1,075
  • 1
  • 18
  • 38
  • I can't imagine regex is powerful enough to cope with all cases, hence: https://stackoverflow.com/questions/14355910/javascript-parser-and-analyzer-in-c-sharp-net-4-5 – Lee Taylor Aug 21 '19 at 15:41
  • @LeeTaylor that seems to be a C# related question, can you be more specific about what you were referring to? – Peter Gordon Aug 21 '19 at 15:43
  • 1
    I doubt writing a simple regex is going to help much here. You'll need to write a parser and lexer if you want accurate results, almost certainly. Try something like [this](https://github.com/NeilFraser/JS-Interpreter). – ggorlen Aug 21 '19 at 15:44
  • @ggorlen do you know of any JS libraries that can take a block of code and output the number of statements? I had thought possibly a linter might have this functionality. – Peter Gordon Aug 21 '19 at 15:45
  • 1
    See https://esprima.org/demo/parse.html I believe this is written in js. – Lee Taylor Aug 21 '19 at 15:46
  • 2
    Well, asking for libraries is [off-topic](https://stackoverflow.com/help/on-topic) (see item #4), but I imagine there are many tools. You can google around and check out the one I mentioned above--I don't know what their names might be off the top of my head. I mainly wanted to mention that writing a regex will be very difficult and point you towards doing personal research. – ggorlen Aug 21 '19 at 15:49
  • Thanks both of you, just wanted to make sure I wasn't missing anything obvious with the regex approach. The libraries you suggested look promising, thanks for the suggestions. – Peter Gordon Aug 21 '19 at 15:52

1 Answers1

1

Since you are trying to understand a particular chunk of code and not building a library, you should check out astexplorer.net

Here is a link that displays a nicely parsed tree and if desired, you can configure the example to use alternative parsers (babel, acorn, eslint, etc).

Peter
  • 2,796
  • 1
  • 17
  • 29
  • 1
    Thanks, pointing me in the direction of ASTs (abstract syntax trees) was very helpful. I ended up using [esprima](https://esprima.readthedocs.io/en/4.0/getting-started.html#using-esprima-in-a-web-browser) to parse the submitted code and count the elements by iterating through the tree produced. – Peter Gordon Aug 22 '19 at 13:26