001: /* Copyright (c) 2006, Sun Microsystems, Inc.
002: * All rights reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * * Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: * * Redistributions in binary form must reproduce the above copyright
010: * notice, this list of conditions and the following disclaimer in the
011: * documentation and/or other materials provided with the distribution.
012: * * Neither the name of the Sun Microsystems, Inc. nor the names of its
013: * contributors may be used to endorse or promote products derived from
014: * this software without specific prior written permission.
015: *
016: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
017: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
018: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
019: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
020: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
021: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
022: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
023: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
024: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
025: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
026: * THE POSSIBILITY OF SUCH DAMAGE.
027: */
028: package org.javacc.parser;
029:
030: import java.util.Vector;
031:
032: /**
033: * Describes regular expressions which are choices from
034: * from among included regular expressions.
035: */
036:
037: public class RChoice extends RegularExpression {
038:
039: /**
040: * The list of choices of this regular expression. Each
041: * Vector component will narrow to RegularExpression.
042: */
043: public java.util.Vector choices = new java.util.Vector();
044:
045: public Nfa GenerateNfa(boolean ignoreCase) {
046: CompressCharLists();
047:
048: if (choices.size() == 1)
049: return ((RegularExpression) choices.elementAt(0))
050: .GenerateNfa(ignoreCase);
051:
052: Nfa retVal = new Nfa();
053: NfaState startState = retVal.start;
054: NfaState finalState = retVal.end;
055:
056: for (int i = 0; i < choices.size(); i++) {
057: Nfa temp;
058: RegularExpression curRE = (RegularExpression) choices
059: .elementAt(i);
060:
061: temp = curRE.GenerateNfa(ignoreCase);
062:
063: startState.AddMove(temp.start);
064: temp.end.AddMove(finalState);
065: }
066:
067: return retVal;
068: }
069:
070: void CompressCharLists() {
071: CompressChoices(); // Unroll nested choices
072: RegularExpression curRE;
073: RCharacterList curCharList = null;
074:
075: for (int i = 0; i < choices.size(); i++) {
076: curRE = (RegularExpression) choices.elementAt(i);
077:
078: while (curRE instanceof RJustName)
079: curRE = ((RJustName) curRE).regexpr;
080:
081: if (curRE instanceof RStringLiteral
082: && ((RStringLiteral) curRE).image.length() == 1)
083: choices.setElementAt(curRE = new RCharacterList(
084: ((RStringLiteral) curRE).image.charAt(0)), i);
085:
086: if (curRE instanceof RCharacterList) {
087: if (((RCharacterList) curRE).negated_list)
088: ((RCharacterList) curRE).RemoveNegation();
089:
090: Vector tmp = ((RCharacterList) curRE).descriptors;
091:
092: if (curCharList == null)
093: choices.setElementAt(
094: curRE = curCharList = new RCharacterList(),
095: i);
096: else
097: choices.removeElementAt(i--);
098:
099: for (int j = tmp.size(); j-- > 0;)
100: curCharList.descriptors
101: .addElement(tmp.elementAt(j));
102: }
103:
104: }
105: }
106:
107: void CompressChoices() {
108: RegularExpression curRE;
109:
110: for (int i = 0; i < choices.size(); i++) {
111: curRE = (RegularExpression) choices.elementAt(i);
112:
113: while (curRE instanceof RJustName)
114: curRE = ((RJustName) curRE).regexpr;
115:
116: if (curRE instanceof RChoice) {
117: choices.removeElementAt(i--);
118: for (int j = ((RChoice) curRE).choices.size(); j-- > 0;)
119: choices.addElement(((RChoice) curRE).choices
120: .elementAt(j));
121: }
122: }
123: }
124:
125: public void CheckUnmatchability() {
126: RegularExpression curRE;
127: int numStrings = 0;
128:
129: for (int i = 0; i < choices.size(); i++) {
130: if (!(curRE = (RegularExpression) choices.elementAt(i)).private_rexp
131: &&
132: //curRE instanceof RJustName &&
133: curRE.ordinal > 0
134: && curRE.ordinal < ordinal
135: && LexGen.lexStates[curRE.ordinal] == LexGen.lexStates[ordinal]) {
136: if (label != null)
137: JavaCCErrors.warning(this ,
138: "Regular Expression choice : "
139: + curRE.label
140: + " can never be matched as : "
141: + label);
142: else
143: JavaCCErrors
144: .warning(
145: this ,
146: "Regular Expression choice : "
147: + curRE.label
148: + " can never be matched as token of kind : "
149: + ordinal);
150: }
151:
152: if (!curRE.private_rexp && curRE instanceof RStringLiteral)
153: numStrings++;
154: }
155: }
156:
157: }
|