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.model.grammar;
010:
011: import net.sourceforge.chaperon.model.Violations;
012: import net.sourceforge.chaperon.model.symbol.Nonterminal;
013: import net.sourceforge.chaperon.model.symbol.SymbolList;
014: import net.sourceforge.chaperon.model.symbol.SymbolSet;
015: import net.sourceforge.chaperon.model.symbol.Terminal;
016:
017: import java.io.Serializable;
018:
019: /**
020: * This class presents a production of a grammar
021: *
022: * @author <a href="mailto:stephan@apache.org">Stephan Michels</a>
023: * @version CVS $Id: Production.java,v 1.6 2003/12/09 19:55:52 benedikta Exp $
024: */
025: public class Production implements Serializable, Cloneable {
026: private Nonterminal ntsymbol = new Nonterminal("noname");
027: private SymbolList definition = new SymbolList();
028: private Terminal precedence = null;
029: private String location = null;
030:
031: /**
032: * Create an empty production.
033: */
034: public Production() {
035: }
036:
037: /**
038: * Create a production.
039: *
040: * @param ntsymbol The symbol of this production.
041: */
042: public Production(Nonterminal ntsymbol) {
043: setSymbol(ntsymbol);
044: }
045:
046: /**
047: * Create a production.
048: *
049: * @param ntsymbol The symbol of this production.
050: * @param definition Definition of the production.
051: */
052: public Production(Nonterminal ntsymbol, SymbolList definition) {
053: setSymbol(ntsymbol);
054: setDefinition(definition);
055: }
056:
057: /**
058: * Set the symbol for this production
059: *
060: * @param ntsymbol Non terminal symbol
061: */
062: public void setSymbol(Nonterminal ntsymbol) {
063: if (ntsymbol == null)
064: throw new NullPointerException();
065:
066: this .ntsymbol = ntsymbol;
067: }
068:
069: /**
070: * Return the symbol from this production
071: *
072: * @return Nonterminal symbol
073: */
074: public Nonterminal getSymbol() {
075: return ntsymbol;
076: }
077:
078: /**
079: * Set the definition for this production
080: *
081: * @param definition A list of symbols, which the definition of this production represented.
082: */
083: public void setDefinition(SymbolList definition) {
084: if (definition == null)
085: throw new NullPointerException();
086:
087: this .definition = definition;
088: }
089:
090: /**
091: * Return the definition.
092: *
093: * @return A list of Symbols, which the definition of this production represented.
094: */
095: public SymbolList getDefinition() {
096: return definition;
097: }
098:
099: /**
100: * Return the the length of the Definition
101: *
102: * @return Lengt of the Definition
103: */
104: public int getLength() {
105: return definition.getSymbolCount();
106: }
107:
108: /**
109: * Set the precedence for this production by a terminal symbol
110: *
111: * @param tsymbol Terminal symbol
112: */
113: public void setPrecedence(Terminal tsymbol) {
114: precedence = tsymbol;
115: }
116:
117: /**
118: * Return the precedence symbol.
119: *
120: * @return Terminal symbol.
121: */
122: public Terminal getPrecedence() {
123: return precedence;
124: }
125:
126: /**
127: * If the production contains a precedence symbol.
128: *
129: * @return True, if a precedence symbol is defined.
130: */
131: public boolean hasPrecedence() {
132: return precedence != null;
133: }
134:
135: /**
136: * Return all used symbols in this production
137: *
138: * @return Set of symbols.
139: */
140: public SymbolSet getSymbols() {
141: SymbolSet set = new SymbolSet();
142:
143: set.addSymbol(ntsymbol);
144: set.addSymbol(definition);
145: if (precedence != null)
146: set.addSymbol(precedence);
147:
148: return set;
149: }
150:
151: /**
152: * Set the location from the input source.
153: *
154: * @param location Location in the input source.
155: */
156: public void setLocation(String location) {
157: this .location = location;
158: }
159:
160: /**
161: * Returns the location from the input source.
162: *
163: * @return Location in the input source.
164: */
165: public String getLocation() {
166: return location;
167: }
168:
169: /**
170: * Validates the production.
171: *
172: * @return Return a list of violations, if this object isn't valid.
173: */
174: public Violations validate() {
175: Violations violations = new Violations();
176:
177: if (ntsymbol == null)
178: violations.addViolation(
179: "No symbol is for the left side defined", location);
180:
181: /*if ((definition==null) || (definition.getSymbolCount()<=0))
182: violations.addViolation("No symbols are for the right side defined",
183: location);*/
184: return violations;
185: }
186:
187: /**
188: * Compares the production with another production.
189: *
190: * @param o Other object.
191: *
192: * @return True, if the production are equal.
193: */
194: public boolean equals(Object o) {
195: if (o == this )
196: return true;
197:
198: if (o instanceof Production) {
199: Production production = (Production) o;
200:
201: if (precedence != null)
202: return (ntsymbol.equals(production.ntsymbol))
203: && (definition.equals(production.definition))
204: && (precedence.equals(production.precedence));
205: else
206: return (ntsymbol.equals(production.ntsymbol))
207: && (definition.equals(production.definition))
208: && (production.precedence == null);
209: }
210:
211: return false;
212: }
213:
214: /**
215: * Return a string representation of the production.
216: *
217: * @return String representation of the production.
218: */
219: public String toString() {
220: StringBuffer buffer = new StringBuffer();
221:
222: buffer.append(ntsymbol + " := ");
223: for (int j = 0; j < definition.getSymbolCount(); j++)
224: buffer.append(definition.getSymbol(j) + " ");
225:
226: if (hasPrecedence())
227: buffer.append("[precedence=" + getPrecedence() + "]");
228:
229: return buffer.toString();
230: }
231:
232: /**
233: * @return
234: *
235: * @throws CloneNotSupportedException
236: */
237: public Object clone() {
238: Production clone = new Production();
239:
240: clone.ntsymbol = ntsymbol;
241: clone.definition = (SymbolList) definition.clone();
242: clone.precedence = precedence;
243: clone.location = location;
244:
245: return clone;
246: }
247: }
|