001: package ro.infoiasi.donald.compiler.lexer;
002:
003: import ro.infoiasi.donald.compiler.lexer.exceptions.*;
004: import java.util.*;
005:
006: /** An ordered set of symbols (characters) */
007: public class Alphabet implements Cloneable {
008: /** An array with all the characters currently in the alphabet */
009: private ArrayList arr;
010: /** A map containing symbol(Char)-index(Integer) pairs used for
011: quickly obtaining the symbol index corresponding to a symbol */
012: private HashMap map;
013:
014: /** Constructs an empty alphabet */
015: public Alphabet() {
016: map = new HashMap();
017: arr = new ArrayList();
018: }
019:
020: /** Constructs an alphabet containing all the distinct symbols
021: in the specified string (in that particular order) */
022: public Alphabet(String s) {
023: this ();
024: for (int i = 0; i < s.length(); i++) {
025: addSymbol(s.charAt(i));
026: }
027: }
028:
029: /** Constructs an alphabet by copying an existing one */
030: public Alphabet(Alphabet alpha) {
031: arr = (ArrayList) alpha.arr.clone();
032: map = (HashMap) alpha.map.clone();
033: }
034:
035: /** Creates and returns a clone of this object */
036: public Object clone() {
037: return new Alphabet(this );
038: }
039:
040: /** Indicates whether some other object is "equal to" this one. */
041: public boolean equals(Object obj) {
042: Alphabet alpha = (Alphabet) obj;
043: if (size() != alpha.size()) {
044: return false;
045: }
046: for (int i = 0; i < size(); i++) {
047: if (getSymbol(i).charValue() != getSymbol(i).charValue()) {
048: return false;
049: }
050: }
051: return true;
052: }
053:
054: /** Returns the number of symbols in this alphabet */
055: public int size() {
056: return arr.size();
057: }
058:
059: /** Removes all symbols from this alphabet */
060: public void clear() {
061: arr.clear();
062: map.clear();
063: }
064:
065: /** Adds the specified character to this alpabet.
066: Once added symbols can only be removed with clear(). */
067: public void addSymbol(char ch) {
068: if (!containsSymbol(ch)) {
069: Character cObj = new Character(ch);
070: arr.add(cObj);
071: map.put(cObj, new Integer(map.size()));
072: }
073: }
074:
075: /** Returns the symbol in the alphabet at the given index */
076: public Character getSymbol(int index) {
077: return (Character) arr.get(index);
078: }
079:
080: /** Returns true if this alphabet contains the specified character. */
081: public boolean containsSymbol(char ch) {
082: return map.containsKey(new Character(ch));
083: }
084:
085: /** Returns the index in the alphabet for the specified character. */
086: public int idxSymbol(char ch) {
087: Integer i = (Integer) map.get(new Character(ch));
088: return i.intValue();
089: }
090:
091: /** Returns a string containg all the symbols of the alphabet
092: in the same order as they were added */
093: public String toString() {
094: StringBuffer sb = new StringBuffer(size());
095: for (int i = 0; i < size(); i++) {
096: sb.append((Character) arr.get(i));
097: }
098: return new String(sb);
099: }
100:
101: /** Prints the contents of the alphabet. [Debuging purpose] */
102: public void print() {
103: System.out.println("Size: " + size());
104: System.out.print("Array: ");
105: System.out.println(arr);
106: System.out.print("Map: ");
107: System.out.println(map.entrySet());
108: }
109: }
|