I finally got my parser working. The main difficulties I and others were having was integrating Appel's code in tiger/chap4/Parse/ with the lexical analyzer. The *key* to getting things to work is not to use Appel's supplied Yylex class and Lexer interface for your scanner. Instead, use *your* own Yylex class. If yours doesn't work, I've made one that does available on the homepage. Once the right Yylex is used, you will still be able to use Appel's ErrorMsg classes. I've also supplied my Parse.java file, which you can use to replace the original in tiger/chap4/Parse/. My Parse.java file pretty prints the syntax tree. The "main" class is included in this file, so the correct use of Parse will be as in "java Parse merge.tig" or "java Parse.Parse merge.tig". (* I wrote my parser inside tiger/chap4/Parse/, and my CLASSPATH includes tiger/chap4/ *) You will also need to replace Appel's files OpExp.java and Print.java in the tiger/chap4/Absyn directory with the new versions I've supplied, and *recompile them*. The older versions don't handle the boolean operators and the unary minus operator correctly. (You may also have to fix your lexer file if it doesn't recognize "&" and "|".) Another thing you should know is that in emacs, "esc-x goto-char" gets you to the right char. This will help if your parser have problems. The initial portions of my .lex file and Grm.cup file looks as follows: /* ---------------------- Initial Portion of .lex file: --- */ package Parse; %% %{ private java_cup.runtime.Symbol tok(int k, Object val) { return new java_cup.runtime.Symbol(k, yychar, yychar+yylength(), val); } public ErrorMsg.ErrorMsg errorMsg; /* From Appel, chap3 : */ private void newline() { errorMsg.newline(yychar); } private void err(int pos, String s) { errorMsg.error(pos,s); } private void err(String s) { err(yychar,s); } Yylex(java.io.InputStream s, ErrorMsg.ErrorMsg e) { this(s); errorMsg=e; } %} %function next_token %type java_cup.runtime.Symbol %line /* ---------------------- Initial Portion of Grm.cup: --- */ package Parse; import Absyn.*; // abstract syntax classes action code {: /* static Symbol.Symbol sym(String s) { return Symbol.Symbol.symbol(s); } */ static Symbol.Symbol sym(String s) { return new Symbol.Symbol(s); } :}; parser code {: public Exp parseResult; Yylex lexer; public void syntax_error(java_cup.runtime.Symbol current) { report_error("Syntax error (" + current.sym + ")", current); } ErrorMsg.ErrorMsg errorMsg; public void report_error(String message, java_cup.runtime.Symbol info) { errorMsg.error(info.left, message); } public parser(Yylex l, ErrorMsg.ErrorMsg err) { this(); errorMsg=err; lexer=l; } :}; scan with {: return lexer.next_token(); :};