PageRenderTime 105ms CodeModel.GetById 96ms app.highlight 6ms RepoModel.GetById 1ms app.codeStats 0ms

/jEdit/tags/jedit-4-0-pre3/gnu/regexp/RETokenWordBoundary.java

#
Java | 85 lines | 44 code | 11 blank | 30 comment | 24 complexity | 438cd8cb20820f549397f3d35ffa3d75 MD5 | raw file
 1/*
 2 *  gnu/regexp/RETokenWordBoundary.java
 3 *  Copyright (C) 2001 Wes Biggs
 4 *
 5 *  This library is free software; you can redistribute it and/or modify
 6 *  it under the terms of the GNU Lesser General Public License as published
 7 *  by the Free Software Foundation; either version 2.1 of the License, or
 8 *  (at your option) any later version.
 9 *
10 *  This library is distributed in the hope that it will be useful,
11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 *  GNU Lesser General Public License for more details.
14 *
15 *  You should have received a copy of the GNU Lesser General Public License
16 *  along with this program; if not, write to the Free Software
17 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20package gnu.regexp;
21
22/**
23 * Represents a combination lookahead/lookbehind for POSIX [:alnum:].
24 */
25final class RETokenWordBoundary extends REToken {
26    private boolean negated;
27    private int where;
28    static final int BEGIN = 1;
29    static final int END = 2;
30
31    RETokenWordBoundary(int subIndex, int where, boolean negated) {
32	super(subIndex);
33	this.where = where;
34	this.negated = negated;
35    }
36    
37    boolean match(CharIndexed input, REMatch mymatch) {
38	// Word boundary means input[index-1] was a word character
39	// and input[index] is not, or input[index] is a word character
40	// and input[index-1] was not
41	//  In the string "one two three", these positions match:
42	//  |o|n|e| |t|w|o| |t|h|r|e|e|
43	//  ^     ^ ^     ^ ^         ^
44	boolean after = false;  // is current character a letter or digit?
45	boolean before = false; // is previous character a letter or digit?
46	char ch;
47
48	// TODO: Also check REG_ANCHORINDEX vs. anchor
49	if (((mymatch.eflags & RE.REG_ANCHORINDEX) != RE.REG_ANCHORINDEX) 
50	    || (mymatch.offset + mymatch.index > mymatch.anchor)) {
51	    if ((ch = input.charAt(mymatch.index - 1)) != CharIndexed.OUT_OF_BOUNDS) {
52		before = Character.isLetterOrDigit(ch) || (ch == '_');
53	    }
54	}
55
56	if ((ch = input.charAt(mymatch.index)) != CharIndexed.OUT_OF_BOUNDS) {
57	    after = Character.isLetterOrDigit(ch) || (ch == '_');
58	}
59
60	// if (before) and (!after), we're at end (\>)
61	// if (after) and (!before), we're at beginning (\<)
62	boolean doNext = false;
63
64	if ((where & BEGIN) == BEGIN) {
65	    doNext = after && !before;
66	}
67	if ((where & END) == END) {
68	    doNext ^= before && !after;
69	}
70
71	if (negated) doNext = !doNext;
72
73	return (doNext ? next(input, mymatch) : false);
74    }
75    
76    void dump(StringBuffer os) {
77	if (where == (BEGIN | END)) {
78	    os.append( negated ? "\\B" : "\\b" );
79	} else if (where == BEGIN) {
80	    os.append("\\<");
81	} else {
82	    os.append("\\>");
83	}
84    }
85}