import java.util.*;

// the semantic error exception
class semanticError extends Exception{
    public semanticError(token t){
	super("variable undefined: " + t.name);
    } // end of constructor
} // end of class semanticError


class semanticAnalyzer {
    private symbolTable symTab;
    
    public semanticAnalyzer(symbolTable s) {
	symTab = s;
	symTab.put(new token(scanner.ID,"_in"));
	symTab.put(new token(scanner.ID,"_out"));
    } // end of constructor
    
    void analyze(token tok) throws semanticError {
	token t;
	switch (tok.type) {
	case scanner._START:
	    analyze((token)tok.children.elementAt(0));
	    break;
	case scanner.ID:
	    if(symTab.get(tok) == null) throw new semanticError(tok);
	    break;
	case scanner.STRING:
	    strToBits(tok);
	    break;
	case scanner.PLUS:
	    analyze((token)tok.children.elementAt(0));
	    analyze((token)tok.children.elementAt(1));
	    break;
	case scanner.MINUS:
	    analyze((token)tok.children.elementAt(0));
	    break;
	case scanner._CLEAR:
	    t = (token)tok.children.elementAt(0); 
	    if(!symTab.containsKey(t)) symTab.put(t);
	    analyze((token)tok.children.elementAt(1));
	    break;
	case scanner.EQ:
	    analyze((token)tok.children.elementAt(1));
	    t = (token)tok.children.elementAt(0);
	    if(!symTab.containsKey(t)) symTab.put(t);
	    break;
	case scanner.BAR:
	    analyze((token)tok.children.elementAt(0));
	    analyze((token)tok.children.elementAt(1));
	    break;
	case scanner.EPSILON:
	    break;
	}
    } // end analyze
    
    public static void strToBits(token tok) {
	StringBuffer bits = new StringBuffer("");
	for (int i=0; i<tok.name.length(); i++)
	    if (tok.name.charAt(i) == '.') bits.append('0');
	    else bits.append('1');
	tok.name = bits.toString();
    } // end of strToBits
    
} // end of semanticAnal
