import demeter.*; public class Parser implements ParserConstants { static char unescapifyChar(String s) { char c = s.charAt(0); if (c == '\\') { switch (s.charAt(1)) { case 'n': c = '\n'; break; case 't': c = '\t'; break; case 'b': c = '\b'; break; case 'r': c = '\r'; break; case 'f': c = '\f'; break; case '\\': c = '\\'; break; case '\'': c = '\''; break; case '\"': c = '\"'; break; default: c = (char) Integer.parseInt(s.substring(2, s.length()), 8); break; } } return c; } static String unescapify(String s) { char str[] = new char[s.length()]; int i = 0, o = 0; while (i < s.length()) { char c = s.charAt(i++); if (c == '\\') { int j = i + 1; while (j < s.length() && Character.digit(s.charAt(j), 8) != -1) { j++; } c = unescapifyChar(s.substring(i-1, j)); i = j; } str[o++] = c; } return String.valueOf(str, 0, o); } protected ParserTokenManager token_source; protected Token token = new Token(); protected Token scanpos, lastpos; private int la; protected Parser me; private int[] scan_hist_kind = new int[10000]; private Token[] scan_hist_index = new Token[10000]; int scan_hist_ptr = 0; public Parser(java.io.InputStream stream) { me = this; ASCII_CharStream input_stream = new ASCII_CharStream(stream, 1, 1); token_source = new ParserTokenManager(input_stream); } public void ReInit(java.io.InputStream stream) { ASCII_CharStream input_stream = new ASCII_CharStream(stream, 1, 1); token_source.ReInit(input_stream); token = new Token(); scan_hist_ptr = 0; } public Parser(ParserTokenManager tm) { me = this; token_source = tm; } public void ReInit(ParserTokenManager tm) { token_source = tm; token = new Token(); scan_hist_ptr = 0; } final private Token consume_token(int kind) throws ParseError { if (token.next != null) token = token.next; else token = token_source.getNextToken(); scan_hist_kind[scan_hist_ptr] = kind; scan_hist_index[scan_hist_ptr++] = token; if (token.kind == kind) { scan_hist_ptr = 0; return token; } token_error_setup(0); throw new ParseError(); } final private boolean scan_token(int kind) throws ParseError { if (scanpos == lastpos) { la--; if (scanpos.next == null) { lastpos = scanpos = scanpos.next = token_source.getNextToken(); } else { lastpos = scanpos = scanpos.next; } } else { scanpos = scanpos.next; } scan_hist_kind[scan_hist_ptr] = kind; scan_hist_index[scan_hist_ptr++] = scanpos; return (scanpos.kind != kind); } final public Token getNextToken() throws ParseError { if (token.next != null) token = token.next; else token = token_source.getNextToken(); return token; } final public Token getToken(int index) throws ParseError { scanpos = token; for (int i = 0; i < index; i++) { if (scanpos.next != null) scanpos = scanpos.next; else scanpos = scanpos.next = token_source.getNextToken(); } return scanpos; } static final String add_escapes(String str) { String retval = ""; char ch; for (int i = 0; i < str.length(); i++) { ch = str.charAt(i); if (ch == '\b') { retval += "\\b"; } else if (ch == '\t') { retval += "\\t"; } else if (ch == '\n') { retval += "\\n"; } else if (ch == '\f') { retval += "\\f"; } else if (ch == '\r') { retval += "\\r"; } else if (ch == '\"') { retval += "\\\""; } else if (ch == '\'') { retval += "\\\'"; } else if (ch == '\\') { retval += "\\\\"; } else { retval += ch; } } return retval; } protected int error_line; protected int error_column; protected String error_string; protected String[] expected_tokens; protected void token_error() { System.out.println(""); System.out.println("Parse error at line " + error_line + ", column " + error_column + ". Encountered:"); System.out.println(" \"" + add_escapes(error_string) + "\""); System.out.println(""); if (expected_tokens.length == 1) { System.out.println("Was expecting:"); } else { System.out.println("Was expecting one of:"); } for (int i = 0; i < expected_tokens.length; i++) { System.out.println(" " + expected_tokens[i]); } System.out.println(""); } final protected void token_error_setup(int stream_ptr) { Token tok; int[] tokenbuf = new int[100]; int tokenbufptr = 0; int maxsize = 0; String[] exp = new String[1000]; int exp_count = 0; for (int i = 0; i < scan_hist_ptr; i++) { if (i == 0 || scan_hist_index[i-1].next == scan_hist_index[i]) { tokenbuf[tokenbufptr++] = scan_hist_kind[i]; if (tokenbufptr > maxsize) maxsize = tokenbufptr; } else { exp[exp_count] = ""; for (int j = 0; j < tokenbufptr; j++) { exp[exp_count] += tokenImage[tokenbuf[j]] + " "; } if (tokenbuf[tokenbufptr-1] != 0) exp[exp_count] += "..."; exp_count++; for (int j = 0; j < exp_count-1; j++) { if (exp[j].equals(exp[exp_count-1])) { exp_count--; break; } } tok = token; if (stream_ptr == 1) tok = tok.next; tokenbufptr = 1; while (tok != scan_hist_index[i]) { tok = tok.next; tokenbufptr++; } tokenbuf[tokenbufptr-1] = scan_hist_kind[i]; } } exp[exp_count] = ""; for (int j = 0; j < tokenbufptr; j++) { exp[exp_count] += tokenImage[tokenbuf[j]] + " "; } if (tokenbuf[tokenbufptr-1] != 0) exp[exp_count] += "..."; exp_count++; for (int j = 0; j < exp_count-1; j++) { if (exp[j].equals(exp[exp_count-1])) { exp_count--; break; } } expected_tokens = new String[exp_count]; for (int i = 0; i < exp_count; i++) { expected_tokens[i] = exp[i]; } error_line = token.beginLine; error_column = token.beginColumn; error_string = ""; tok = token; if (stream_ptr == 1) tok = tok.next; for (int i = 0; i < maxsize; i++) { if (tok.kind == 0) { error_string += " " + tokenImage[0]; break; } error_string += " " + tok.image; tok = tok.next; } error_string = error_string.substring(1); me.token_error(); } final public Container Container() throws ParseError { Container it; Item_List _contents; Capacity _capacity; it=new Container(); consume_token(1); _contents = Item_List(); it.set_contents(_contents); _capacity = Capacity(); it.set_capacity(_capacity); consume_token(2); return it; } final public Item Item() throws ParseError { Item it; if (_Jack2_1(1)) { it = Container(); } else if (_Jack2_2(1)) { it = Simple(); } else { token_error_setup(1); throw new ParseError(); } return it; } final public Simple Simple() throws ParseError { Simple it; ItemName _name; Weight _w; it=new Simple(); _name = ItemName(); it.set_name(_name); _w = Weight(); it.set_w(_w); return it; } final public ItemName ItemName() throws ParseError { ItemName it; Ident _i; it=new ItemName(); _i = Ident(); it.set_i(_i); return it; } final public Capacity Capacity() throws ParseError { Capacity it; Integer _i; it=new Capacity(); _i = Integer(); it.set_i(_i); return it; } final public Weight Weight() throws ParseError { Weight it; Integer _i; it=new Weight(); _i = Integer(); it.set_i(_i); return it; } final public SummingVisitor SummingVisitor() throws ParseError { SummingVisitor it; Integer _total; it=new SummingVisitor(); _total = Integer(); it.set_total(_total); return it; } final public CountingVisitor CountingVisitor() throws ParseError { CountingVisitor it; Integer _total; it=new CountingVisitor(); _total = Integer(); it.set_total(_total); return it; } final public AverageVisitor AverageVisitor() throws ParseError { AverageVisitor it; CountingVisitor _cV; SummingVisitor _sV; Float _current; it=new AverageVisitor(); _cV = CountingVisitor(); it.set_cV(_cV); _sV = SummingVisitor(); it.set_sV(_sV); _current = Float(); it.set_current(_current); return it; } final public Main Main() throws ParseError { Main it; it=new Main(); return it; } final public Item_List Item_List() throws ParseError { Item_List it; Nonempty_Item_List _first; it=new Item_List(); if (_Jack2_3(1)) { _first = Nonempty_Item_List(); it.set_first(_first); } return it; } final public Nonempty_Item_List Nonempty_Item_List() throws ParseError { Nonempty_Item_List it; Item _it; Nonempty_Item_List _next; it=new Nonempty_Item_List(); _it = Item(); it.set_it(_it); if (_Jack2_4(1)) { _next = Nonempty_Item_List(); it.set_next(_next); } return it; } final public Ident Ident() throws ParseError { Token t; t = consume_token(IDENTIFIER); return new Ident(t.image); } final public String String() throws ParseError { Token t; t = consume_token(STRING_LITERAL); String s = t.image; return unescapify(s.substring(1, s.length()-1)); } final public Text Text() throws ParseError { Token t; t = consume_token(TEXT_LITERAL); String s = t.image; return new Text(s.substring(2, s.length()-2)); } final public Number Number() throws ParseError { Token t; String s; int radix; Number num; if (_Jack2_5(1)) { if (_Jack2_6(1)) { t = consume_token(DECIMAL_LITERAL); s = t.image; radix = 10; } else if (_Jack2_7(1)) { t = consume_token(HEX_LITERAL); s = t.image.substring(2, t.image.length()); radix = 16; } else if (_Jack2_8(1)) { t = consume_token(OCTAL_LITERAL); s = t.image; radix = 8; } else { token_error_setup(1); throw new ParseError(); } switch (s.charAt(s.length()-1)) { case 'l': case 'L': num = Long.valueOf(s.substring(0, s.length()-1), radix); break; default: num = Integer.valueOf(s, radix); break; } } else if (_Jack2_9(1)) { t = consume_token(FLOATING_POINT_LITERAL); s = t.image; switch (s.charAt(s.length()-1)) { case 'd': case 'D': num = Double.valueOf(s.substring(0, s.length()-1)); break; case 'f': case 'F': num = Float.valueOf(s.substring(0, s.length()-1)); break; default: num = Float.valueOf(s); break; } } else { token_error_setup(1); throw new ParseError(); } return num; } final public Integer Integer() throws ParseError { Number num; num = Number(); return new Integer(num.intValue()); } final public Long Long() throws ParseError { Number num; num = Number(); return new Long(num.longValue()); } final public Float Float() throws ParseError { Number num; num = Number(); return new Float(num.floatValue()); } final public Double Double() throws ParseError { Number num; num = Number(); return new Double(num.doubleValue()); } final private boolean _Jack2_1(int xla) throws ParseError { la = xla; lastpos = scanpos = token; return !_Jack3_1(); } final private boolean _Jack2_2(int xla) throws ParseError { la = xla; lastpos = scanpos = token; return !_Jack3_2(); } final private boolean _Jack2_3(int xla) throws ParseError { la = xla; lastpos = scanpos = token; return !_Jack3_3(); } final private boolean _Jack2_4(int xla) throws ParseError { la = xla; lastpos = scanpos = token; return !_Jack3_4(); } final private boolean _Jack2_5(int xla) throws ParseError { la = xla; lastpos = scanpos = token; return !_Jack3_5(); } final private boolean _Jack2_6(int xla) throws ParseError { la = xla; lastpos = scanpos = token; return !_Jack3_6(); } final private boolean _Jack2_7(int xla) throws ParseError { la = xla; lastpos = scanpos = token; return !_Jack3_7(); } final private boolean _Jack2_8(int xla) throws ParseError { la = xla; lastpos = scanpos = token; return !_Jack3_8(); } final private boolean _Jack2_9(int xla) throws ParseError { la = xla; lastpos = scanpos = token; return !_Jack3_9(); } final private boolean _Jack3_1() throws ParseError { if (_Jack3Container()) return true; if (la == 0 && scanpos == lastpos) return false; return false; } final private boolean _Jack3_2() throws ParseError { if (_Jack3Simple()) return true; if (la == 0 && scanpos == lastpos) return false; return false; } final private boolean _Jack3_3() throws ParseError { if (_Jack3Nonempty_Item_List()) return true; if (la == 0 && scanpos == lastpos) return false; return false; } final private boolean _Jack3_4() throws ParseError { if (_Jack3Nonempty_Item_List()) return true; if (la == 0 && scanpos == lastpos) return false; return false; } final private boolean _Jack3_5() throws ParseError { Token xsp; xsp = scanpos; if (_Jack3_6()) { scanpos = xsp; if (_Jack3_7()) { scanpos = xsp; if (_Jack3_8()) return true; if (la == 0 && scanpos == lastpos) return false; } else if (la == 0 && scanpos == lastpos) return false; } else if (la == 0 && scanpos == lastpos) return false; return false; } final private boolean _Jack3_6() throws ParseError { if (scan_token(DECIMAL_LITERAL)) return true; if (la == 0 && scanpos == lastpos) return false; return false; } final private boolean _Jack3_7() throws ParseError { if (scan_token(HEX_LITERAL)) return true; if (la == 0 && scanpos == lastpos) return false; return false; } final private boolean _Jack3_8() throws ParseError { if (scan_token(OCTAL_LITERAL)) return true; if (la == 0 && scanpos == lastpos) return false; return false; } final private boolean _Jack3_9() throws ParseError { if (scan_token(FLOATING_POINT_LITERAL)) return true; if (la == 0 && scanpos == lastpos) return false; return false; } final private boolean _Jack3Container() throws ParseError { if (scan_token(1)) return true; if (la == 0 && scanpos == lastpos) return false; if (_Jack3Item_List()) return true; if (la == 0 && scanpos == lastpos) return false; if (_Jack3Capacity()) return true; if (la == 0 && scanpos == lastpos) return false; if (scan_token(2)) return true; if (la == 0 && scanpos == lastpos) return false; return false; } final private boolean _Jack3Simple() throws ParseError { if (_Jack3ItemName()) return true; if (la == 0 && scanpos == lastpos) return false; if (_Jack3Weight()) return true; if (la == 0 && scanpos == lastpos) return false; return false; } final private boolean _Jack3Nonempty_Item_List() throws ParseError { if (_Jack3Item()) return true; if (la == 0 && scanpos == lastpos) return false; Token xsp; xsp = scanpos; if (_Jack3_4()) scanpos = xsp; else if (la == 0 && scanpos == lastpos) return false; return false; } final private boolean _Jack3Item_List() throws ParseError { Token xsp; xsp = scanpos; if (_Jack3_3()) scanpos = xsp; else if (la == 0 && scanpos == lastpos) return false; return false; } final private boolean _Jack3Capacity() throws ParseError { if (_Jack3Integer()) return true; if (la == 0 && scanpos == lastpos) return false; return false; } final private boolean _Jack3ItemName() throws ParseError { if (_Jack3Ident()) return true; if (la == 0 && scanpos == lastpos) return false; return false; } final private boolean _Jack3Weight() throws ParseError { if (_Jack3Integer()) return true; if (la == 0 && scanpos == lastpos) return false; return false; } final private boolean _Jack3Item() throws ParseError { Token xsp; xsp = scanpos; if (_Jack3_1()) { scanpos = xsp; if (_Jack3_2()) return true; if (la == 0 && scanpos == lastpos) return false; } else if (la == 0 && scanpos == lastpos) return false; return false; } final private boolean _Jack3Integer() throws ParseError { if (_Jack3Number()) return true; if (la == 0 && scanpos == lastpos) return false; return false; } final private boolean _Jack3Ident() throws ParseError { if (scan_token(IDENTIFIER)) return true; if (la == 0 && scanpos == lastpos) return false; return false; } final private boolean _Jack3Number() throws ParseError { Token xsp; xsp = scanpos; if (_Jack3_5()) { scanpos = xsp; if (_Jack3_9()) return true; if (la == 0 && scanpos == lastpos) return false; } else if (la == 0 && scanpos == lastpos) return false; return false; } }