Compiler Design in C: Errata Sheet

holub@violet.Berkeley.EDU ()
Fri, 15 Jun 90 12:11:06 GMT

          From comp.compilers

Related articles
Compiler Design in C: Errata Sheet holub@violet.Berkeley.EDU (1990-06-15)
| List of all articles for this month |
Newsgroups: comp.compilers
From: holub@violet.Berkeley.EDU ()
Date: Fri, 15 Jun 90 12:11:06 GMT
Organization: University of California, Berkeley
Keywords: Compiler Design in C, errata, LeX, occs, llama, holub

This message is an errata sheet for Compiler Design in C. I post this with
some trepidation because some people might be misled by the number of errors
into thinking that there are serious problems with the book. This is not
true. The real problem isn't the error count, which is about par for the
first printing of a book of this size, but that most authors and publishers
don't want to admit that their books have errors, so you're not used to
having them pointed out to you. Most of the errors are, in any event, trivial
(misplaced commas, wrong fonts, etc.). The errors in the code have, of
course, been fixed in the software-distribution disks. The distribution
version number is found in each entry, so you can update your disks if you
have an earlier version. If you find anything not on the following list, I'd
be grateful if you'd point it out to me. Send the report to me directly and
I'll post it to the net once I've made the change. This document is also
distributed in printed form along with the software. I hope that the
following is helpful to you.


-Allen Holub
  holub@violet.berkeley.edu


------------------------------ cut here ------------------------------


                                Errata: Compiler Design in C


This document is a list of all typos and corrections that
need to be made to the first and second printings of
Compiler Design in C, Allen Holub, 1990 (as of June 14,
1990). The corrections marked ``disk file only'' represent
changes made to the files on the distribution disk that
either don't affect the code in any significant way or are
too big to insert into the book. All these will eventually
be encorporated into the second edition, if there is one,
but they won't be put into subsequent printings of the first
edition. There are also a few trivial changes, made before
any software was distributed, that are not listed here.
____________________________________________________________
Page xvi - Seventh line from the bottom. Change ``No credit
cards'' to ``No purchase orders or credit cards.''
____________________________________________________________
Page xvi - Last line. Internet can now be accessed from
CompuServe. Add the Compuserve/internet address
>INTERNET:holub@violet.berkeley.edu to the parenthesized
list at the end of the paragraph.
____________________________________________________________
Page xviii - Line 7, change ``that'' to ``than''.
____________________________________________________________
Page 8 - The line that starts "JANE verb object" in the
display at the bottom of the page is repeated. Delete the
first instance.
____________________________________________________________
Page 18 - Replace the first line of the untitled table just
under Listing 1.4 with the following (the |- is the end of
input symbol):


      1. statements -> expression ; |-
____________________________________________________________
Page 27 - (Fixed in software ver. 1.00.) Replace the word
"temporary" in the code part of lines 19, 26, and 42 of
Listing 1.9 with the word "tempvar."
____________________________________________________________
Page 36 - (Fixed in software ver. 1.00.) Replace Lines 16
and 17 of Listing 2.1 with the following (I've added a few
parentheses):


16 #define get(stream) (Pbackp < &Pbackbuf[SIZE] ? *Pbackp++ : getc(stream) )
17 #define unget(c) (Pbackp <= Pbackbuf ? -1 : (*--Pbackp=(c)) )
____________________________________________________________
Page 68 - The first line beneath the Figure should read as
follows (the Figure and Listing numbers are wrong):


table is shown in Figure 2.6 and in Listing 2.15. The
Yy_cmap[] array is indexed by
















June 14, 1990 -1- Errata: Compiler Design in C




____________________________________________________________
Page 72 - The first display (second and third lines) should
read as follows:


      ['0',2] ['1',2] ['2',2] ['3',2] ['4',2]
      ['5',2] ['6',2] ['7',2] ['8',2] ['9',2] ['e',5]




____________________________________________________________
Page 73 - The first line of the third paragraph calls out
the wrong line number. It should read as follows:


      The YYERROR() macro on line 151 of Listing 2.19 prints
internal error messages.
____________________________________________________________
Page 76 - (Fixed in software ver. 1.00.) Listing 2.19, line
166. Some code is missing. Replace line 166 with the
following line:


  166 if( (c = ii_input()) && (c != -1) )


____________________________________________________________
Page 85 - Third line from the bottom (which starts ``For
example'') should read:
For example, in a machine with a 16-bit int, the first two
bytes of the string are the
____________________________________________________________
Page 86 - Listing 2.21. Change the number 512 on line 28 to
768.
____________________________________________________________
Page 104 - Second paragraph, first four lines (above the
first picture) should read:


      Subroutines expr() and cat_expr() are in Listing 2.30.
