package de.fuberlin.projecta.parser; import java.util.EnumSet; import java.util.HashMap; import java.util.Map; import de.fuberlin.commons.lexer.TokenType; import de.fuberlin.commons.parser.ISymbol; public class Symbol implements ISymbol { /** * Internal symbols, for building up the parse tree */ public enum Reserved { EPSILON("ε"), // epsilon production FP("_FP"); // frame pointer (internal) private static Map<String,Reserved> terminalSymbol2Reserved = new HashMap<String, Reserved>(); static{ for(Reserved t : EnumSet.allOf(Reserved.class)){ terminalSymbol2Reserved.put(t.getTerminalSymbol(), t); } } private final String terminalSymbol; private Reserved(String terminalSymbol) { this.terminalSymbol=terminalSymbol; } public String getTerminalSymbol(){ return this.terminalSymbol; } public static Reserved byTerminalSymbol(String s){ return terminalSymbol2Reserved.get(s); } } private Object symbol; /** * Constructor for reserved (internal) symbols */ public Symbol(Reserved symbol) { this.symbol = symbol; } /** * Construct Symbol instance from string * * @param string A string describing a terminal or non-terminal or reserved symbol */ public Symbol(String string) { // parse by definitions (for the generic parser groups) this.symbol=Reserved.byTerminalSymbol(string); if (symbol!=null) return; this.symbol = NonTerminal.byNonTerminalSymbol(string); if (symbol!=null) return; this.symbol = TokenType.byTerminalSymbol(string); if (symbol!=null) return; // parse by enum value (for projecta) try { this.symbol = Reserved.valueOf(string); return; } catch (IllegalArgumentException e) { } try { this.symbol = NonTerminal.valueOf(string); return; } catch (IllegalArgumentException e) { } try { this.symbol = TokenType.valueOf(string); return; } catch (IllegalArgumentException e) { } if (symbol == null) throw new RuntimeException("Failed to resolve symbol: " + string); } public Symbol(TokenType terminal) { this.symbol = terminal; } public Symbol(NonTerminal nonTerminal) { this.symbol = nonTerminal; } public TokenType asTerminal() { return (TokenType) symbol; } public NonTerminal asNonTerminal() { return (NonTerminal) symbol; } public Reserved asReservedTerminal() { return (Reserved) symbol; } public boolean isTerminal() { return symbol instanceof TokenType; } public boolean isNonTerminal() { return symbol instanceof NonTerminal; } public boolean isReservedTerminal() { return symbol instanceof Reserved; } @Override public String toString() { if (isTerminal()) return "<T," + asTerminal() + ">"; if (isNonTerminal()) return "<NT," + asNonTerminal() + ">"; if (isReservedTerminal()) { return "<R," + asReservedTerminal() + ">"; } // never reached return "<invalid>"; } @Override public String getName() { if (isTerminal()) return asTerminal().toString(); if (isNonTerminal()) return asNonTerminal().toString(); if (isReservedTerminal()) { return asReservedTerminal().toString(); } // never reached return "invalid"; } @Override public boolean equals(Object other) { if (other == null) return false; if (other instanceof Symbol) { Symbol that = (Symbol)other; if (this.getName().equals(that.getName())) return true; } return false; } @Override public int hashCode() { return getName().hashCode(); } }