private void parseCharClassValEntry2(CClassNode cc, CCStateArg arg) {
cc.nextStateValue(arg, env);
}
private Node parseEnclose(TokenType term) {
Node node = null;
if (!left()) newSyntaxException(ERR_END_PATTERN_WITH_UNMATCHED_PARENTHESIS);
int option = env.option;
if (peekIs('?') && syntax.op2QMarkGroupEffect()) {
inc();
if (!left()) newSyntaxException(ERR_END_PATTERN_IN_GROUP);
boolean listCapture = false;
fetch();
switch(c) {
case ':': /* (?:...) grouping only */
fetchToken(); // group:
node = parseSubExp(term);
returnCode = 1; /* group */
return node;
case '=':
node = new AnchorNode(AnchorType.PREC_READ);
break;
case '!': /* preceding read */
node = new AnchorNode(AnchorType.PREC_READ_NOT);
if (syntax.op2OptionECMAScript()) {
env.pushPrecReadNotNode(node);
}
break;
case '>': /* (?>...) stop backtrack */
node = new EncloseNode(EncloseType.STOP_BACKTRACK); // node_new_enclose
break;
case '\'':
if (Config.USE_NAMED_GROUP) {
if (syntax.op2QMarkLtNamedGroup()) {
listCapture = false; // goto named_group1
node = parseEncloseNamedGroup2(listCapture);
break;
} else {
newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
}
} // USE_NAMED_GROUP
break;
case '<': /* look behind (?<=...), (?<!...) */
fetch();
if (c == '=') {
node = new AnchorNode(AnchorType.LOOK_BEHIND);
} else if (c == '!') {
node = new AnchorNode(AnchorType.LOOK_BEHIND_NOT);
} else {
if (Config.USE_NAMED_GROUP) {
if (syntax.op2QMarkLtNamedGroup()) {
unfetch();
c = '<';
listCapture = false; // named_group1:
node = parseEncloseNamedGroup2(listCapture); // named_group2:
break;
} else {
newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
}
} else { // USE_NAMED_GROUP
newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
} // USE_NAMED_GROUP
}
break;
case '@':
if (syntax.op2AtMarkCaptureHistory()) {
if (Config.USE_NAMED_GROUP) {
if (syntax.op2QMarkLtNamedGroup()) {
fetch();
if (c == '<' || c == '\'') {
listCapture = true;
node = parseEncloseNamedGroup2(listCapture); // goto named_group2 /* (?@<name>...) */
}
unfetch();
}
} // USE_NAMED_GROUP
EncloseNode en = new EncloseNode(env.option, false); // node_new_enclose_memory
int num = env.addMemEntry();
if (num >= BitStatus.BIT_STATUS_BITS_NUM) newValueException(ERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY);
en.regNum = num;
node = en;
} else {
newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
}
break;
// case 'p': #ifdef USE_POSIXLINE_OPTION
case '-':
case 'i':
case 'm':
case 's':
case 'x':
boolean neg = false;
while (true) {
switch(c) {
case ':':
case ')':
break;
case '-':
neg = true;
break;
case 'x':
option = bsOnOff(option, Option.EXTEND, neg);
break;
case 'i':
option = bsOnOff(option, Option.IGNORECASE, neg);
break;
case 's':
if (syntax.op2OptionPerl()) {
option = bsOnOff(option, Option.MULTILINE, neg);
} else {
newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
}
break;
case 'm':
if (syntax.op2OptionPerl()) {
option = bsOnOff(option, Option.SINGLELINE, !neg);
} else if (syntax.op2OptionRuby()) {
option = bsOnOff(option, Option.MULTILINE, neg);
} else {
newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
}
break;
// case 'p': #ifdef USE_POSIXLINE_OPTION // not defined
// option = bsOnOff(option, Option.MULTILINE|Option.SINGLELINE, neg);
// break;
default:
newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
} // switch
if (c == ')') {
EncloseNode en = new EncloseNode(option, 0); // node_new_option
node = en;
returnCode = 2; /* option only */
return node;
} else if (c == ':') {
int prev = env.option;
env.option = option;
fetchToken();
Node target = parseSubExp(term);
env.option = prev;
EncloseNode en = new EncloseNode(option, 0); // node_new_option
en.setTarget(target);
node = en;
returnCode = 0;
return node;
}
if (!left()) newSyntaxException(ERR_END_PATTERN_IN_GROUP);
fetch();
} // while
default:
newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
} // switch
} else {
if (isDontCaptureGroup(env.option)) {
fetchToken(); // goto group
node = parseSubExp(term);
returnCode = 1; /* group */
return node;
}
EncloseNode en = new EncloseNode(env.option, false); // node_new_enclose_memory
int num = env.addMemEntry();
en.regNum = num;
node = en;
}
fetchToken();
Node target = parseSubExp(term);
if (node.getType() == NodeType.ANCHOR) {
AnchorNode an = (AnchorNode) node;
an.setTarget(target);
if (syntax.op2OptionECMAScript() && an.type == AnchorType.PREC_READ_NOT) {