int expr(int[] flags) throws RESyntaxException {
  int paren=-1;
  int ret=-1;
  int closeParens=parens;
  if ((flags[0] & NODE_TOPLEVEL) == 0 && pattern.charAt(idx) == '(') {
    if (idx + 2 < len && pattern.charAt(idx + 1) == '?' && pattern.charAt(idx + 2) == ':') {
      paren=2;
      idx+=3;
      ret=node(RE.OP_OPEN_CLUSTER,0);
    }
 else {
      paren=1;
      idx++;
      ret=node(RE.OP_OPEN,parens++);
    }
  }
  flags[0]&=~NODE_TOPLEVEL;
  boolean open=false;
  int branch=branch(flags);
  if (ret == -1) {
    ret=branch;
  }
 else {
    setNextOfEnd(ret,branch);
  }
  while (idx < len && pattern.charAt(idx) == '|') {
    if (!open) {
      nodeInsert(RE.OP_BRANCH,0,branch);
      open=true;
    }
    idx++;
    setNextOfEnd(branch,branch=node(RE.OP_BRANCH,0));
    branch(flags);
  }
  int end;
  if (paren > 0) {
    if (idx < len && pattern.charAt(idx) == ')') {
      idx++;
    }
 else {
      syntaxError("Missing close paren");
    }
    if (paren == 1) {
      end=node(RE.OP_CLOSE,closeParens);
    }
 else {
      end=node(RE.OP_CLOSE_CLUSTER,0);
    }
  }
 else {
    end=node(RE.OP_END,0);
  }
  setNextOfEnd(ret,end);
  int currentNode=ret;
  int nextNodeOffset=instruction[currentNode + RE.offsetNext];
  while (nextNodeOffset != 0 && currentNode < lenInstruction) {
    if (instruction[currentNode] == RE.OP_BRANCH) {
      setNextOfEnd(currentNode + RE.nodeSize,end);
    }
    nextNodeOffset=instruction[currentNode + RE.offsetNext];
    currentNode+=nextNodeOffset;
  }
  return ret;
}

int expr ( int [ ] flags ) throws RESyntaxException { int paren = - 1 ; int ret = - 1 ; int closeParens = parens ; if ( ( flags [ 0 ] & NODE_TOPLEVEL ) == 0 && pattern . charAt ( idx ) == '(' ) { if ( idx + 2 < len && pattern . charAt ( idx + 1 ) == '?' && pattern . charAt ( idx + 2 ) == ':' ) { paren = 2 ; idx += 3 ; ret = node ( RE . OP_OPEN_CLUSTER , 0 ) ; } else { paren = 1 ; idx ++ ; ret = node ( RE . OP_OPEN , parens ++ ) ; } } flags [ 0 ] &= ~ NODE_TOPLEVEL ; boolean open = false ; int branch = branch ( flags ) ; if ( ret == - 1 ) { ret = branch ; } else { setNextOfEnd ( ret , branch ) ; } while ( idx < len && pattern . charAt ( idx ) == '|' ) { if ( ! open ) { nodeInsert ( RE . OP_BRANCH , 0 , branch ) ; open = true ; } idx ++ ; setNextOfEnd ( branch , branch = node ( RE . OP_BRANCH , 0 ) ) ; branch ( flags ) ; } int end ; if ( paren > 0 ) { if ( idx < len && pattern . charAt ( idx ) == ')' ) { idx ++ ; } else { syntaxError ( "Missing close paren" ) ; } if ( paren == 1 ) { end = node ( RE . OP_CLOSE , closeParens ) ; } else { end = node ( RE . OP_CLOSE_CLUSTER , 0 ) ; } } else { end = node ( RE . OP_END , 0 ) ; } setNextOfEnd ( ret , end ) ; int currentNode = ret ; int nextNodeOffset = instruction [ currentNode + RE . offsetNext ] ; while ( nextNodeOffset != 0 && currentNode < lenInstruction ) { if ( instruction [ currentNode ] == RE . OP_BRANCH ) { setNextOfEnd ( currentNode + RE . nodeSize , end ) ; } nextNodeOffset = instruction [ currentNode + RE . offsetNext ] ; currentNode += nextNodeOffset ; } return ret ; }
compile an expression with possible parens around it . paren matching is done at this level so we can tie the branch tails together .
