Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!seismo!rutgers!mcnc!rti!rajan From: rajan@rti.UUCP (Sundar Varadarajan) Newsgroups: comp.bugs.4bsd Subject: Bugs in yacc error handling and types on value stack. Message-ID: <1600@rti.UUCP> Date: Mon, 3-Aug-87 13:23:26 EDT Article-I.D.: rti.1600 Posted: Mon Aug 3 13:23:26 1987 Date-Received: Tue, 4-Aug-87 03:51:25 EDT Organization: Research Triangle Institute, RTP, NC Lines: 43 Keywords: yacc error types Hi, There seem to be two problems with the way yacc handles errors. (1) If, in a state the action on error is to shift, but the default action is to reduce, then yacc will reduce, rather than shift, on error. (See "Introduction to Compiler Construction with UNIX" by Axel T. Schreiner and H. George Friedman Jr. Chapter 4, page 71 for a full explanation). (2) If, in a state the action on error is to reduce by a rule but the default action is to reduce by another rule, then yacc will reduce by the latter rather than by the former(on error). The fixes for the two problems are as follows. If in a state there is a shift on the special terminal "error", then make the default action the error action. That is, yacc recognizes the input as being in error by default. For the second problem, if there is a reduce on error, then make that the default action. This is done by modifying the code in y3.c in the yacc source as fol- lows. 288c296 < if( temp1[chfind(2,"error")] > 0 ) lastred = 0; --- > if( temp1[1] > 0 ) lastred = 0; 290,293d297 < /* for error recovery, arrange that, if there is a reduce on the */ < /* error recovery token, `error', the default be that reduction */ < if( temp1[chfind(2,"error")] < 0 ) lastred = -temp1[chfind(2,"error")]; < (This is extracted by "diff newy3.c y3.c". Furthermore, the line numbers are likely to be slightly off). Another yacc bug. Yacc sometimes gets confused with the type (of the value on the value stack) of a terminal. If you have more than 64 different types attached to non-terminals and if you declare the type of the non- terminals before the type of the terminals (with the "%type <...>" and "%token <...>" declarations), yacc will get confused about the type of the terminals. Always declare the type of the terminals first and then the non- terminals. Sundar