JSFiddle - React, Tailwind, and code Playground

HTML

<html>
    <head></head>
    <body>
        <div id="test" style="padding: 10px;"></div>
    </body>
</html>

JavaScript

var operator = {
  KLEENE: "*",
  UNION: "|",
  CONCAT: ","
};

var NFA = function(par) {
  this.stack = [];
  this.op_stack = [];
  this.parent = par;

};

NFA.prototype.parse = function(pattern) {
  var done = false;
  for(var i in pattern) {
    if (done === true) {
      break;
    }
    switch(pattern.charAt(i)) {
      case "(":
        var sub_nfa = new NFA(this);
        this.stack.push(sub_nfa);
        sub_nfa.parse(pattern.substring(i+1, pattern.length));
        done = true;
        break;
      case ")":
        if (this.parent !== null) {
          test = document.getElementById("test");
            test.innerHTML = test.innerHTML + "Substring @ i: " +  pattern.substring(i, pattern.length);
          test.innerHTML = test.innerHTML + "<br />"
          test.innerHTML = test.innerHTML + "Substring @ i+1: " + pattern.substring(i+1, pattern.length);
          this.parent.parse(pattern.substring(i, pattern.length));
          done = true;
          break;
        }
      case "*":
        this.op_stack.push(operator.KLEENE);
        break;
      case "|":
        this.op_stack.push(operator.UNION);
        break;
      default:
        if(this.stack.length > 0) {
          //only push concat after we see at least one symbol
          this.op_stack.push(operator.CONCAT);        
        }
        this.stack.push(pattern.charAt(i));
    }
  }
};

var nfa = new NFA(null);
nfa.parse("(a|b)a");