[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