[jruby-joni] 114/194: bits for absent operator
Hideki Yamane
henrich at moszumanska.debian.org
Thu Feb 1 12:04:32 UTC 2018
This is an automated email from the git hooks/post-receive script.
henrich pushed a commit to branch debian/sid
in repository jruby-joni.
commit 062a9819905038b652a24e1589d42710eb214147
Author: Marcin Mielzynski <lopx at gazeta.pl>
Date: Sun Jan 7 20:34:05 2018 +0100
bits for absent operator
---
src/org/joni/Analyser.java | 8 ++---
src/org/joni/Lexer.java | 2 +-
src/org/joni/Parser.java | 14 ++++----
src/org/joni/Syntax.java | 49 ++++++++++++++++++++++------
src/org/joni/ast/QuantifierNode.java | 2 +-
src/org/joni/constants/EncloseType.java | 1 +
src/org/joni/constants/OPCode.java | 34 ++++++++++++-------
src/org/joni/constants/OPSize.java | 3 ++
src/org/joni/constants/StackType.java | 2 ++
src/org/joni/constants/SyntaxProperties.java | 6 ++--
10 files changed, 84 insertions(+), 37 deletions(-)
diff --git a/src/org/joni/Analyser.java b/src/org/joni/Analyser.java
index 64d7790..c9b2048 100644
--- a/src/org/joni/Analyser.java
+++ b/src/org/joni/Analyser.java
@@ -413,14 +413,14 @@ final class Analyser extends Parser {
if (br.isRecursion()) break;
if (br.back[0] > env.numMem) {
- if (!syntax.op2OptionECMAScript()) newValueException(ERR_INVALID_BACKREF);
+ if (!syntax.op3OptionECMAScript()) newValueException(ERR_INVALID_BACKREF);
} else {
min = getMinMatchLength(env.memNodes[br.back[0]]);
}
for (int i=1; i<br.backNum; i++) {
if (br.back[i] > env.numMem) {
- if (!syntax.op2OptionECMAScript()) newValueException(ERR_INVALID_BACKREF);
+ if (!syntax.op3OptionECMAScript()) newValueException(ERR_INVALID_BACKREF);
} else {
int tmin = getMinMatchLength(env.memNodes[br.back[i]]);
if (min > tmin) min = tmin;
@@ -554,7 +554,7 @@ final class Analyser extends Parser {
for (int i=0; i<br.backNum; i++) {
if (br.back[i] > env.numMem) {
- if(!syntax.op2OptionECMAScript()) newValueException(ERR_INVALID_BACKREF);
+ if(!syntax.op3OptionECMAScript()) newValueException(ERR_INVALID_BACKREF);
} else {
int tmax = getMaxMatchLength(env.memNodes[br.back[i]]);
if (max < tmax) max = tmax;
@@ -1837,7 +1837,7 @@ final class Analyser extends Parser {
BackRefNode br = (BackRefNode)node;
for (int i=0; i<br.backNum; i++) {
if (br.back[i] > env.numMem) {
- if (!syntax.op2OptionECMAScript()) newValueException(ERR_INVALID_BACKREF);
+ if (!syntax.op3OptionECMAScript()) newValueException(ERR_INVALID_BACKREF);
} else {
env.backrefedMem = bsOnAt(env.backrefedMem, br.back[i]);
env.btMemStart = bsOnAt(env.btMemStart, br.back[i]);
diff --git a/src/org/joni/Lexer.java b/src/org/joni/Lexer.java
index 68fa49e..9685c6c 100644
--- a/src/org/joni/Lexer.java
+++ b/src/org/joni/Lexer.java
@@ -187,7 +187,7 @@ class Lexer extends ScannerSupport {
private void fetchEscapedValueControl() {
if (!left()) {
- if (syntax.op2OptionECMAScript()) {
+ if (syntax.op3OptionECMAScript()) {
return;
} else {
newSyntaxException(ERR_END_PATTERN_AT_CONTROL);
diff --git a/src/org/joni/Parser.java b/src/org/joni/Parser.java
index 56ae0ed..7854833 100644
--- a/src/org/joni/Parser.java
+++ b/src/org/joni/Parser.java
@@ -160,7 +160,7 @@ class Parser extends Lexer {
neg = false;
}
- if (token.type == TokenType.CC_CLOSE && !syntax.op2OptionECMAScript()) {
+ if (token.type == TokenType.CC_CLOSE && !syntax.op3OptionECMAScript()) {
if (!codeExistCheck(']', true)) newSyntaxException(ERR_EMPTY_CHAR_CLASS);
env.ccEscWarn("]");
token.type = TokenType.CHAR; /* allow []...] */
@@ -451,7 +451,7 @@ class Parser extends Lexer {
break;
case '!': /* preceding read */
node = new AnchorNode(AnchorType.PREC_READ_NOT);
- if (syntax.op2OptionECMAScript()) {
+ if (syntax.op3OptionECMAScript()) {
env.pushPrecReadNotNode(node);
}
break;
@@ -691,14 +691,14 @@ class Parser extends Lexer {
if (node.getType() == NodeType.ANCHOR) {
AnchorNode an = (AnchorNode)node;
an.setTarget(target);
- if (syntax.op2OptionECMAScript() && an.type == AnchorType.PREC_READ_NOT) {
+ if (syntax.op3OptionECMAScript() && an.type == AnchorType.PREC_READ_NOT) {
env.popPrecReadNotNode(an);
}
} else {
EncloseNode en = (EncloseNode)node;
en.setTarget(target);
if (en.type == EncloseType.MEMORY) {
- if (syntax.op2OptionECMAScript()) {
+ if (syntax.op3OptionECMAScript()) {
en.containingAnchor = env.currentPrecReadNotNode();
}
/* Don't move this to previous of parse_subexp() */
@@ -1319,7 +1319,7 @@ class Parser extends Lexer {
while (token.type == TokenType.OP_REPEAT || token.type == TokenType.INTERVAL) { // repeat:
if (isInvalidQuantifier(target)) newSyntaxException(ERR_TARGET_OF_REPEAT_OPERATOR_INVALID);
- if (!group && syntax.op2OptionECMAScript() && target.getType() == NodeType.QTFR) {
+ if (!group && syntax.op3OptionECMAScript() && target.getType() == NodeType.QTFR) {
newSyntaxException(ERR_NESTED_REPEAT_NOT_ALLOWED);
}
QuantifierNode qtfr = new QuantifierNode(token.getRepeatLower(),
@@ -1336,7 +1336,7 @@ class Parser extends Lexer {
qn = en;
}
- if (ret == 0 || (syntax.op2OptionECMAScript() && ret == 1)) {
+ if (ret == 0 || (syntax.op3OptionECMAScript() && ret == 1)) {
target = qn;
} else if (ret == 2) { /* split case: /abc+/ */
target = ConsAltNode.newListNode(target, null);
@@ -1500,7 +1500,7 @@ class Parser extends Lexer {
private Node parseBackref() {
final Node node;
- if (syntax.op2OptionECMAScript() && token.getBackrefNum() == 1 && env.memNodes != null) {
+ if (syntax.op3OptionECMAScript() && token.getBackrefNum() == 1 && env.memNodes != null) {
EncloseNode encloseNode = (EncloseNode) env.memNodes[token.getBackrefRef1()];
boolean shouldIgnore = false;
if (encloseNode != null && encloseNode.containingAnchor != null) {
diff --git a/src/org/joni/Syntax.java b/src/org/joni/Syntax.java
index 42146a6..087c730 100644
--- a/src/org/joni/Syntax.java
+++ b/src/org/joni/Syntax.java
@@ -23,16 +23,18 @@ import static org.joni.constants.MetaChar.INEFFECTIVE_META_CHAR;
import org.joni.constants.SyntaxProperties;
-public final class Syntax implements SyntaxProperties{
+public final class Syntax implements SyntaxProperties {
private final int op;
private final int op2;
+ private final int op3;
private final int behavior;
public final int options;
public final MetaCharTable metaCharTable;
- public Syntax(int op, int op2, int behavior, int options, MetaCharTable metaCharTable) {
+ public Syntax(int op, int op2, int op3, int behavior, int options, MetaCharTable metaCharTable) {
this.op = op;
this.op2 = op2;
+ this.op3 = op3;
this.behavior = behavior;
this.options = options;
this.metaCharTable = metaCharTable;
@@ -321,12 +323,16 @@ public final class Syntax implements SyntaxProperties{
return isOp2(OP2_QMARK_CAPITAL_P_NAMED_GROUP);
}
- public boolean op2OptionJava() {
- return isOp2(OP2_OPTION_JAVA);
+ protected boolean isOp3(int opm) {
+ return (op3 & opm) != 0;
}
- public boolean op2OptionECMAScript() {
- return isOp2(OP2_OPTION_ECMASCRIPT);
+ public boolean op3OptionJava() {
+ return isOp3(OP3_OPTION_JAVA);
+ }
+
+ public boolean op3OptionECMAScript() {
+ return isOp3(OP3_OPTION_ECMASCRIPT);
}
@@ -429,6 +435,8 @@ public final class Syntax implements SyntaxProperties{
OP2_ESC_CAPITAL_R_LINEBREAK | OP2_ESC_CAPITAL_K_KEEP
),
+ 0,
+
( GNU_REGEX_BV |
ALLOW_INTERVAL_LOW_ABBREV |
DIFFERENT_LEN_ALT_LOOK_BEHIND |
@@ -453,7 +461,7 @@ public final class Syntax implements SyntaxProperties{
public static final Syntax DEFAULT = RUBY;
- public static final Syntax TEST = new Syntax(RUBY.op, RUBY.op2, RUBY.behavior, RUBY.options & ~ Option.ASCII_RANGE, RUBY.metaCharTable);
+ public static final Syntax TEST = new Syntax(RUBY.op, RUBY.op2, RUBY.op3, RUBY.behavior, RUBY.options & ~ Option.ASCII_RANGE, RUBY.metaCharTable);
public static final Syntax ASIS = new Syntax(
0,
@@ -462,6 +470,8 @@ public final class Syntax implements SyntaxProperties{
0,
+ 0,
+
Option.NONE,
new MetaCharTable(
@@ -482,6 +492,8 @@ public final class Syntax implements SyntaxProperties{
0,
+ 0,
+
( Option.SINGLELINE | Option.MULTILINE ),
new MetaCharTable(
@@ -501,6 +513,8 @@ public final class Syntax implements SyntaxProperties{
0,
+ 0,
+
( CONTEXT_INDEP_ANCHORS |
CONTEXT_INDEP_REPEAT_OPS | CONTEXT_INVALID_REPEAT_OPS |
ALLOW_UNMATCHED_CLOSE_SUBEXP |
@@ -528,6 +542,8 @@ public final class Syntax implements SyntaxProperties{
OP2_ESC_GNU_BUF_ANCHOR,
+ 0,
+
ALLOW_EMPTY_RANGE_IN_CC,
Option.NONE,
@@ -553,6 +569,8 @@ public final class Syntax implements SyntaxProperties{
0,
+ 0,
+
( ALLOW_EMPTY_RANGE_IN_CC | NOT_NEWLINE_IN_NEGATIVE_CC ),
Option.NONE,
@@ -569,7 +587,11 @@ public final class Syntax implements SyntaxProperties{
public static final Syntax GnuRegex = new Syntax(
GNU_REGEX_OP,
+
+ 0,
+
0,
+
GNU_REGEX_BV,
Option.NONE,
@@ -597,6 +619,8 @@ public final class Syntax implements SyntaxProperties{
OP2_ESC_V_VTAB | OP2_ESC_U_HEX4 |
OP2_ESC_P_BRACE_CHAR_PROPERTY ),
+ 0,
+
( GNU_REGEX_BV | DIFFERENT_LEN_ALT_LOOK_BEHIND ),
(Option.SINGLELINE | Option.WORD_BOUND_ALL_RANGE | Option.WORD_BOUND_ALL_RANGE),
@@ -623,6 +647,8 @@ public final class Syntax implements SyntaxProperties{
OP2_ESC_P_BRACE_CHAR_PROPERTY |
OP2_ESC_P_BRACE_CIRCUMFLEX_NOT ),
+ 0,
+
GNU_REGEX_BV,
Option.SINGLELINE,
@@ -652,6 +678,8 @@ public final class Syntax implements SyntaxProperties{
OP2_ESC_K_NAMED_BACKREF |
OP2_ESC_G_SUBEXP_CALL ),
+ 0,
+
( GNU_REGEX_BV |
CAPTURE_ONLY_NAMED_GROUP |
ALLOW_MULTIPLEX_DEFINITION_NAME ),
@@ -680,14 +708,15 @@ public final class Syntax implements SyntaxProperties{
OP2_QMARK_GROUP_EFFECT | OP2_OPTION_PERL |
OP2_ESC_P_BRACE_CHAR_PROPERTY |
OP2_ESC_P_BRACE_CIRCUMFLEX_NOT |
- OP2_ESC_U_HEX4 | OP2_ESC_V_VTAB |
- OP2_OPTION_ECMASCRIPT ),
+ OP2_ESC_U_HEX4 | OP2_ESC_V_VTAB),
+
+ OP3_OPTION_ECMASCRIPT,
( CONTEXT_INDEP_ANCHORS |
CONTEXT_INDEP_REPEAT_OPS |
CONTEXT_INVALID_REPEAT_OPS |
ALLOW_INVALID_INTERVAL |
- BACKSLASH_ESCAPE_IN_CC |
+ BACKSLASH_ESCAPE_IN_CC |
ALLOW_DOUBLE_RANGE_OP_IN_CC |
DIFFERENT_LEN_ALT_LOOK_BEHIND ),
diff --git a/src/org/joni/ast/QuantifierNode.java b/src/org/joni/ast/QuantifierNode.java
index 78fc51e..dcc94cd 100644
--- a/src/org/joni/ast/QuantifierNode.java
+++ b/src/org/joni/ast/QuantifierNode.java
@@ -193,7 +193,7 @@ public final class QuantifierNode extends StateNode {
public int setQuantifier(Node tgt, boolean group, ScanEnvironment env, byte[]bytes, int p, int end) {
if (lower == 1 && upper == 1) {
- if (env.syntax.op2OptionECMAScript()) {
+ if (env.syntax.op3OptionECMAScript()) {
setTarget(tgt);
}
return 1;
diff --git a/src/org/joni/constants/EncloseType.java b/src/org/joni/constants/EncloseType.java
index 7927545..a0468d2 100644
--- a/src/org/joni/constants/EncloseType.java
+++ b/src/org/joni/constants/EncloseType.java
@@ -24,6 +24,7 @@ public interface EncloseType {
final int OPTION = 1<<1;
final int STOP_BACKTRACK = 1<<2;
final int CONDITION = 1<<3;
+ final int ABSENT = 1<<4;
final int ALLOWED_IN_LB = MEMORY | OPTION;
final int ALLOWED_IN_LB_NOT = OPTION;
diff --git a/src/org/joni/constants/OPCode.java b/src/org/joni/constants/OPCode.java
index 33b5cd7..01e4fae 100644
--- a/src/org/joni/constants/OPCode.java
+++ b/src/org/joni/constants/OPCode.java
@@ -121,22 +121,26 @@ public interface OPCode {
final int PUSH_LOOK_BEHIND_NOT = 83; /* (?<!...) start */
final int FAIL_LOOK_BEHIND_NOT = 84; /* (?<!...) end */
- final int CALL = 85; /* \g<name> */
- final int RETURN = 86;
- final int CONDITION = 87;
+ final int ABSENT_POS = 85; /* (?~...) start */
+ final int ABSENT = 86; /* (?~...) start of inner loop */
+ final int ABSENT_END = 87; /* (?~...) end */
- final int STATE_CHECK_PUSH = 88; /* combination explosion check and push */
- final int STATE_CHECK_PUSH_OR_JUMP = 89; /* check ok -> push, else jump */
- final int STATE_CHECK = 90; /* check only */
- final int STATE_CHECK_ANYCHAR_STAR = 91;
- final int STATE_CHECK_ANYCHAR_ML_STAR = 92;
+ final int CALL = 88; /* \g<name> */
+ final int RETURN = 89;
+ final int CONDITION = 90;
+
+ final int STATE_CHECK_PUSH = 91; /* combination explosion check and push */
+ final int STATE_CHECK_PUSH_OR_JUMP = 92; /* check ok -> push, else jump */
+ final int STATE_CHECK = 93; /* check only */
+ final int STATE_CHECK_ANYCHAR_STAR = 94;
+ final int STATE_CHECK_ANYCHAR_ML_STAR = 95;
/* no need: IS_DYNAMIC_OPTION() == 0 */
- final int SET_OPTION_PUSH = 93; /* set option and push recover option */
- final int SET_OPTION = 94; /* set option */
+ final int SET_OPTION_PUSH = 96; /* set option and push recover option */
+ final int SET_OPTION = 97; /* set option */
- final int EXACT1_IC_SB = 95; /* single byte, N = 1, ignore case */
- final int EXACTN_IC_SB = 96; /* single byte, ignore case */
+ final int EXACT1_IC_SB = 98; /* single byte, N = 1, ignore case */
+ final int EXACTN_IC_SB = 99; /* single byte, ignore case */
public final String OpCodeNames[] = Config.DEBUG_COMPILE ? new String[] {
"finish", /*OP_FINISH*/
@@ -224,6 +228,9 @@ public interface OPCode {
"look-behind", /*OP_LOOK_BEHIND*/
"push-look-behind-not", /*OP_PUSH_LOOK_BEHIND_NOT*/
"fail-look-behind-not", /*OP_FAIL_LOOK_BEHIND_NOT*/
+ "push-absent-pos", /*OP_PUSH_ABSENT_POS*/
+ "absent", /*OP_ABSENT*/
+ "absent-end", /*OP_ABSENT_END*/
"call", /*OP_CALL*/
"return", /*OP_RETURN*/
"condition", /*OP_CONDITION*/
@@ -325,6 +332,9 @@ public interface OPCode {
Arguments.SPECIAL, /*OP_LOOK_BEHIND*/
Arguments.SPECIAL, /*OP_PUSH_LOOK_BEHIND_NOT*/
Arguments.NON, /*OP_FAIL_LOOK_BEHIND_NOT*/
+ Arguments.NON, /*OP_PUSH_ABSENT_POS*/
+ Arguments.RELADDR, /*OP_ABSENT*/
+ Arguments.NON, /*OP_ABSENT_END*/
Arguments.ABSADDR, /*OP_CALL*/
Arguments.NON, /*OP_RETURN*/
Arguments.SPECIAL, /*OP_CONDITION*/
diff --git a/src/org/joni/constants/OPSize.java b/src/org/joni/constants/OPSize.java
index fa3d3c6..a872782 100644
--- a/src/org/joni/constants/OPSize.java
+++ b/src/org/joni/constants/OPSize.java
@@ -68,6 +68,9 @@ public interface OPSize {
final int CALL = (OPCODE + ABSADDR);
final int RETURN = OPCODE;
final int CONDITION = (OPCODE + MEMNUM + RELADDR);
+ final int PUSH_ABSENT_POS = OPCODE;
+ final int ABSENT = (OPCODE + RELADDR);
+ final int ABSENT_END = OPCODE;
// #ifdef USE_COMBINATION_EXPLOSION_CHECK
final int STATE_CHECK = (OPCODE + STATE_CHECK_NUM);
diff --git a/src/org/joni/constants/StackType.java b/src/org/joni/constants/StackType.java
index 4a6527c..11c8618 100644
--- a/src/org/joni/constants/StackType.java
+++ b/src/org/joni/constants/StackType.java
@@ -43,6 +43,8 @@ public interface StackType {
final int CALL_FRAME = 0x0800;
final int RETURN = 0x0900;
final int VOID = 0x0a00; /* for fill a blank */
+ final int ABSENT_POS = 0x0b00; /* for absent */
+ final int ABSENT = 0x0c00; /* absent inner loop marker */
/* stack type check mask */
final int MASK_POP_USED = 0x00ff;
diff --git a/src/org/joni/constants/SyntaxProperties.java b/src/org/joni/constants/SyntaxProperties.java
index 5ed9e00..7f75700 100644
--- a/src/org/joni/constants/SyntaxProperties.java
+++ b/src/org/joni/constants/SyntaxProperties.java
@@ -85,8 +85,10 @@ public interface SyntaxProperties {
final int OP2_QMARK_BAR_BRANCH_RESET = (1<<28); /* (?|...) */
final int OP2_QMARK_LPAREN_CONDITION = (1<<29); /* (?(cond)yes...|no...) */
final int OP2_QMARK_CAPITAL_P_NAMED_GROUP= (1<<30); /* (?P<name>...), (?P=name), (?P>name) -- Python/PCRE */
- final int OP2_OPTION_JAVA = (1<<31); /* (?idmsux), (?-idmsux) */
- final int OP2_OPTION_ECMASCRIPT = (1<<32); /* EcmaScript quirks */
+ final int OP2_QMARK_TILDE_ABSENT = (1<<31); /* (?~...) */
+
+ final int OP3_OPTION_JAVA = (1<<0); /* (?idmsux), (?-idmsux) */
+ final int OP3_OPTION_ECMASCRIPT = (1<<1); /* EcmaScript quirks */
/* syntax (behavior); */
final int CONTEXT_INDEP_ANCHORS = (1<<31); /* not implemented */
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/jruby-joni.git
More information about the pkg-java-commits
mailing list