package de.skuzzle.polly.core.parser;
import java.util.Collection;
import java.util.EnumMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
/**
* This class maps token types which represent operators to a certain precedence level.
*
* @author Simon Taddiken
*/
public class PrecedenceTable {
public enum PrecedenceLevel {
RELATION, DISJUNCTION, CONJUNCTION, SECTERM, TERM, FACTOR, POSTFIX, DOTDOT, UNARY;
}
private Map<PrecedenceLevel, Set<TokenType>> levels;
public PrecedenceTable() {
this.levels = new EnumMap<PrecedenceLevel, Set<TokenType>>(PrecedenceLevel.class);
for (PrecedenceLevel lvl : PrecedenceLevel.values()) {
this.levels.put(lvl, new TreeSet<TokenType>());
}
this.add(PrecedenceLevel.RELATION, TokenType.EGT);
this.add(PrecedenceLevel.RELATION, TokenType.ELT);
this.add(PrecedenceLevel.RELATION, TokenType.EQ);
this.add(PrecedenceLevel.RELATION, TokenType.NEQ);
this.add(PrecedenceLevel.RELATION, TokenType.GT);
this.add(PrecedenceLevel.RELATION, TokenType.LT);
this.add(PrecedenceLevel.RELATION, TokenType.EQUIVALENCE);
this.add(PrecedenceLevel.RELATION, TokenType.IMPLICATION);
this.add(PrecedenceLevel.DISJUNCTION, TokenType.BOOLEAN_OR);
this.add(PrecedenceLevel.DISJUNCTION, TokenType.INT_OR);
this.add(PrecedenceLevel.DISJUNCTION, TokenType.XOR);
this.add(PrecedenceLevel.DISJUNCTION, TokenType.AND_OR);
this.add(PrecedenceLevel.CONJUNCTION, TokenType.BOOLEAN_AND);
this.add(PrecedenceLevel.CONJUNCTION, TokenType.INT_AND);
this.add(PrecedenceLevel.SECTERM, TokenType.ADD);
this.add(PrecedenceLevel.SECTERM, TokenType.ADDWAVE);
this.add(PrecedenceLevel.SECTERM, TokenType.SUB);
this.add(PrecedenceLevel.SECTERM, TokenType.WAVE);
this.add(PrecedenceLevel.SECTERM, TokenType.GT); // ISSUE #12: parser makes effort to recognize a rightshift here
//this.add(PrecedenceLevel.SECTERM, TokenType.URIGHT_SHIFT);
this.add(PrecedenceLevel.SECTERM, TokenType.LEFT_SHIFT);
// ISSUE 0000099: Add open brace and identifier to TERM precedence level so they
// are recognized as multiplications
this.add(PrecedenceLevel.TERM, TokenType.OPENBR);
this.add(PrecedenceLevel.TERM, TokenType.IDENTIFIER);
this.add(PrecedenceLevel.TERM, TokenType.MUL);
this.add(PrecedenceLevel.TERM, TokenType.DIV);
this.add(PrecedenceLevel.TERM, TokenType.INTDIV);
this.add(PrecedenceLevel.TERM, TokenType.MOD);
this.add(PrecedenceLevel.FACTOR, TokenType.POWER);
this.add(PrecedenceLevel.POSTFIX, TokenType.OPENSQBR);
this.add(PrecedenceLevel.POSTFIX, TokenType.QUESTION);
this.add(PrecedenceLevel.POSTFIX, TokenType.QUEST_EXCALAMTION);
this.add(PrecedenceLevel.POSTFIX, TokenType.TRANSPOSE);
this.add(PrecedenceLevel.DOTDOT, TokenType.DOTDOT);
this.add(PrecedenceLevel.UNARY, TokenType.SUB);
this.add(PrecedenceLevel.UNARY, TokenType.EXCLAMATION);
}
public boolean match(Token t, PrecedenceLevel level) {
return this.levels.get(level).contains(t.getType());
}
public void add(PrecedenceLevel level, TokenType t) {
this.levels.get(level).add(t);
}
public Collection<TokenType> getLevel(PrecedenceLevel level) {
return this.levels.get(level);
}
}