/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* This file is part of SableCC. *
* See the file "LICENSE" for copyright information and the *
* terms and conditions for copying, distribution and *
* modification of SableCC. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
package org.sablecc.sablecc;
@SuppressWarnings("rawtypes")
final class LR1Item implements Cloneable, Comparable {
final LR0Item lr0Item;
final int terminal;
LR1Item(LR0Item lr0Item, int terminal) {
this.lr0Item = lr0Item;
this.terminal = terminal;
}
@Override
public Object clone() {
return new LR1Item(lr0Item, terminal);
}
@Override
public boolean equals(Object obj) {
if ((obj == null) ||
(obj.getClass() != this.getClass())) {
return false;
}
LR1Item item = (LR1Item) obj;
return (item.lr0Item.equals(lr0Item)) &&
(item.terminal == terminal);
}
@Override
public int hashCode() {
return lr0Item.hashCode() * (terminal + 1) * 37;
}
@Override
public String toString() {
return lr0Item + ":" + Symbol.symbol(terminal, true);
}
public String toString(Symbol lookahead) {
// two cases:
// (1) we are facing a reduction, and the lookahed
// should match
// (2) we are in the middle of a production. The
// next element should match.
Symbol[] rightside = Production.production(lr0Item.production).rightside();
if (lr0Item.position == rightside.length) {
Symbol term = Symbol.symbol(terminal, true);
if (term == lookahead) {
return lr0Item + " followed by " + term + " (reduce)";
} else {
return null;
}
}
if (rightside[lr0Item.position] == lookahead) {
return lr0Item + " (shift)";
} else {
return null;
}
}
@Override
public int compareTo(Object object) {
LR1Item item = (LR1Item) object;
int result = lr0Item.compareTo(item.lr0Item);
if (result == 0) {
result = terminal - item.terminal;
}
return result;
}
}