001: /*
002: * Copyright (C) Chaperon. All rights reserved.
003: * -------------------------------------------------------------------------
004: * This software is published under the terms of the Apache Software License
005: * version 1.1, a copy of which has been included with this distribution in
006: * the LICENSE file.
007: */
008:
009: package net.sourceforge.chaperon.process.extended;
010:
011: import net.sourceforge.chaperon.model.extended.ExtendedGrammar;
012: import net.sourceforge.chaperon.model.extended.Pattern;
013: import net.sourceforge.chaperon.model.extended.PatternSet;
014:
015: /**
016: * This class represents a set of items, which means positions of definition, in definition. These
017: * states were used to decribes states.
018: *
019: * @author <a href="mailto:stephan@apache.org">Stephan Michels</a>
020: * @version CVS $Id: State.java,v 1.1 2004/01/04 16:49:12 benedikta Exp $
021: */
022: public class State {
023: public State next = null;
024:
025: //private Item[] items = new Item[0];
026: public Item first = null;
027: private ShiftAction[] shiftActions = new ShiftAction[0];
028: private GotoAction[] gotoActions = new GotoAction[0];
029: private LookaheadReduceAction[] lookaheadReduceActions = new LookaheadReduceAction[0];
030: private ReduceAction[] reduceActions = new ReduceAction[0];
031: private ExtendedGrammar grammar;
032:
033: public State(ExtendedGrammar grammar) {
034: this .grammar = grammar;
035: }
036:
037: public boolean addItem(Item newItem) {
038: if (first == null) {
039: first = newItem;
040: return true;
041: }
042:
043: for (Item item = first; item != null; item = item.next) {
044: if (item.equals(newItem))
045: return false;
046:
047: if (item.next == null) {
048: item.next = newItem;
049: return true;
050: }
051: }
052:
053: return true;
054: }
055:
056: public boolean isEmpty() {
057: return first == null;
058: }
059:
060: /**
061: * Compares two states.
062: *
063: * @param o Other state.
064: *
065: * @return True, if the states are equal.
066: */
067: public boolean equals(Object o) {
068: if (o instanceof State) {
069: State state = (State) o;
070:
071: for (Item item = first; item != null; item = item.next)
072: for (Item foreignItem = state.first; foreignItem != null; foreignItem = foreignItem.next) {
073: if (item.equals(foreignItem))
074: break;
075:
076: if (foreignItem.next == null)
077: return false;
078: }
079:
080: for (Item foreignItem = state.first; foreignItem != null; foreignItem = foreignItem.next)
081: for (Item item = first; item != null; item = item.next) {
082: if (item.equals(foreignItem))
083: break;
084:
085: if (item.next == null)
086: return false;
087: }
088:
089: return true;
090: }
091:
092: return false;
093: }
094:
095: public PatternSet getNextPattern() {
096: PatternSet pattern = new PatternSet();
097:
098: for (Item item = first; item != null; item = item.next)
099: if (item.position == Item.SHIFT)
100: pattern.addPattern(item.pattern);
101:
102: return pattern;
103: }
104:
105: public PatternSet getPreviousPattern() {
106: PatternSet pattern = new PatternSet();
107:
108: for (Item item = first; item != null; item = item.next)
109: if ((item.position == Item.GOTO) && (item.pattern != null))
110: pattern.addPattern(item.pattern);
111:
112: return pattern;
113: }
114:
115: /**
116: * Add a transition to this state.
117: *
118: * @param symbol Symbol, which forces a transition into another state.
119: * @param state Destination state.
120: */
121: public boolean addShiftAction(char minimum, char maximum,
122: State state) {
123: return addShiftAction(new ShiftAction(minimum, maximum, state));
124: }
125:
126: public boolean addShiftAction(ShiftAction action) {
127: for (int i = 0; i < shiftActions.length; i++) {
128: if (shiftActions[i].equals(action))
129: if (shiftActions[i].state != action.state)
130: throw new IllegalArgumentException(
131: "Already shift transition defined with different destination");
132: else
133: return false;
134:
135: // merging actions
136: if ((shiftActions[i].minimum == (action.maximum + 1))
137: && (shiftActions[i].state == action.state)) {
138: shiftActions[i] = new ShiftAction(action.minimum,
139: shiftActions[i].maximum, action.state);
140:
141: return true;
142: }
143:
144: if ((shiftActions[i].maximum == (action.minimum - 1))
145: && (shiftActions[i].state == action.state)) {
146: shiftActions[i] = new ShiftAction(
147: shiftActions[i].minimum, action.maximum,
148: action.state);
149:
150: return true;
151: }
152: }
153:
154: ShiftAction[] newShiftActions = new ShiftAction[shiftActions.length + 1];
155: System.arraycopy(shiftActions, 0, newShiftActions, 0,
156: shiftActions.length);
157: newShiftActions[shiftActions.length] = action;
158: shiftActions = newShiftActions;
159:
160: return true;
161: }
162:
163: public ShiftAction[] getShiftActions() {
164: return shiftActions;
165: }
166:
167: public ShiftAction getShiftAction(char character) {
168: for (int i = 0; i < shiftActions.length; i++)
169: if ((shiftActions[i].minimum <= character)
170: && (shiftActions[i].maximum >= character))
171: return shiftActions[i];
172:
173: return null;
174: }
175:
176: public void addGotoAction(String symbol, State state) {
177: addGotoAction(new GotoAction(symbol, state));
178: }
179:
180: public void addGotoAction(Pattern pattern, State state) {
181: addGotoAction(new GotoAction(pattern, state));
182: }
183:
184: public void addGotoAction(GotoAction action) {
185: for (int i = 0; i < gotoActions.length; i++)
186: if (gotoActions[i].equals(action))
187: if (gotoActions[i].state != action.state)
188: throw new IllegalArgumentException(
189: "Already goto transition defined with different destination");
190: else
191: return;
192:
193: GotoAction[] newGotoActions = new GotoAction[gotoActions.length + 1];
194:
195: for (int i = 0; i < gotoActions.length; i++)
196: newGotoActions[i] = gotoActions[i];
197:
198: newGotoActions[gotoActions.length] = action;
199: gotoActions = newGotoActions;
200: }
201:
202: public GotoAction[] getGotoActions() {
203: return gotoActions;
204: }
205:
206: public GotoAction getGotoAction(String symbol) {
207: for (int i = 0; i < gotoActions.length; i++)
208: if ((gotoActions[i].symbol != null)
209: && (gotoActions[i].symbol.equals(symbol)))
210: return gotoActions[i];
211:
212: return null;
213: }
214:
215: public GotoAction getGotoAction(Pattern pattern) {
216: for (int i = 0; i < gotoActions.length; i++)
217: if (gotoActions[i].pattern == pattern)
218: return gotoActions[i];
219:
220: return null;
221: }
222:
223: public GotoAction getGotoAction(ReduceAction action) {
224: if (action.symbol != null) {
225: for (int i = 0; i < gotoActions.length; i++)
226: if ((gotoActions[i].symbol != null)
227: && (gotoActions[i].symbol.equals(action.symbol)))
228: return gotoActions[i];
229: } else {
230: for (int i = 0; i < gotoActions.length; i++)
231: if (gotoActions[i].pattern == action.pattern)
232: return gotoActions[i];
233: }
234:
235: return null;
236: }
237:
238: public void addLookaheadReduceAction(char minimum, char maximum,
239: String symbol, int length) {
240: addLookaheadReduceAction(new LookaheadReduceAction(minimum,
241: maximum, symbol, length));
242: }
243:
244: public void addLookaheadReduceAction(char minimum, char maximum,
245: Pattern pattern, int length) {
246: addLookaheadReduceAction(new LookaheadReduceAction(minimum,
247: maximum, pattern, length));
248: }
249:
250: public boolean addLookaheadReduceAction(LookaheadReduceAction action) {
251: for (int i = 0; i < lookaheadReduceActions.length; i++) {
252: if (lookaheadReduceActions[i].equals(action))
253: return false;
254:
255: // merging actions
256: if (lookaheadReduceActions[i].symbol != null) {
257: if ((lookaheadReduceActions[i].minimum == (action.maximum + 1))
258: && (lookaheadReduceActions[i].symbol
259: .equals(action.symbol))
260: && (lookaheadReduceActions[i].length == action.length)) {
261: lookaheadReduceActions[i] = new LookaheadReduceAction(
262: action.minimum,
263: lookaheadReduceActions[i].maximum,
264: action.symbol, action.length);
265: return true;
266: }
267:
268: if ((lookaheadReduceActions[i].maximum == (action.minimum - 1))
269: && (lookaheadReduceActions[i].symbol
270: .equals(action.symbol))
271: && (lookaheadReduceActions[i].length == action.length)) {
272: lookaheadReduceActions[i] = new LookaheadReduceAction(
273: lookaheadReduceActions[i].minimum,
274: action.maximum, action.symbol,
275: action.length);
276: return true;
277: }
278: } else {
279: if ((lookaheadReduceActions[i].minimum == (action.maximum + 1))
280: && (lookaheadReduceActions[i].pattern == action.pattern)
281: && (lookaheadReduceActions[i].length == action.length)) {
282: lookaheadReduceActions[i] = new LookaheadReduceAction(
283: action.minimum,
284: lookaheadReduceActions[i].maximum,
285: action.pattern, action.length);
286: return true;
287: }
288:
289: if ((lookaheadReduceActions[i].maximum == (action.minimum - 1))
290: && (lookaheadReduceActions[i].pattern == action.pattern)
291: && (lookaheadReduceActions[i].length == action.length)) {
292: lookaheadReduceActions[i] = new LookaheadReduceAction(
293: lookaheadReduceActions[i].minimum,
294: action.maximum, action.pattern,
295: action.length);
296: return true;
297: }
298: }
299: }
300:
301: LookaheadReduceAction[] newLookaheadReduceActions = new LookaheadReduceAction[lookaheadReduceActions.length + 1];
302:
303: for (int i = 0; i < lookaheadReduceActions.length; i++)
304: newLookaheadReduceActions[i] = lookaheadReduceActions[i];
305:
306: newLookaheadReduceActions[lookaheadReduceActions.length] = action;
307: lookaheadReduceActions = newLookaheadReduceActions;
308: return true;
309: }
310:
311: public LookaheadReduceAction[] getLookaheadReduceActions() {
312: return lookaheadReduceActions;
313: }
314:
315: public void addReduceAction(String symbol, int length) {
316: addReduceAction(new ReduceAction(symbol, length));
317: }
318:
319: public void addReduceAction(Pattern pattern, int length) {
320: addReduceAction(new ReduceAction(pattern, length));
321: }
322:
323: public void addReduceAction(ReduceAction action) {
324: for (int i = 0; i < reduceActions.length; i++)
325: if (reduceActions[i].equals(action))
326: return;
327:
328: ReduceAction[] newReduceActions = new ReduceAction[reduceActions.length + 1];
329:
330: for (int i = 0; i < reduceActions.length; i++)
331: newReduceActions[i] = reduceActions[i];
332:
333: newReduceActions[reduceActions.length] = action;
334: reduceActions = newReduceActions;
335: }
336:
337: public ReduceAction[] getReduceActions() {
338: return reduceActions;
339: }
340:
341: /**
342: * Return a string representation of this state.
343: *
344: * @return String representation of this state.
345: */
346: public String toString() {
347: StringBuffer buffer = new StringBuffer();
348:
349: for (Item item = first; item != null; item = item.next) {
350: buffer.append(item);
351: buffer.append("\n");
352: }
353:
354: return buffer.toString();
355: }
356: }
|