int closure(int[] flags) throws RESyntaxException {
  int idxBeforeTerminal=idx;
  int[] terminalFlags={NODE_NORMAL};
  int ret=terminal(terminalFlags);
  flags[0]|=terminalFlags[0];
  if (idx >= len) {
    return ret;
  }
  boolean greedy=true;
  char closureType=pattern.charAt(idx);
switch (closureType) {
case '?':
case '*':
    flags[0]|=NODE_NULLABLE;
case '+':
  idx++;
case '{':
int opcode=instruction[ret];
if (opcode == RE.OP_BOL || opcode == RE.OP_EOL) {
syntaxError("Bad closure operand");
}
if ((terminalFlags[0] & NODE_NULLABLE) != 0) {
syntaxError("Closure operand can't be nullable");
}
}
if (idx < len && pattern.charAt(idx) == '?') {
idx++;
greedy=false;
}
if (greedy) {
switch (closureType) {
case '{':
{
bracket();
int bracketEnd=idx;
int bracketMin=this.bracketMin;
int bracketOpt=this.bracketOpt;
int pos=ret;
for (int c=0; c < bracketMin; c++) {
idx=idxBeforeTerminal;
setNextOfEnd(pos,pos=terminal(terminalFlags));
}
if (bracketOpt == bracketUnbounded) {
idx=bracketEnd;
nodeInsert(RE.OP_STAR,0,pos);
setNextOfEnd(pos + RE.nodeSize,pos);
break;
}
 else if (bracketOpt > 0) {
int opt[]=new int[bracketOpt + 1];
nodeInsert(RE.OP_MAYBE,0,pos);
opt[0]=pos;
for (int c=1; c < bracketOpt; c++) {
  opt[c]=node(RE.OP_MAYBE,0);
  idx=idxBeforeTerminal;
  terminal(terminalFlags);
}
int end=opt[bracketOpt]=node(RE.OP_NOTHING,0);
for (int c=0; c < bracketOpt; c++) {
  setNextOfEnd(opt[c],end);
  setNextOfEnd(opt[c] + RE.nodeSize,opt[c + 1]);
}
}
 else {
lenInstruction=pos;
node(RE.OP_NOTHING,0);
}
idx=bracketEnd;
break;
}
case '?':
{
nodeInsert(RE.OP_MAYBE,0,ret);
int n=node(RE.OP_NOTHING,0);
setNextOfEnd(ret,n);
setNextOfEnd(ret + RE.nodeSize,n);
break;
}
case '*':
{
nodeInsert(RE.OP_STAR,0,ret);
setNextOfEnd(ret + RE.nodeSize,ret);
break;
}
case '+':
{
nodeInsert(RE.OP_CONTINUE,0,ret);
int n=node(RE.OP_PLUS,0);
setNextOfEnd(ret + RE.nodeSize,n);
setNextOfEnd(n,ret);
break;
}
}
}
 else {
switch (closureType) {
case '?':
{
nodeInsert(RE.OP_RELUCTANTMAYBE,0,ret);
int n=node(RE.OP_NOTHING,0);
setNextOfEnd(ret,n);
setNextOfEnd(ret + RE.nodeSize,n);
break;
}
case '*':
{
nodeInsert(RE.OP_RELUCTANTSTAR,0,ret);
setNextOfEnd(ret + RE.nodeSize,ret);
break;
}
case '+':
{
nodeInsert(RE.OP_CONTINUE,0,ret);
int n=node(RE.OP_RELUCTANTPLUS,0);
setNextOfEnd(n,ret);
setNextOfEnd(ret + RE.nodeSize,n);
break;
}
}
}
return ret;
}

