[jruby-joni] 181/279: Add IGNORE_BACKREF_PROC_READ_NOT syntax option
Hideki Yamane
henrich at moszumanska.debian.org
Mon Nov 16 11:27:28 UTC 2015
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 fbdd0c42d1eec7d958b27ad44640e3d29b1c4b45
Author: Ben Browning <bbrownin at redhat.com>
Date: Thu Sep 5 21:00:09 2013 -0400
Add IGNORE_BACKREF_PROC_READ_NOT syntax option
Setting this enables the JavaScript behavior of ignoring any
backreferences to negative lookahead captures outside of the negative
lookahead itself.
In otherwords, in a regular expression like "(.*?)a(?!(a+)b\2c)\2(.*)"
the second backreference to "\2", outside of the ?! group, is ignored.
---
src/org/joni/Parser.java | 47 +++++++++++++++++++++++-----
src/org/joni/ScanEnvironment.java | 32 +++++++++++++++++++
src/org/joni/Syntax.java | 4 +++
src/org/joni/ast/EncloseNode.java | 1 +
src/org/joni/constants/SyntaxProperties.java | 1 +
5 files changed, 78 insertions(+), 7 deletions(-)
diff --git a/src/org/joni/Parser.java b/src/org/joni/Parser.java
index f0a049b..4f9764b 100644
--- a/src/org/joni/Parser.java
+++ b/src/org/joni/Parser.java
@@ -429,6 +429,9 @@ class Parser extends Lexer {
break;
case '!': /* preceding read */
node = new AnchorNode(AnchorType.PREC_READ_NOT);
+ if (syntax.ignoreBackrefPrecReadNot()) {
+ env.pushPrecReadNotNode(node);
+ }
break;
case '>': /* (?>...) stop backtrack */
node = new EncloseNode(EncloseType.STOP_BACKTRACK); // node_new_enclose
@@ -579,10 +582,16 @@ class Parser extends Lexer {
if (node.getType() == NodeType.ANCHOR) {
AnchorNode an = (AnchorNode) node;
an.setTarget(target);
+ if (syntax.ignoreBackrefPrecReadNot() && an.type == AnchorType.PREC_READ_NOT) {
+ env.popPrecReadNotNode(an);
+ }
} else {
EncloseNode en = (EncloseNode)node;
en.setTarget(target);
if (en.type == EncloseType.MEMORY) {
+ if (syntax.ignoreBackrefPrecReadNot()) {
+ en.containingAnchor = env.currentPrecReadNotNode();
+ }
/* Don't move this to previous of parse_subexp() */
env.setMemNode(en.regNum, node);
}
@@ -750,13 +759,37 @@ class Parser extends Lexer {
break;
case BACKREF:
- int[]backRefs = token.getBackrefNum() > 1 ? token.getBackrefRefs() : new int[]{token.getBackrefRef1()};
- node = new BackRefNode(token.getBackrefNum(),
- backRefs,
- token.getBackrefByName(),
- token.getBackrefExistLevel(), // #ifdef USE_BACKREF_AT_LEVEL
- token.getBackrefLevel(), // ...
- env);
+ if (syntax.ignoreBackrefPrecReadNot() && token.getBackrefNum() == 1 && env.memNodes != null) {
+ EncloseNode encloseNode = (EncloseNode) env.memNodes[token.getBackrefRef1()];
+ boolean shouldIgnore = false;
+ if (encloseNode != null && encloseNode.containingAnchor != null) {
+ shouldIgnore = true;
+ for (Node anchorNode : env.precReadNotNodes) {
+ if (anchorNode == encloseNode.containingAnchor) {
+ shouldIgnore = false;
+ break;
+ }
+ }
+ }
+ if (shouldIgnore) {
+ node = StringNode.EMPTY;
+ } else {
+ node = new BackRefNode(token.getBackrefNum(),
+ new int[]{token.getBackrefRef1()},
+ token.getBackrefByName(),
+ token.getBackrefExistLevel(), // #ifdef USE_BACKREF_AT_LEVEL
+ token.getBackrefLevel(), // ...
+ env);
+ }
+ } else {
+ int[]backRefs = token.getBackrefNum() > 1 ? token.getBackrefRefs() : new int[]{token.getBackrefRef1()};
+ node = new BackRefNode(token.getBackrefNum(),
+ backRefs,
+ token.getBackrefByName(),
+ token.getBackrefExistLevel(), // #ifdef USE_BACKREF_AT_LEVEL
+ token.getBackrefLevel(), // ...
+ env);
+ }
break;
diff --git a/src/org/joni/ScanEnvironment.java b/src/org/joni/ScanEnvironment.java
index 02a1ad7..0dbce24 100644
--- a/src/org/joni/ScanEnvironment.java
+++ b/src/org/joni/ScanEnvironment.java
@@ -55,6 +55,9 @@ public final class ScanEnvironment {
int currMaxRegNum;
boolean hasRecursion;
+ int numPrecReadNotNodes;
+ Node precReadNotNodes[];
+
public ScanEnvironment(Regex regex, Syntax syntax) {
this.reg = regex;
option = regex.options;
@@ -80,6 +83,9 @@ public final class ScanEnvironment {
combExpMaxRegNum = 0;
currMaxRegNum = 0;
hasRecursion = false;
+
+ numPrecReadNotNodes = 0;
+ precReadNotNodes = null;
}
public int addMemEntry() {
@@ -102,6 +108,32 @@ public final class ScanEnvironment {
}
}
+ public void pushPrecReadNotNode(Node node) {
+ numPrecReadNotNodes++;
+ if (precReadNotNodes == null) {
+ precReadNotNodes = new Node[SCANENV_MEMNODES_SIZE];
+ } else if (numPrecReadNotNodes >= precReadNotNodes.length) {
+ Node[]tmp = new Node[precReadNotNodes.length << 1];
+ System.arraycopy(precReadNotNodes, 0, tmp, 0, precReadNotNodes.length);
+ precReadNotNodes = tmp;
+ }
+ precReadNotNodes[numPrecReadNotNodes - 1] = node;
+ }
+
+ public void popPrecReadNotNode(Node node) {
+ if (precReadNotNodes != null && precReadNotNodes[numPrecReadNotNodes - 1] == node) {
+ precReadNotNodes[numPrecReadNotNodes - 1] = null;
+ numPrecReadNotNodes--;
+ }
+ }
+
+ public Node currentPrecReadNotNode() {
+ if (numPrecReadNotNodes > 0) {
+ return precReadNotNodes[numPrecReadNotNodes - 1];
+ }
+ return null;
+ }
+
public int convertBackslashValue(int c) {
if (syntax.opEscControlChars()) {
switch (c) {
diff --git a/src/org/joni/Syntax.java b/src/org/joni/Syntax.java
index 774284c..89ead78 100644
--- a/src/org/joni/Syntax.java
+++ b/src/org/joni/Syntax.java
@@ -326,6 +326,10 @@ public final class Syntax implements SyntaxProperties{
return isBehavior(FIXED_INTERVAL_IS_GREEDY_ONLY);
}
+ public boolean ignoreBackrefPrecReadNot() {
+ return isBehavior(IGNORE_BACKREF_PREC_READ_NOT);
+ }
+
public boolean notNewlineInNegativeCC() {
return isBehavior(NOT_NEWLINE_IN_NEGATIVE_CC);
diff --git a/src/org/joni/ast/EncloseNode.java b/src/org/joni/ast/EncloseNode.java
index 0a07ed1..7c45d14 100644
--- a/src/org/joni/ast/EncloseNode.java
+++ b/src/org/joni/ast/EncloseNode.java
@@ -34,6 +34,7 @@ public final class EncloseNode extends StateNode implements EncloseType {
public int maxLength; // OnigDistance
public int charLength;
public int optCount; // referenced count in optimize_node_left()
+ public Node containingAnchor; //
// node_new_enclose / onig_node_new_enclose
public EncloseNode(int type) {
diff --git a/src/org/joni/constants/SyntaxProperties.java b/src/org/joni/constants/SyntaxProperties.java
index 78191ec..b31b6cb 100644
--- a/src/org/joni/constants/SyntaxProperties.java
+++ b/src/org/joni/constants/SyntaxProperties.java
@@ -88,6 +88,7 @@ public interface SyntaxProperties {
final int ALLOW_MULTIPLEX_DEFINITION_NAME = (1<<8); /* (?<x>);(?<x>); */
final int FIXED_INTERVAL_IS_GREEDY_ONLY = (1<<9); /* a{n}?=(?:a{n});? */
final int ALLOW_NESTED_REPEAT = (1<<10); /* a{0,}{1}{2} */
+ final int IGNORE_BACKREF_PREC_READ_NOT = (1<<11); /* /(?!(a+)b\2c)\2 */
/* syntax (behavior); in char class [...] */
final int NOT_NEWLINE_IN_NEGATIVE_CC = (1<<20); /* [^...] */
--
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