Merged gcj-eclipse branch to trunk.
From-SVN: r120621
This commit is contained in:
@@ -76,6 +76,13 @@ public interface CharIndexed {
|
||||
*/
|
||||
boolean move(int index);
|
||||
|
||||
/**
|
||||
* Shifts the input buffer by a given number of positions. Returns
|
||||
* true if the new cursor position is valid or cursor position is at
|
||||
* the end of input.
|
||||
*/
|
||||
boolean move1(int index); // I cannot think of a better name for this.
|
||||
|
||||
/**
|
||||
* Returns true if the most recent move() operation placed the cursor
|
||||
* position at a valid position in the input.
|
||||
@@ -104,6 +111,16 @@ public interface CharIndexed {
|
||||
*/
|
||||
REMatch getLastMatch();
|
||||
|
||||
/**
|
||||
* Sets the information used for hitEnd().
|
||||
*/
|
||||
void setHitEnd(REMatch match);
|
||||
|
||||
/**
|
||||
* Returns whether the matcher has hit the end of input.
|
||||
*/
|
||||
boolean hitEnd();
|
||||
|
||||
/**
|
||||
* Returns the anchor.
|
||||
*/
|
||||
|
||||
@@ -62,6 +62,10 @@ class CharIndexedCharSequence implements CharIndexed, Serializable {
|
||||
return ((anchor += index) < len);
|
||||
}
|
||||
|
||||
public boolean move1(int index) {
|
||||
return ((anchor += index) <= len);
|
||||
}
|
||||
|
||||
public CharIndexed lookBehind(int index, int length) {
|
||||
if (length > (anchor + index)) length = anchor + index;
|
||||
return new CharIndexedCharSequence(s, anchor + index - length);
|
||||
@@ -77,6 +81,15 @@ class CharIndexedCharSequence implements CharIndexed, Serializable {
|
||||
lastMatch.anchor = anchor;
|
||||
}
|
||||
public REMatch getLastMatch() { return lastMatch; }
|
||||
|
||||
private int rightmostTriedPosition = 0;
|
||||
public void setHitEnd(REMatch match) {
|
||||
int pos = anchor + match.index;
|
||||
if (pos > rightmostTriedPosition) rightmostTriedPosition = pos;
|
||||
}
|
||||
public boolean hitEnd() { return rightmostTriedPosition >= len; }
|
||||
|
||||
public int getAnchor() { return anchor; }
|
||||
public void setAnchor(int anchor) { this.anchor = anchor; }
|
||||
|
||||
}
|
||||
|
||||
@@ -166,6 +166,16 @@ class CharIndexedInputStream implements CharIndexed {
|
||||
"difficult to support getLastMatch for an input stream");
|
||||
}
|
||||
|
||||
public void setHitEnd(REMatch match) {
|
||||
throw new UnsupportedOperationException(
|
||||
"difficult to support setHitEnd for an input stream");
|
||||
}
|
||||
|
||||
public boolean hitEnd() {
|
||||
throw new UnsupportedOperationException(
|
||||
"difficult to support hitEnd for an input stream");
|
||||
}
|
||||
|
||||
public int getAnchor() {
|
||||
throw new UnsupportedOperationException(
|
||||
"difficult to support getAnchor for an input stream");
|
||||
@@ -176,6 +186,10 @@ class CharIndexedInputStream implements CharIndexed {
|
||||
"difficult to support setAnchor for an input stream");
|
||||
}
|
||||
|
||||
public boolean move1(int index) {
|
||||
throw new UnsupportedOperationException(
|
||||
"difficult to support move1 for an input stream");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -130,7 +130,11 @@ public class RE extends REToken {
|
||||
private static final String VERSION = "1.1.5-dev";
|
||||
|
||||
// The localized strings are kept in a separate file
|
||||
private static ResourceBundle messages = PropertyResourceBundle.getBundle("gnu/java/util/regex/MessagesBundle", Locale.getDefault());
|
||||
// Used by getLocalizedMessage().
|
||||
private static ResourceBundle messages;
|
||||
|
||||
// Name of the bundle that contains the localized messages.
|
||||
private static final String bundle = "gnu/java/util/regex/MessagesBundle";
|
||||
|
||||
// These are, respectively, the first and last tokens in our linked list
|
||||
// If there is only one token, firstToken == lastToken
|
||||
@@ -252,6 +256,13 @@ public class RE extends REToken {
|
||||
*/
|
||||
public static final int REG_ICASE_USASCII = 0x0800;
|
||||
|
||||
/**
|
||||
* Execution flag.
|
||||
* Do not move the position at which the search begins. If not set,
|
||||
* the starting position will be moved until a match is found.
|
||||
*/
|
||||
public static final int REG_FIX_STARTING_POSITION = 0x1000;
|
||||
|
||||
/** Returns a string representing the version of the gnu.regexp package. */
|
||||
public static final String version() {
|
||||
return VERSION;
|
||||
@@ -259,6 +270,8 @@ public class RE extends REToken {
|
||||
|
||||
// Retrieves a message from the ResourceBundle
|
||||
static final String getLocalizedMessage(String key) {
|
||||
if (messages == null)
|
||||
messages = PropertyResourceBundle.getBundle(bundle, Locale.getDefault());
|
||||
return messages.getString(key);
|
||||
}
|
||||
|
||||
@@ -1643,6 +1656,7 @@ public class RE extends REToken {
|
||||
|
||||
/* Implements abstract method REToken.match() */
|
||||
boolean match(CharIndexed input, REMatch mymatch) {
|
||||
input.setHitEnd(mymatch);
|
||||
if (firstToken == null) {
|
||||
return next(input, mymatch);
|
||||
}
|
||||
@@ -1720,15 +1734,23 @@ public class RE extends REToken {
|
||||
|
||||
REMatch getMatchImpl(CharIndexed input, int anchor, int eflags, StringBuffer buffer) {
|
||||
boolean tryEntireMatch = ((eflags & REG_TRY_ENTIRE_MATCH) != 0);
|
||||
boolean doMove = ((eflags & REG_FIX_STARTING_POSITION) == 0);
|
||||
RE re = (tryEntireMatch ? (RE) this.clone() : this);
|
||||
if (tryEntireMatch) {
|
||||
re.chain(new RETokenEnd(0, null));
|
||||
RETokenEnd reEnd = new RETokenEnd(0, null);
|
||||
reEnd.setFake(true);
|
||||
re.chain(reEnd);
|
||||
}
|
||||
// Create a new REMatch to hold results
|
||||
REMatch mymatch = new REMatch(numSubs, anchor, eflags);
|
||||
do {
|
||||
/* The following potimization is commented out because
|
||||
the matching should be tried even if the length of
|
||||
input is obviously too short in order that
|
||||
java.util.regex.Matcher#hitEnd() may work correctly.
|
||||
// Optimization: check if anchor + minimumLength > length
|
||||
if (minimumLength == 0 || input.charAt(minimumLength-1) != CharIndexed.OUT_OF_BOUNDS) {
|
||||
*/
|
||||
if (re.match(input, mymatch)) {
|
||||
REMatch best = mymatch;
|
||||
// We assume that the match that coms first is the best.
|
||||
@@ -1749,13 +1771,17 @@ public class RE extends REToken {
|
||||
input.setLastMatch(best);
|
||||
return best;
|
||||
}
|
||||
}
|
||||
/* End of the optimization commented out
|
||||
}
|
||||
*/
|
||||
mymatch.clear(++anchor);
|
||||
// Append character to buffer if needed
|
||||
if (buffer != null && input.charAt(0) != CharIndexed.OUT_OF_BOUNDS) {
|
||||
buffer.append(input.charAt(0));
|
||||
}
|
||||
} while (input.move(1));
|
||||
// java.util.regex.Matcher#hitEnd() requires that the search should
|
||||
// be tried at the end of input, so we use move1(1) instead of move(1)
|
||||
} while (doMove && input.move1(1));
|
||||
|
||||
// Special handling at end of input for e.g. "$"
|
||||
if (minimumLength == 0) {
|
||||
|
||||
@@ -307,12 +307,12 @@ public final class REMatch implements Serializable, Cloneable {
|
||||
}
|
||||
|
||||
/* The following are used for debugging purpose
|
||||
static String d(REMatch m) {
|
||||
public static String d(REMatch m) {
|
||||
if (m == null) return "null";
|
||||
else return "[" + m.index + "]";
|
||||
}
|
||||
|
||||
String substringUptoIndex(CharIndexed input) {
|
||||
public String substringUptoIndex(CharIndexed input) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (int i = 0; i < index; i++) {
|
||||
sb.append(input.charAt(i));
|
||||
|
||||
@@ -54,8 +54,6 @@ import java.util.BitSet;
|
||||
public final class RESyntax implements Serializable {
|
||||
static final String DEFAULT_LINE_SEPARATOR = System.getProperty("line.separator");
|
||||
|
||||
private static final String SYNTAX_IS_FINAL = RE.getLocalizedMessage("syntax.final");
|
||||
|
||||
private BitSet bits;
|
||||
|
||||
// true for the constant defined syntaxes
|
||||
@@ -513,7 +511,8 @@ public final class RESyntax implements Serializable {
|
||||
* @return a reference to this object for easy chaining.
|
||||
*/
|
||||
public RESyntax set(int index) {
|
||||
if (isFinal) throw new IllegalAccessError(SYNTAX_IS_FINAL);
|
||||
if (isFinal)
|
||||
throw new IllegalAccessError(RE.getLocalizedMessage("syntax.final"));
|
||||
bits.set(index);
|
||||
return this;
|
||||
}
|
||||
@@ -525,7 +524,8 @@ public final class RESyntax implements Serializable {
|
||||
* @return a reference to this object for easy chaining.
|
||||
*/
|
||||
public RESyntax clear(int index) {
|
||||
if (isFinal) throw new IllegalAccessError(SYNTAX_IS_FINAL);
|
||||
if (isFinal)
|
||||
throw new IllegalAccessError(RE.getLocalizedMessage("syntax.final"));
|
||||
bits.clear(index);
|
||||
return this;
|
||||
}
|
||||
@@ -548,7 +548,8 @@ public final class RESyntax implements Serializable {
|
||||
* @return this object for convenient chaining
|
||||
*/
|
||||
public RESyntax setLineSeparator(String aSeparator) {
|
||||
if (isFinal) throw new IllegalAccessError(SYNTAX_IS_FINAL);
|
||||
if (isFinal)
|
||||
throw new IllegalAccessError(RE.getLocalizedMessage("syntax.final"));
|
||||
lineSeparator = aSeparator;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -72,6 +72,16 @@ abstract class REToken implements Serializable, Cloneable {
|
||||
|
||||
/** Returns true if the match succeeded, false if it failed. */
|
||||
boolean match(CharIndexed input, REMatch mymatch) {
|
||||
return match(input, mymatch, false);
|
||||
}
|
||||
boolean matchFake(CharIndexed input, REMatch mymatch) {
|
||||
return match(input, mymatch, true);
|
||||
}
|
||||
|
||||
private boolean match(CharIndexed input, REMatch mymatch, boolean fake) {
|
||||
if (!fake) {
|
||||
setHitEnd(input, mymatch);
|
||||
}
|
||||
REMatch m = matchThis(input, mymatch);
|
||||
if (m == null) return false;
|
||||
if (next(input, m)) {
|
||||
@@ -81,6 +91,11 @@ abstract class REToken implements Serializable, Cloneable {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Sets whether the matching occurs at the end of input */
|
||||
void setHitEnd(CharIndexed input, REMatch mymatch) {
|
||||
input.setHitEnd(mymatch);
|
||||
}
|
||||
|
||||
/** Returns true if the match succeeded, false if it failed.
|
||||
* The matching is done against this REToken only. Chained
|
||||
* tokens are not checked.
|
||||
|
||||
@@ -58,15 +58,20 @@ final class RETokenChar extends REToken {
|
||||
}
|
||||
|
||||
REMatch matchThis(CharIndexed input, REMatch mymatch) {
|
||||
int z = ch.length;
|
||||
if (matchOneString(input, mymatch.index)) {
|
||||
mymatch.index += z;
|
||||
mymatch.index += matchedLength;
|
||||
return mymatch;
|
||||
}
|
||||
// java.util.regex.Matcher#hitEnd() requires that the length of
|
||||
// partial match be counted.
|
||||
mymatch.index += matchedLength;
|
||||
input.setHitEnd(mymatch);
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean matchOneString(CharIndexed input, int index) {
|
||||
private int matchedLength;
|
||||
private boolean matchOneString(CharIndexed input, int index) {
|
||||
matchedLength = 0;
|
||||
int z = ch.length;
|
||||
char c;
|
||||
for (int i=0; i<z; i++) {
|
||||
@@ -74,6 +79,7 @@ final class RETokenChar extends REToken {
|
||||
if (! charEquals(c, ch[i])) {
|
||||
return false;
|
||||
}
|
||||
++matchedLength;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -45,6 +45,12 @@ final class RETokenEnd extends REToken {
|
||||
private String newline;
|
||||
private boolean check_java_line_terminators;
|
||||
|
||||
/**
|
||||
* Indicates whether this token is a real one generated at compile time,
|
||||
* or a fake one temporarily added by RE#getMatchImpl.
|
||||
*/
|
||||
private boolean fake = false;
|
||||
|
||||
RETokenEnd(int subIndex,String newline) {
|
||||
super(subIndex);
|
||||
this.newline = newline;
|
||||
@@ -57,10 +63,19 @@ final class RETokenEnd extends REToken {
|
||||
this.check_java_line_terminators = b;
|
||||
}
|
||||
|
||||
void setFake(boolean fake) {
|
||||
this.fake = fake;
|
||||
}
|
||||
|
||||
int getMaximumLength() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
boolean match(CharIndexed input, REMatch mymatch) {
|
||||
if (!fake) return super.match(input, mymatch);
|
||||
return super.matchFake(input, mymatch);
|
||||
}
|
||||
|
||||
REMatch matchThis(CharIndexed input, REMatch mymatch) {
|
||||
char ch = input.charAt(mymatch.index);
|
||||
if (ch == CharIndexed.OUT_OF_BOUNDS)
|
||||
|
||||
@@ -58,6 +58,10 @@ final class RETokenEndSub extends REToken {
|
||||
return super.findMatch(input, mymatch);
|
||||
}
|
||||
|
||||
void setHitEnd(CharIndexed input, REMatch mymatch) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
void dump(StringBuffer os) {
|
||||
// handled by RE
|
||||
// But add something for debugging.
|
||||
|
||||
@@ -260,6 +260,14 @@ final class RETokenNamedProperty extends REToken {
|
||||
return new UnicodeCategoryHandler(Character.UNASSIGNED);
|
||||
if (name.equals("Lu"))
|
||||
return new UnicodeCategoryHandler(Character.UPPERCASE_LETTER);
|
||||
if (name.equals("all"))
|
||||
return new Handler()
|
||||
{
|
||||
public boolean includes(char c)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
throw new REException("unsupported name " + name, REException.REG_ESCAPE, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -120,6 +120,7 @@ final class RETokenOneOf extends REToken {
|
||||
}
|
||||
|
||||
boolean match(CharIndexed input, REMatch mymatch) {
|
||||
setHitEnd(input, mymatch);
|
||||
if (matchesOneChar) return matchOneChar(input, mymatch);
|
||||
else return matchOneRE(input, mymatch);
|
||||
}
|
||||
|
||||
@@ -38,8 +38,7 @@ exception statement from your version. */
|
||||
|
||||
package gnu.java.util.regex;
|
||||
|
||||
// import java.util.Vector;
|
||||
// import java.util.Stack;
|
||||
import java.util.ArrayList;
|
||||
|
||||
final class RETokenRepeated extends REToken {
|
||||
private REToken token;
|
||||
@@ -168,19 +167,63 @@ final class RETokenRepeated extends REToken {
|
||||
}
|
||||
}
|
||||
|
||||
private static class FindMatchControlStack extends ArrayList {
|
||||
private void push(FindMatchControl control) {
|
||||
add(control);
|
||||
}
|
||||
private FindMatchControl pop() {
|
||||
return (FindMatchControl)remove(size()-1);
|
||||
}
|
||||
private boolean empty() {
|
||||
return isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
private static class FindMatchControl {
|
||||
DoablesFinder finder;
|
||||
FindMatchControl(DoablesFinder finder) {
|
||||
this.finder = finder;
|
||||
}
|
||||
}
|
||||
|
||||
private REMatch findMatch(BacktrackStack stack) {
|
||||
// Avoid using recursive calls.
|
||||
return findMatch(stack, new FindMatchControlStack());
|
||||
}
|
||||
|
||||
private REMatch findMatch(BacktrackStack stack,
|
||||
FindMatchControlStack controlStack) {
|
||||
REMatch result = null;
|
||||
StackedInfo si = null;
|
||||
CharIndexed input = null;
|
||||
int numRepeats = 0;
|
||||
REMatch mymatch = null;
|
||||
int[] visited = null;
|
||||
DoablesFinder finder = null;
|
||||
|
||||
// Avoid using recursive calls because a match can be very long.
|
||||
|
||||
// This is the first entry point of this method.
|
||||
// If you want to call this method recursively and you need the
|
||||
// result returned, save necessary information in a FindMatchControl
|
||||
// object and push it to controlStack, then continue from this point.
|
||||
// You can check the result after exiting MAIN_LOOP.
|
||||
MAIN_LOOP0:
|
||||
while (true) {
|
||||
|
||||
// This is the second entry point of this method.
|
||||
// If you want to call this method recursively but you do not need the
|
||||
// result returned, just continue from this point.
|
||||
MAIN_LOOP:
|
||||
while (true) {
|
||||
|
||||
if (stack.empty()) return null;
|
||||
StackedInfo si = (StackedInfo)(stack.peek());
|
||||
CharIndexed input = si.input;
|
||||
int numRepeats = si.numRepeats;
|
||||
REMatch mymatch = si.match;
|
||||
int[] visited = si.visited;
|
||||
DoablesFinder finder = si.finder;
|
||||
|
||||
if (stack.empty()) break MAIN_LOOP;
|
||||
si = (StackedInfo)(stack.peek());
|
||||
input = si.input;
|
||||
numRepeats = si.numRepeats;
|
||||
mymatch = si.match;
|
||||
visited = si.visited;
|
||||
finder = si.finder;
|
||||
|
||||
if (mymatch.backtrackStack == null)
|
||||
mymatch.backtrackStack = new BacktrackStack();
|
||||
|
||||
@@ -192,12 +235,13 @@ final class RETokenRepeated extends REToken {
|
||||
m1.backtrackStack.push(new BacktrackStack.Backtrack(
|
||||
this, input, mymatch, stack));
|
||||
}
|
||||
return m1;
|
||||
result = m1;
|
||||
break MAIN_LOOP;
|
||||
}
|
||||
if (stingy) {
|
||||
continue MAIN_LOOP;
|
||||
}
|
||||
return null;
|
||||
break MAIN_LOOP;
|
||||
}
|
||||
|
||||
if (finder == null) {
|
||||
@@ -238,7 +282,8 @@ final class RETokenRepeated extends REToken {
|
||||
m1.backtrackStack.push(new BacktrackStack.Backtrack(
|
||||
this, input, mymatch, stack));
|
||||
}
|
||||
return m1;
|
||||
result = m1;
|
||||
break MAIN_LOOP;
|
||||
}
|
||||
else {
|
||||
continue MAIN_LOOP;
|
||||
@@ -247,8 +292,82 @@ final class RETokenRepeated extends REToken {
|
||||
|
||||
visited = addVisited(mymatch.index, visited);
|
||||
|
||||
TryAnotherResult taresult = tryAnother(stack, input, mymatch, numRepeats, finder, visited);
|
||||
visited = taresult.visited;
|
||||
switch (taresult.status) {
|
||||
case TryAnotherResult.TRY_FURTHER:
|
||||
controlStack.push(new FindMatchControl(
|
||||
finder));
|
||||
continue MAIN_LOOP0;
|
||||
case TryAnotherResult.RESULT_FOUND:
|
||||
result = taresult.result;
|
||||
break MAIN_LOOP;
|
||||
}
|
||||
|
||||
if (!stack.empty()) {
|
||||
stack.pop();
|
||||
}
|
||||
if (possessive) {
|
||||
stack.clear();
|
||||
}
|
||||
REMatch m1 = matchRest(input, mymatch);
|
||||
if (m1 != null) {
|
||||
if (! stack.empty()) {
|
||||
m1.backtrackStack.push(new BacktrackStack.Backtrack(
|
||||
this, input, mymatch, stack));
|
||||
}
|
||||
result = m1;
|
||||
break MAIN_LOOP;
|
||||
}
|
||||
|
||||
} // MAIN_LOOP
|
||||
|
||||
if (controlStack.empty()) return result;
|
||||
FindMatchControl control = controlStack.pop();
|
||||
if (possessive) {
|
||||
return result;
|
||||
}
|
||||
if (result != null) {
|
||||
result.backtrackStack.push(new BacktrackStack.Backtrack(
|
||||
this, input, mymatch, stack));
|
||||
return result;
|
||||
}
|
||||
|
||||
finder = control.finder;
|
||||
|
||||
TryAnotherResult taresult = tryAnother(stack, input, mymatch, numRepeats, finder, visited);
|
||||
visited = taresult.visited;
|
||||
switch (taresult.status) {
|
||||
case TryAnotherResult.TRY_FURTHER:
|
||||
controlStack.push(new FindMatchControl(
|
||||
finder));
|
||||
continue MAIN_LOOP0;
|
||||
case TryAnotherResult.RESULT_FOUND:
|
||||
return taresult.result;
|
||||
}
|
||||
continue MAIN_LOOP0;
|
||||
|
||||
} // MAIN_LOOP0
|
||||
}
|
||||
|
||||
private static class TryAnotherResult {
|
||||
REMatch result;
|
||||
int status;
|
||||
static final int RESULT_FOUND = 1;
|
||||
static final int TRY_FURTHER = 2;
|
||||
static final int NOTHING_FOUND = 3;
|
||||
int[] visited;
|
||||
}
|
||||
|
||||
private TryAnotherResult tryAnother(BacktrackStack stack,
|
||||
CharIndexed input, REMatch mymatch, int numRepeats,
|
||||
DoablesFinder finder, int[] visited) {
|
||||
|
||||
TryAnotherResult taresult = new TryAnotherResult();
|
||||
taresult.visited = visited;
|
||||
|
||||
DO_THIS:
|
||||
do {
|
||||
{
|
||||
|
||||
boolean emptyMatchFound = false;
|
||||
|
||||
@@ -263,61 +382,45 @@ final class RETokenRepeated extends REToken {
|
||||
|
||||
if (!emptyMatchFound) {
|
||||
int n = doable.index;
|
||||
if (! visitedContains(n, visited)) {
|
||||
visited = addVisited(n, visited);
|
||||
}
|
||||
else {
|
||||
if (visitedContains(n, visited)) {
|
||||
continue DO_ONE_DOABLE;
|
||||
}
|
||||
visited = addVisited(n, visited);
|
||||
stack.push(new StackedInfo(
|
||||
input, numRepeats + 1, doable, visited, null));
|
||||
REMatch m1 = findMatch(stack);
|
||||
if (possessive) {
|
||||
return m1;
|
||||
}
|
||||
if (m1 != null) {
|
||||
m1.backtrackStack.push(new BacktrackStack.Backtrack(
|
||||
this, input, mymatch, stack));
|
||||
return m1;
|
||||
}
|
||||
input, numRepeats + 1, doable, visited, null));
|
||||
taresult.visited = visited;
|
||||
taresult.status = TryAnotherResult.TRY_FURTHER;
|
||||
return taresult;
|
||||
}
|
||||
else {
|
||||
REMatch m1 = matchRest(input, doable);
|
||||
if (possessive) {
|
||||
return m1;
|
||||
taresult.result = m1;
|
||||
taresult.status = TryAnotherResult.RESULT_FOUND;
|
||||
return taresult;
|
||||
}
|
||||
if (m1 != null) {
|
||||
if (! stack.empty()) {
|
||||
m1.backtrackStack.push(new BacktrackStack.Backtrack(
|
||||
this, input, mymatch, stack));
|
||||
}
|
||||
return m1;
|
||||
}
|
||||
taresult.result = m1;
|
||||
taresult.status = TryAnotherResult.RESULT_FOUND;
|
||||
return taresult;
|
||||
}
|
||||
}
|
||||
|
||||
} // DO_ONE_DOABLE
|
||||
|
||||
} while (false); // DO_THIS only once;
|
||||
} // DO_THIS
|
||||
|
||||
if (!stack.empty()) {
|
||||
stack.pop();
|
||||
}
|
||||
if (possessive) {
|
||||
stack.clear();
|
||||
}
|
||||
REMatch m1 = matchRest(input, mymatch);
|
||||
if (m1 != null) {
|
||||
if (! stack.empty()) {
|
||||
m1.backtrackStack.push(new BacktrackStack.Backtrack(
|
||||
this, input, mymatch, stack));
|
||||
}
|
||||
return m1;
|
||||
}
|
||||
taresult.status = TryAnotherResult.NOTHING_FOUND;
|
||||
return taresult;
|
||||
|
||||
} // MAIN_LOOP
|
||||
}
|
||||
|
||||
boolean match(CharIndexed input, REMatch mymatch) {
|
||||
setHitEnd(input, mymatch);
|
||||
REMatch m1 = findMatch(input, mymatch);
|
||||
if (m1 != null) {
|
||||
mymatch.assignFrom(m1);
|
||||
|
||||
Reference in New Issue
Block a user