These routines handle the binary operations: | (OR) and
concatenation. I'll show how expr() works by watching it
process the expression A|B. The cat_expr() call on line 621
creates a machine that recognizes the A:
____________________________________________________________
Page 152 - Remove the code on line 3 (#include "date.h"),
leaving the line number in place, but the rest of the line
should be blank.
____________________________________________________________
Page 157 - (Fixed in software ver. 1.00.) Replace line 117
with the following (I've added the --argc on the left):


  117 for( ++argv, --argc; argc && *(p = *argv) == '-'; ++argv, --argc )


____________________________________________________________
Page 171 - Replace the first display (which now reads
noun->time|banana) with the following:


      noun -> fruit | banana








June 14, 1990 -2- Errata: Compiler Design in C




____________________________________________________________
Page 171 - Second display, text to the right of the -> is
missing. It should read as follows:


      compound_stmt -> LEFT_CURLY stmt RIGHT_CURLY
                                            LEFT_CURLY RIGHT_CURLY
____________________________________________________________
Page 178 - Third line below the one that starts with
``Since'' (next to the marginal note), replace ``the the''
with ``the'':
____________________________________________________________
Page 183 - Display at bottom of page. Remove the
exclamation point. The expression should read as follows:


      expr -> + term {op('+');} expr
____________________________________________________________
Page 190 - First three lines beneath the figure (which start
``right-hand side'') should read:


right-hand side of the production, as if they were used in
the subroutine. For example, say that an attribute, t,
represents a temporary variable name, and it is attached to
an expr; it is represented like this in the subroutine
representing the expr:
____________________________________________________________
Page 196 - Figure 4.1. both instances of the word ``number''
should be in boldface.
____________________________________________________________
Page 218 - Table 4.16, Replace the table with the following
one. I've made several small changes. None of these changes
effect substance, but the table is a little more readable as
a consequence:










































June 14, 1990 -3- Errata: Compiler Design in C






          Table 16. Finding LL(1) Selection Sets
          __________________________________________________
          (1) A production is nullable if the entire
                        right-hand side can go to epsilon. This is the
                        case, both when the right-hand side
                        consists only of epsilon, and when all symbols
                        on the right-hand side can go to epsilon by some
                        derivation.


          (2) For nonnullable productions: Given a
                        production of the form:
                                  s->alpha B...
                        where s is a nonterminal, alpha is a
                        collection of one or more nullable
                        nonterminals, and B is either a terminal
                        or a nonnullable nonterminal (one that
                        can't go to epsilon) followed by any number of
                        additional symbols: the LL(1) select set
                        for that production is the union of
                        FIRST(alpha) and FIRST(B). That is, it's the
                        union of the FIRST sets for every
                        nonterminal in alpha plus FIRST(B). If alpha
                        doesn't exist (there are no nullable
                        nonterminals to the left of B), then
                        SELECT(s)=FIRST(B).


          (3) For nullable productions: Given a
                        production of the form
                                  s->alpha
                        where s is a nonterminal and alpha is a
                        collection of zero or more nullable
                        nonterminals (it can be epsilon): the LL(1)
                        select set for that production is the
                        union of FIRST(alpha) and FOLLOW(s). In plain
                        words: if a production is nullable, it can
                        be transparent-it can disappear entirely
                        in some derivation (be replaced by an
                        empty string). Consequently, if the
                        production is transparent, you have to
                        look through it to the symbols that can
                        follow it to determine whether it can be
                        applied in a given situation.


____________________________________________________________
Page 224 - The sentence on lines 13 and 14 (which starts
with ``If an ambiguous'') should read as follows:


      If an ambiguous right-hand side is one of several, then
all of these right-hand sides must move as part of the
substitution. For example, given:




June 14, 1990 -4- Errata: Compiler Design in C






____________________________________________________________
Page 228 - 8th line from the bottom, the ``Y'' in ``You''
should be in lower case.
____________________________________________________________
Page 242 - Pieces of the section heading for Section 4.9.2
are in the wrong font, and the last two lines of the following
paragraph are messed up. Replace with the following:






4.9.2 Occs and LLama Debugging Support-yydebug.c.


This section discusses the debug-mode support routines used by
the LLama-generated parser in the previous section. The
same routines are used by the occs-generated parser
discussed in the next chapter. You should be familiar with
the interface to the curses, window-management functions
described in Appendix A before continuing.
____________________________________________________________
Page 255 - Fourth line beneath the listing (starting with
``teractive mode''), replace comma following the close
parenthesis with a period.
____________________________________________________________
Page 271-303 - Odd numbered pages. Remove all tildes from
the running heads.
____________________________________________________________
Page 282 - The last paragraph should read as follows (the
Listing and Table numbers are wrong):


      The recursive-descent parser for LLama is in Listing
4.25. It is a straightforward representation of the grammar
in Table 4.19.
____________________________________________________________
Page 312 - (Fixed in software ver. 1.00.) Listing 4.30.
Replace lines 60 to 63 with the following:


60 PRIVATE int *Dtran; /* Internal representation of the parse table.
61 * Initialization in make_yy_dtran() assumes
62 * that it is an int [it calls memiset()].
63 */


____________________________________________________________
Page 315 - (Fixed in software ver. 1.00.) Listing 4.30.
Replace lines 231 to 240 with the following:


231 nterms = USED_TERMS + 1; /* +1 for EOI */
232 nnonterms = USED_NONTERMS;
233
234 i = nterms * nnonterms; /* Number of cells in array */
235
236 if( !(Dtran = (int *) malloc(i * sizeof(*Dtran)) )) /* number of bytes */
237 ferr("Out of memory\n");
238
239 memiset( Dtran, -1, i ); /* Initialize Dtran to all failures */
240 ptab( Symtab, fill_row, NULL, 0 ); /* and fill nonfailure transitions. */


June 14, 1990 -5- Errata: Compiler Design in C






____________________________________________________________
Page 330 - Listing 4.34, line 464. Delete everything except
the line number.
____________________________________________________________
Page 360 - Figure 5.6. The item immediately below the line
in State 7 (ie. the first closure item) should be changed
from e->.e*f to the following:
      t -> . t * f
____________________________________________________________
Page 361 - Third paragraph of section 5.6.2 (which starts
``The FOLLOW''). Replace the paragraph with the following
one:


      The FOLLOW sets for our current grammar are in Table 17.
Looking at the shift/reduce conflict in State 4, FOLLOW(e)
doesn't contain a *, so the SLR(1) method works in this
case. Similarly, in State 3, FOLLOW(s) doesn't contain a +,
so everything's okay. And finally, in State 10, there is an
outgoing edge labeled with a *, but FOLLOW(e) doesn't
contain a *. Since the FOLLOW sets alone are enough to
resolve the shift/reduce conflicts in all three states, this
is indeed an SLR(1) grammar.
____________________________________________________________
Page 361 - First paragraph in section 5.6.3 (which starts
``Continuing our quest''). Replace the paragraph with the
following one:


      Many grammars are not as tractable as the current one-
it's likely that a FOLLOW set will contain symbols that also
label an outgoing edge. A closer look at the machine yields
an interesting fact that can be used to solve this
difficulty. A nonterminal's FOLLOW set includes all symbols
that can follow that nonterminal in every possible context.
The state machine, however, is more limited. You don't
really care which symbols can follow a nonterminal in every
possible case; you care only about those symbols that can be
in the input when you reduce by a production that has that
nonterminal on its left-hand side. This set of relevant
lookahead symbols is typically a subset of the complete
FOLLOW set, and is called the lookahead set.
____________________________________________________________
Page 363 - The C is in the wrong font in both the first
marginal note and the first display (on the third line). It
should be in Roman.
____________________________________________________________
Page 364 - Figure 5.7. About 3 inches from the left of the
figure and 1-3/4 inches from the bottom, a line going from
the box marked 2 to a circle with a B in it is currently
labeled ``t e f NUM (.'' Delete the e.












June 14, 1990 -6- Errata: Compiler Design in C






____________________________________________________________
Page 365 - The fourth line below Figure 5.7 should read:


best of both worlds. Examining the LR(1) machine in Figure
5.7, you are immediately
____________________________________________________________
Page 365 - Figure 5.7 (continued). The upper-case F in the
second item of State 16 should be lower case.
t-> . t * f
____________________________________________________________
Page 366 - First and third line under the Figure. The
figure numbers are called out incorrectly in the text. The
first three lines beneath the figure should read:


parenthesis first. The outer part of the machine (all of
the left half of Figure 5.7 except States 6 and 9) handles
unparenthesized expressions, and the inner part (States 6
and 9, and all of the right half of Figure 5.7) handles
parenthesized subexpressions. The parser


____________________________________________________________
Page 370 - Listing 5.2, line 14. Change the sentence
``Reduce by production n'' to read as follows


      Reduce by production n, n == -action.
____________________________________________________________
Page 371 - Listing 5.2, line 16. Change the sentence ``Shift
to state n'' to read as follows:


      Shift to state n, n == action.
____________________________________________________________
Page 373 - (Fixed in software ver. 1.00.) Listing 5.4, line
6. Remove the yy in yylookahead.
____________________________________________________________
Page 373 - (Fixed in software ver. 1.00.) Listing 5.4, line
29. Change rhs_len to rhs_lenth.
____________________________________________________________
Page 373 - Last line. Change to read as follows (the state
number is wrong):


shifts to State 1, where the only legal action is a reduce
by Production 6 if the next input
____________________________________________________________
Page 374 - Paragraph beneath table, replace ``you you'' on
third line with ``you''.
____________________________________________________________
Page 387 - (Fixed in software ver. 1.00.) Listing 5.11,
line 107. Add the word short. The repaired line looks like
this:


  107 #define YYF ((YY_TTYPE)( (unsigned short)~0 >>1 ))


June 14, 1990 -7- Errata: Compiler Design in C




____________________________________________________________
Page 388 - Second paragraph, third and fourth lines. Change
``the largest positive integer'' to ``to the largest
positive short int.'' and remove the following ``I'm.''
____________________________________________________________
Page 390 - Listing 5.12, line 199. Change the sentence
``Reduce by production n'' to read as follows (leave the
left part of the line intact):
      Reduce by production n, n == -action.
____________________________________________________________
Page 390 - Listing 5.2, line 201. Change the sentence
``Shift to state n'' to read as follows (leave the left part
of the line intact):
      Shift to state n, n == action.
____________________________________________________________
Page 425 - (Fixed in software ver. 1.00.) Lines 585-594.
Replace with the following code:


  585 if( nclose )
  586 {
  587 assort( closure_items, nclose, sizeof(ITEM*), item_cmp );
  588 nitems = move_eps( cur_state, closure_items, nclose );
  589 p = closure_items + nitems;
  590 nclose -= nitems ;
  591
  592 if( Verbose > 1 )
  593 pclosure( cur_state, p, nclose );
  594 }


____________________________________________________________
Page 440 - (Fixed in software ver. 1.00.) Listing 5.33,
replace the code on lines 1435 to 1438 with the following
(be sure that the quote marks on the left remain aligned
with previous lines):


1435 " action < 0 -- Reduce by production n, n == -action.",
1436 " action == 0 -- Accept. (ie. Reduce by production 0.)",
1437 " action > 0 -- Shift to state n, n == action.",
1438 " action == YYF -- error.",


____________________________________________________________
Page 447 - Line 14. Change "hardly every maps" to "hardly
ever maps".
____________________________________________________________
Page 452 - First line below Listing 6.2. Change ``2048'' to
``1024''.








June 14, 1990 -8- Errata: Compiler Design in C






____________________________________________________________
Page 453 - Figure 6.1. Around the middle of the figure.
Change ``2048'' to ``1024''.
____________________________________________________________
Page 475 - (Fixed in software ver. 1.00.) Listing 6.19,
Line 80. Replace the first (b) with an (s). The line should
now read:


    80 #define BIT(b,s) if( (s) & (1 << (b)) )


____________________________________________________________
Page 524 - Second line of last paragraph, remove period
after TYPE and change ``Listing 6.38'' to Listing 6.39.
____________________________________________________________
Page 527 - First line below Listing 6.40. Change ``Listing
6.40'' to Listing 6.39.
____________________________________________________________
Page 558 - (Fixed in software ver. 1.01c.) Listing 6.60,
lines 578-582. Replace with the following:


578 discard_link_chain(existing->type); /* Replace existing type */
579 existing->type = sym->type; /* chain with the current one.*/
580 existing->etype = sym->etype;
581 sym->type = sym->etype = NULL; /* Must be NULL for discard_- */
582 } /* symbol() call, below. */


____________________________________________________________
Page 573 - Fifth line from the bottom. Insert a period after
``needed''.
____________________________________________________________
Page 578 - First paragraph. Replace with the following
paragraph:


      The cell is marked as ``in use'' on line 73. The Region
element corresponding to the first cell of the allocated
space is set to the number of stack elements that are being
allocated. If more than one stack element is required for
the temporary, adjacent cells that are part of the temporary
are filled with a place marker. Other subroutines in
Listing 6.64 de-allocate a temporary variable by reseting
the equivalent Region elements to zero, de-allocate all
temporary variables currently in use, and provide access to
the high-water mark. You should take a moment and review
them now.
____________________________________________________________
Page 598 - Third paragraph, second line (which starts ``type
int for''), replace line with the following one:


type int for the undeclared identifier (on line 62 of
Listing 6.72). The




June 14, 1990 -9- Errata: Compiler Design in C




____________________________________________________________
Page 601 - First line beneath Listing 6.76. Replace
``generate'' with ``generated'':
____________________________________________________________
Page 608 - Fonts are wrong in all three marginal notes.
____________________________________________________________
Page 613 - First line of last paragraph is garbled. Since
the fix affects the formatting in the entire paragraph, a
replacement paragraph follows. Everything that doesn't fit on
page 613 should be put at the top of the next page.


      The call() subroutine at the top of Listing 6.87
generates both the call instruction and the code that
handles return values and stack clean up. It also takes
care of implicit subroutine declarations on lines 513 to
526. The action in unary->NAME creates a symbol of type int
for an undeclared identifier, and this symbol eventually
ends up here as the incoming attribute. The call()
subroutine changes the type to ``function returning int'' by
adding another link to the head of the type chain. It also
clears the implicit bit to indicate that the symbol is a
legal implicit declaration rather than an undeclared
variable. Finally, a C-code extern statement is generated
for the function.


____________________________________________________________
Page 644 - (Fixed in software ver. 1.00.) Lines 895 and
896. There is a missing double-quote mark on line 895,
insertion of which also affects the formatting on line 896.
Replace lines 895 and 896 with the following:


  895 gen("goto%s%d", L_BODY, $5 );
  896 gen(":%s%d", L_INCREMENT, $5 );


____________________________________________________________
Page 648 - (Fixed in software ver. 1.01.) Listing 6.107,
line 1, change the 128 to 256.
____________________________________________________________
Page 658 - First paragraph of section 7.2.1 should be
replaced with the following one:


      A strength reduction replaces an operation with a more
efficient operation or series of operations that yield the
same result in fewer machine clock cycles. For example,
multiplication by a power of two can be replaced by a left
shift, which executes faster on most machines. (x*8 can be
done with x<<3.) You can divide a positive number by a
power of two with a right shift (x/8 is x>>3 if x is
positive) and do a modulus division by a power of two with a
bitwise AND (x%8 is x&7).






June 14, 1990 -10- Errata: Compiler Design in C




____________________________________________________________
Page 671 - Figure 7.1, third subfigure from the bottom.
There's an asterisk missing from the apex of the tree. The
subscript is there, but the asterisk isn't. Add the
asterisk.
____________________________________________________________
Page 681 - (Fixed in software ver. 1.00.) Listing A.1,
lines 19 and 20 are missing semicolons. Change them to the
following:


19 typedef long time_t; /* for the VAX, may have to change this */
20 typedef unsigned size_t; /* for the VAX, may have to change this */


____________________________________________________________
Page 682 - Listing A.1, line 52. Delete all the text on the
line, but leave the asterisk at the far left.
____________________________________________________________
Page 696 - (Fixed in software ver. 1.00.) Listing A.4, line
40. The comment is wrong. The line should read as follows:


    40 #define _DIFFERENCE 2 /* (x in s1) and (x not in s2) */


____________________________________________________________
Page 706 - Listing A.8, line 330. Change unsigned to int:
____________________________________________________________
Page 713 - Third line from the bottom. ``nextsym()'' should
be in courier.
____________________________________________________________
Page 719 - Second line above Listing A.17, change ``tree''
to ``table'':
____________________________________________________________
Page 736 - (Fixed in software ver. 1.00.) Listing A.33,
line 34. Change to the following:


    34 PUBLIC void stop_prnt(){}


____________________________________________________________
Page 737 - (Fixed in software ver. 1.00.) Listing A.33,
line 97. Change to the following:


    97 char *str, *fmt, *argp;


____________________________________________________________
Page 743 - (Fixed in software ver. 1.00.) Listing A.36.
Delete the text (but not the line number) of line 4 (which
now says #include <fcntl.h>).
____________________________________________________________
Page 745 - Change caption of Listing A.38 to the following:
Listing 38. memiset.c- Initialize Array of int to Arbitrary Value




















June 14, 1990 -11- Errata: Compiler Design in C




____________________________________________________________
Page 758 - Listing A.45, line 49. Remove the semicolon at
the far right of the line.
____________________________________________________________
Page 803 - Just above heading for section B.2. The line
should read:


set to 100; otherwise, arg is set to 1.
____________________________________________________________
Page 803. Replace the last paragraph on page with the
following one:


      The stack, when the recursive call to erato is active, is
shown in Figure B.2. There is one major difference between
these stack frames and C stack frames: the introduction of
a second pointer called the static link. The dynamic link
is the old frame pointer, just as in C. The static link
points, not at the previously active subroutine, but at the
parent subroutine in the nesting sequence-in the
declaration. Since erato and thalia are both nested inside
calliope, their static links point at calliope's stack
frame. You can chase down the static links to access the
local variables in the outer routine's
____________________________________________________________
Page 804 - Replace Figure B.2 with the figure at the end of.
this document. (I can't nroff the figure, so this is only an
ASCII approximation.)
____________________________________________________________
Page 805 - Top of the page. Replace the top seven lines
(everything up to the paragraph that begins ``This
organization'') with the following:




stack frame. For example, clio can be accessed from erato
with the following C-code:
      r0.pp = WP(fp + 4); /* r0 = static link */
      _x = W(r0.pp - 8); /* x = cleo */
You can access polyhymnia from erato with:
      r0.pp = WP(fp + 4); /* r0 = static link */
      _x = W(r0.pp + 8); /* x = cleo */
Though it's not shown this way in the current example, it's
convenient for the frame pointer to point at the static,
rather than the dynamic link to make the foregoing
indirection a little easier to do. The static links can be
set up as follows: Assign to each subroutine a declaration
level, equivalent to the nesting level at which the
subroutine is declared. Here, calliope is a level 0
subroutine, erato is a level 1 subroutine, and so forth.
Then:
  o If a subroutine calls a subroutine at the same level, the
      static link of the called subroutine is identical to the
      static link of the calling subroutine.
  o If a subroutine at level N calls a subroutine at level
      N+1, the static link of the called subroutine points at
      the static link of the calling subroutine.
  o If a subroutine calls a subroutine at a lower (more
      outer) level, use the following algorithm:




June 14, 1990 -12- Errata: Compiler Design in C






            i = the difference in levels between the two subroutines;
            p = the static link in the calling subroutine's stack frame;
            while( --i >= 0 )
                    p = *p;
            the static link of the called subroutine = p;


Note that the difference in levels (i) can be figured at
compile time, but you must chase down the static links at
run time. Since the static link must be initialized by the
calling subroutine (the called subroutine doesn't know who
called it), it is placed beneath the return address in the
stack frame.
____________________________________________________________
Page 806 - Change caption and title of Listing C.1 as
follows:


Listing 1. A Summary of the C Grammar in Chapter Six.
____________________________________________________________
Page 819 - First full paragraph. Replace the ``the the'' on
the fourth line with a single ``the.''
____________________________________________________________
Page 821 - (Fixed in software ver. 1.01.) Listing D.1,
replace lines 14 and 15 with the following:


    14 while( yylex() )
    15 ;


____________________________________________________________
Page 821 - First two lines beneath the listing. Delete both
lines and replace with the following text:


LEX and yyleng is adjusted accordingly. Zero is returned at
end of file, -1 if the lexeme is too long.13


____________________________________________________________
Page 821 - Replace Footnote 13 at the bottom of the page
with the one at the bottom of the page you are now reading.
____________________________________________________________
Page 841 - (Fixed in software ver. 1.00.) Replace the code
on the first five lines of Listing E.2 with the following
five lines-leave the line numbers intact:


      1 %term ID /* an identifier */
      2 %term NUM /* a number */
      3 %left PLUS /* + */
      4 %left STAR /* * */
      5 %left LP RP /* ( and ) */




__________
13. UNIX lex doesn't return -1 and it doesn't modify the
        yytext or yyleng; it just returns the next input
        character.








June 14, 1990 -13- Errata: Compiler Design in C






____________________________________________________________
Page 871 - Figure E.6. Label the line between states 5 and
7 with STAR.
____________________________________________________________
Page 886 - Listing E.19. Replace lines 51 to 57 with the
following:


    51 {0} 512, line 42 : {$1=$2=newname();}
    52 {1} 513, line 42 : {freename($0);}
    53 {2} 514, line 48 : {$1=$2=newname();}
    54 {3} 515, line 49 : { yycode("%s+=%s\\n",$$,$0); freename($0); }
    55 {4} 516, line 56 : {$1=$2=newname();}
    56 {5} 517, line 57 : { yycode("%s*=%s\\n",$$,$0); freename($0);}
    57 {6} 518, line 61 : { yycode("%s=%0.*s\\n",$$,yyleng,yytext); }


____________________________________________________________
Page 887 - (Fixed in software ver. 1.00.) Listing E.19.
Replace lines 46 and 54 with the following:


    46 { yycode("%s+=%s\n",$$,$0); freename($0); } expr'
    54 { yycode("%s*=%s\n",$$,$0); freename($0); } term'


____________________________________________________________
Page 888 - (Fixed in software ver. 1.00.) Listing E.19.
Replace line 58 with the following:


    58 factor : NUM_OR_ID { yycode("%s=%0.*s\n", $$, yyleng, yytext); }


____________________________________________________________
Disk file only. (Fixed in software ver. 1.00.) I made
several changes to searchen.c (p. 747) to make the returned
path names more consistent (everything's now mapped to a
UNIX-style name). Also added a disk identifier when running
under DOS. The new version follows:


Listing 41. searchen.c--Search for File Along Path Specified in Environment


  1 #include <stdio.h>
  2 #include <tools/debug.h>
  3
  4 #define PBUF_SIZE 129 /* Maximum length of a path name + 1 */
  5
  6 #ifdef MSDOS
  7 static void unixfy( str ) /* convert name to lower case */
  8 char *str; /* and convert \'s to /'s */
  9 {
10 for(; *str; ++str )
11 if( (*str = tolower(*str)) == '\\' )
12 *str = '/';
13 }
14 #endif
15 /*----------------------------------------------------------------------*/
16








June 14, 1990 -14- Errata: Compiler Design in C


  Listing 41. continued...
17 int searchenv( filename, envname, pathname )
18 char *filename; /* file name to search for */
19 char *envname; /* environment name to use as PATH */
20 char *pathname; /* Place to put full path name when found */
21 {
22 /* Search for file by looking in the directories listed in the envname
23 * environment. Put the full path name (if you find it) into pathname.
24 * Otherwise set *pathname to 0. Unlike the DOS PATH command (and the
25 * microsoft _searchenv), you can use either a space or semicolon
26 * to separate directory names. The pathname array must be at least
27 * 128 characters. If the file is in the current directory, the path
28 * name of the current directory is appended to the front of the name.
29 *
30 * Unlike the Microsoft version, this one returns 1 on success, 0=failure
31 */
32
33 char pbuf[PBUF_SIZE];
34 char *p ;
35 char *strpbrk(), *strtok(), *getenv();
36 MS( int disk; )
37
38 getcwd( pathname, PBUF_SIZE );
39 MS( disk = tolower( *pathname ); )
40
41 concat( PBUF_SIZE, pathname, pathname, "/", filename, NULL );
42 if( access( pathname, 0 ) != -1 ) /* check current directory */
43 {
44 unixfy( pathname );
45 return 1; /* ...it's there. */
46 }
47
48 /* The file doesn't exist in the current directory. If a specific path
49 * was requested (ie. file contains \ or /) or if the environment isn't
50 * set, return failure, otherwise search for the file on the path.
51 */
52
53 if( strpbrk(filename,"\\/") || !(p = getenv(envname)) )
54 return( *pathname = '\0');
55
56 strncpy( pbuf, p, PBUF_SIZE );
57 if( p = strtok( pbuf, "; " ) )
58 {
59 do
60 {
61 MS( if( !p[1] || p[1] != ':' ) )
62 MS( sprintf( pathname,"%c:%0.90s/%0.20s",disk,p,filename); )
63 MS( else )
64 sprintf( pathname, "%0.90s/%0.20s", p, filename );
65
66 if( access( pathname, 0 ) >= 0 )
67 {
68 MS( unixfy( pathname ); )
69 return 1; /* found it */
70 }
71 }
72 while( p = strtok( NULL, "; ") );
73 }






June 14, 1990 -15- Errata: Compiler Design in C






  Listing 41. continued...
74
75 return( *pathname = '\0' );
76 }
____________________________________________________________
Disk file only. (Fixed in software ver. 1.00.) Put the
following at the top of debug.h (p. 681):


#ifndef __DEBUG_H /* Makes sure that debug.h isn't included more than */
#define __DEBUG_H /* once. Matching endif is at end of file. */


and put the following at the bottom:


#endif /* #ifdef __DEBUG_H */
____________________________________________________________
Disk file only. (Fixed in software ver. 1.00.) Put the
following at the top of set.h (p. 696).


      #include <tools/debug.h>
____________________________________________________________
Disk file only. (Fixed in software ver. 1.00.) Insert the
following into the brace-processing code, between lines 115
and 116 of parser.lex on page 273:


                                                        if( i == '\n' && in_string )
                                                        {
                                                                lerror( WARNING,
                                                                                      "Newline in string, inserting \"\n");
                                                                in_string = 0;
                                                        }
____________________________________________________________
Disk file only. (Fixed in software ver. 1.01c.) Add a
semicolon to the end of the extern char *bsearch() statement
in the <search.h> file (which is on the disk, but not in the
book).
____________________________________________________________
Disk file only. (Fixed in software ver. 1.01.) The do_unop
subroutine on page 604 (Line 177 of Listing 6.79) wasn't
handling incoming constant values correctly and it wasn't
doing any semantic-error checking at all. It's been
replaced by the following code. (Instructions are now
generated only if the incoming value isn't a constant,
otherwise the constant value at the end of the link chain is
just modified by performing the indicated operation at
compile time.)


177 value *do_unop( op, val )
178 int op;
179 value *val;
180 {
181 char *op_buf = "=?" ;
182 int i;
183
184 if( op != '!' ) /* ~ or unary - */
185 {
186 if( !IS_CHAR(val->type) && !IS_INT(val->type) )
187 yyerror( "Unary operator requires integral argument\n" );




June 14, 1990 -16- Errata: Compiler Design in C




Listing 43. continued...
188
189 else if( IS_UNSIGNED(val->type) && op == '-' )
190 yyerror( "Minus has no meaning on an unsigned operand\n" );
191
192 else if( IS_CONSTANT( val->type ) )
193 do_unary_const( op, val );
194 else
195 {
196 op_buf[1] = op;
197 gen( op_buf, val->name, val->name );
198 }
199 }
200 else /* ! */
201 {
202 if( IS_AGGREGATE( val->type ) )
203 yyerror("May not apply ! operator to aggregate type\n");
204
205 else if( IS_INT_CONSTANT( val->type ) )
206 do_unary_const( '!', val );
207 else
208 {
209 gen( "EQ", rvalue(val), "0" ); /* EQ(x, 0) */
210 gen( "goto%s%d", L_TRUE, i = tf_label() ); /* goto T000; */
211 val = gen_false_true( i, val ); /* fall thru to F */
212 }
213 }
214 return val;
215 }
216 /*----------------------------------------------------------------------*/
217 do_unary_const( op, val )
218 int op;
219 value *val;
220 {
221 /* Handle unary constants by modifying the constant's value. */
222
223 link *t = val->type;
224
225 if( IS_INT(t) )
226 {
227 switch( op )
228 {
229 case '~': t->V_INT = ~t->V_INT; break;
230 case '-': t->V_INT = -t->V_INT; break;
231 case '!': t->V_INT = !t->V_INT; break;
232 }
233 }
234 else if( IS_LONG(t) )
235 {
236 switch( op )
237 {
238 case '~': t->V_LONG = ~t->V_LONG; break;
239 case '-': t->V_LONG = -t->V_LONG; break;
240 case '!': t->V_LONG = !t->V_LONG; break;
241 }


June 14, 1990 -17- Errata: Compiler Design in C




Listing 43. continued...
242 }
243 else
244 yyerror("INTERNAL do_unary_const: unexpected type\n");
245 }






































































































June 14, 1990 -18- Errata: Compiler Design in C


ASCII Approximation of new Figure B.2 on page 804. Static links have been
moved beneath the return address.




                +------------------+ ------------------------------
                | | terpsichore ^
                +------------------+ |
        +---|-* dynamic link | <- fp |
        | +------------------+ |
        | | return address | erato
        | +------------------+ |
+<--|---|-* static link | |
| | +------------------+ |
| V | 3 | urania |
| \ +------------------+ ---------------------------X---
| \ | | terpsichore |
V \ +------------------+ |
| +---|-* dynamic link | |
| | +------------------+ |
| | | return address | erato
| | +------------------+ |
|<--|---|-* static link | |
| | +------------------+ |
| V | 2 | urania |
| \ +------------------+ ---------------------------X---
| \ | | melpomene |
V \ +------------------+ |
| +--\|-* dynamic link | |
| | +------------------+ |
| | | return address | thalia
| | +------------------+ |
|<--|---|-* static link | |
| | +------------------+ |
| V | 1 | euterpe |
| \ +------------------+ ---------------------------X---
| \ | | clio |
V \ +------------------+ |
| -|-* dynamic link | |
| +------------------+ |
| | return address | calliope
| +------------------+ |
+------>|-* static link | |
                +------------------+ |
                | | polyhymnia V
                +------------------+ -------------------------------


--


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.