/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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; } }