int closure ( int [ ] flags ) throws RESyntaxException { int idxBeforeTerminal = idx ; int [ ] terminalFlags = { NODE_NORMAL } ; int ret = terminal ( terminalFlags ) ; flags [ 0 ] |= terminalFlags [ 0 ] ; if ( idx >= len ) { return ret ; } boolean greedy = true ; char closureType = pattern . charAt ( idx ) ; switch ( closureType ) { case '?' : case '*' : flags [ 0 ] |= NODE_NULLABLE ; case '+' : idx ++ ; case '{' : int opcode = instruction [ ret ] ; if ( opcode == RE . OP_BOL || opcode == RE . OP_EOL ) { syntaxError ( "Bad closure operand" ) ; } if ( ( terminalFlags [ 0 ] & NODE_NULLABLE ) != 0 ) { syntaxError ( "Closure operand can't be nullable" ) ; } } if ( idx < len && pattern . charAt ( idx ) == '?' ) { idx ++ ; greedy = false ; } if ( greedy ) { switch ( closureType ) { case '{' : { bracket ( ) ; int bracketEnd = idx ; int bracketMin = this . bracketMin ; int bracketOpt = this . bracketOpt ; int pos = ret ; for ( int c = 0 ; c < bracketMin ; c ++ ) { idx = idxBeforeTerminal ; setNextOfEnd ( pos , pos = terminal ( terminalFlags ) ) ; } if ( bracketOpt == bracketUnbounded ) { idx = bracketEnd ; nodeInsert ( RE . OP_STAR , 0 , pos ) ; setNextOfEnd ( pos + RE . nodeSize , pos ) ; break ; } else if ( bracketOpt > 0 ) { int opt [ ] = new int [ bracketOpt + 1 ] ; nodeInsert ( RE . OP_MAYBE , 0 , pos ) ; opt [ 0 ] = pos ; for ( int c = 1 ; c < bracketOpt ; c ++ ) { opt [ c ] = node ( RE . OP_MAYBE , 0 ) ; idx = idxBeforeTerminal ; terminal ( terminalFlags ) ; } int end = opt [ bracketOpt ] = node ( RE . OP_NOTHING , 0 ) ; for ( int c = 0 ; c < bracketOpt ; c ++ ) { setNextOfEnd ( opt [ c ] , end ) ; setNextOfEnd ( opt [ c ] + RE . nodeSize , opt [ c + 1 ] ) ; } } else { lenInstruction = pos ; node ( RE . OP_NOTHING , 0 ) ; } idx = bracketEnd ; break ; } case '?' : { nodeInsert ( RE . OP_MAYBE , 0 , ret ) ; int n = node ( RE . OP_NOTHING , 0 ) ; setNextOfEnd ( ret , n ) ; setNextOfEnd ( ret + RE . nodeSize , n ) ; break ; } case '*' : { nodeInsert ( RE . OP_STAR , 0 , ret ) ; setNextOfEnd ( ret + RE . nodeSize , ret ) ; break ; } case '+' : { nodeInsert ( RE . OP_CONTINUE , 0 , ret ) ; int n = node ( RE . OP_PLUS , 0 ) ; setNextOfEnd ( ret + RE . nodeSize , n ) ; setNextOfEnd ( n , ret ) ; break ; } } } else { switch ( closureType ) { case '?' : { nodeInsert ( RE . OP_RELUCTANTMAYBE , 0 , ret ) ; int n = node ( RE . OP_NOTHING , 0 ) ; setNextOfEnd ( ret , n ) ; setNextOfEnd ( ret + RE . nodeSize , n ) ; break ; } case '*' : { nodeInsert ( RE . OP_RELUCTANTSTAR , 0 , ret ) ; setNextOfEnd ( ret + RE . nodeSize , ret ) ; break ; } case '+' : { nodeInsert ( RE . OP_CONTINUE , 0 , ret ) ; int n = node ( RE . OP_RELUCTANTPLUS , 0 ) ; setNextOfEnd ( n , ret ) ; setNextOfEnd ( ret + RE . nodeSize , n ) ; break ; } } } return ret ; }
compile a possibly closured terminal
