Re: need Tools in "Crafting a Compiler with C"

Jerry Leichter <leichter@smarts.com>
29 Jan 1996 17:49:53 -0500

          From comp.compilers

Related articles
need Tools in "Crafting a Compiler with C" simon@iis.sinica.edu.tw (1996-01-23)
Re: need Tools in "Crafting a Compiler with C" rasumner@ccnga.uwaterloo.ca (1996-01-25)
Re: need Tools in "Crafting a Compiler with C" leichter@smarts.com (Jerry Leichter) (1996-01-29)
| List of all articles for this month |

From: Jerry Leichter <leichter@smarts.com>
Newsgroups: comp.compilers
Date: 29 Jan 1996 17:49:53 -0500
Organization: System Management ARTS
References: 96-01-064 96-01-076
Keywords: books, tools

>Ming-Shing Su <simon@iis.sinica.edu.tw> wrote:
> There are some tools in the book "Crafting a Compiler
>with C" written by Charles N. Fisher, such as ScanGen, LLGen,
>and LALRGen. [Are they available on the net?]


I taught a course using this text a couple of years back. I searched
around at that time, and found three sources:


1. The publisher. If you're using this as the textbook in a
course, talk to your publisher's rep. The tools are
available as a set of 6 DOS floppies. What's on the
floppies is the tools and some sample assignments and
answers for those assignments, all from a course given
somewhere.


I have copies of this stuff on-line, but the floppies come
with copyrights restricting re-distribution, so I can't
make them available.


2. Anonymous FTP from FTP.CS.UMN.EDU.


3. Anonymous FTP from KAESE.CS.WISC.EDU.


The software from the three sources is *different*. As far as I can
tell, the basic software from source 1 is the oldest, that from source
2 is somewhere in between, and that from source 3 is the newest. (As
I recall, LeBlanc, the other author of the text, is at Wisconsin. I
think I found the other site with Gopher.) The code from source 1 is
the most extensively commented, though it looks as if the comments are
mainly the result of merging some separate "readme" files with the
source - at the FTP sites, the "readme" files remain separate.


Be aware that in general the code is essentially uncommented and not
very clearly written. (There is reasonable documentation on *usage*
in separate files, which expand on what appears in the textbook
itself.) It also isn't clear what Pascal compiler it was written for
- I had a bit of trouble getting some of it to work. Expect to put in
a couple of hours of fine-tuning on at least some of the files.


I've attached a context diff for the version of scangen.p found at
source 3. I can no longer remember exactly what I changed because
otherwise I couldn't compile the code, and what I changed for other
reasons. Most of the changes increased the size of some internal
tables and, in particular, the length of the longest keyword - there
was some keyword in Modula-2 - probably "IMPLEMENTATION" - that the
original couldn't handle. Changing something so simple has unexpected
ramifications throughout the code, since it's full of "magic numbers"
that are not obviously related to the MaxString constant.


With these changes, I was able to successfully compile and use scangen
on both a VMS system using VAX Pascal, and a SunOS system using (most
likely, I no longer remember for certain) p2c.


I never worked on patch files for any of the other code.


Good luck!
-- Jerry


*** scangen.p_org
--- scangen.p
**************
*** 39,46
    LABEL 1; {Used to simulate STOP stmt}


    CONST
! MaxDFAState = 200;
! MaxTokenNum = 100;
            MaxClass = 100;
            Epsilon = 0;
            MaxSymbol = 150;
--- 39,46 -----
    LABEL 1; {Used to simulate STOP stmt}


    CONST
! MaxDFAState = 300;
! MaxTokenNum = 200;
            MaxClass = 100;
            Epsilon = 0;
            MaxSymbol = 300;
**************
*** 43,51
            MaxTokenNum = 100;
            MaxClass = 100;
            Epsilon = 0;
! MaxSymbol = 150;
! MaxString = 12;
! MaxReservedWord = 100;
            MaxChar = 127; { This is set for ASCII; change to 255 for EBCDIC }


    { CONST from in.i}
--- 43,51 -----
            MaxTokenNum = 200;
            MaxClass = 100;
            Epsilon = 0;
! MaxSymbol = 300;
! MaxString = 16;
! MaxReservedWord = 200;
            MaxChar = 127; { This is set for ASCII; change to 255 for EBCDIC }


    { CONST from in.i}
**************
*** 60,66


            MaxNDFAState = 1000;


! Version = ' Version 2.0 (12/82)';


    TYPE


--- 60,66 -----


            MaxNDFAState = 1000;


! Version = ' Version 2.0:jsl (12/82:15Feb94)';


    TYPE


**************
*** 97,103
                          ListRE : (List : ListofCharClass;
                                              TossSaveFlag2 : TossSave);
                          END;
! SymbolType = (TokenSymbol,AuxSymbol,ClassSymbol,SetSymbol);
            SymbolRec = RECORD
                      SymbolName : String;
                          case SymbolTag : SymbolType OF
--- 97,103 -----
                          ListRE : (List : ListofCharClass;
                                              TossSaveFlag2 : TossSave);
                          END;
! SymbolType = (TokenSymbol,AuxSymbol,ClassSymbol(*?,SetSymbol*));
            SymbolRec = RECORD
                      SymbolName : String;
                          case SymbolTag : SymbolType OF
**************
*** 296,319
                      ScannerRSW[5].Major:=RswClass;
                      ScannerRSW[6].Major:=RswNot;
                      ScannerRSW[7].Major:=RswOptions;
! ScannerRSW[1].Chars := 'TOKEN ';
! ScannerRSW[2].Chars := 'TOSS ';
! ScannerRSW[3].Chars := 'EXCEPT ';
! ScannerRSW[4].Chars := 'DEFINITION ';
! ScannerRSW[5].Chars := 'CLASS ';
! ScannerRSW[6].Chars := 'NOT ';
! ScannerRSW[7].Chars := 'OPTIONS ';
! OptionsTable[DebugOption] := 'Debug ';
! OptionsTable[EpsilonOption] := 'Epsilon ';
! OptionsTable[IdfaOption] := 'Idfa ';
! OptionsTable[ListOption] := 'List ';
! OptionsTable[DfaOption] := 'Dfa ';
! OptionsTable[NdfaOption] := 'Ndfa ';
! OptionsTable[ReportOption] := 'Report ';
! OptionsTable[TestOption] := 'Test ';
! OptionsTable[TablesOption] := 'Tables ';
! OptionsTable[OptimizeOption] := 'Optimize ';
! OptionsTable[UnreachableOption]:= 'Unreachable ';
                      OptionsSet := [];
                      END;


--- 296,319 -----
                      ScannerRSW[5].Major:=RswClass;
                      ScannerRSW[6].Major:=RswNot;
                      ScannerRSW[7].Major:=RswOptions;
! ScannerRSW[1].Chars := 'TOKEN ';
! ScannerRSW[2].Chars := 'TOSS ';
! ScannerRSW[3].Chars := 'EXCEPT ';
! ScannerRSW[4].Chars := 'DEFINITION ';
! ScannerRSW[5].Chars := 'CLASS ';
! ScannerRSW[6].Chars := 'NOT ';
! ScannerRSW[7].Chars := 'OPTIONS ';
! OptionsTable[DebugOption] := 'Debug ';
! OptionsTable[EpsilonOption] := 'Epsilon ';
! OptionsTable[IdfaOption] := 'Idfa ';
! OptionsTable[ListOption] := 'List ';
! OptionsTable[DfaOption] := 'Dfa ';
! OptionsTable[NdfaOption] := 'Ndfa ';
! OptionsTable[ReportOption] := 'Report ';
! OptionsTable[TestOption] := 'Test ';
! OptionsTable[TablesOption] := 'Tables ';
! OptionsTable[OptimizeOption] := 'Optimize ';
! OptionsTable[UnreachableOption]:= 'Unreachable ';
                      OptionsSet := [];
                      END;


**************
*** 985,991
    NumLists := 0;
    WITH SymbolTable[1] DO
            BEGIN
! SymbolName := 'EPSILON ';
            SymbolTag := ClassSymbol;
            ClassNum := Epsilon
            END;
--- 985,991 -----
    NumLists := 0;
    WITH SymbolTable[1] DO
            BEGIN
! SymbolName := 'EPSILON ';
            SymbolTag := ClassSymbol;
            ClassNum := Epsilon
            END;
**************
*** 1217,1224
                      WITH SymbolTable[I] DO
                                IF SymbolTag = ClassSymbol THEN
                                          ClassNames[ClassNum] := SymbolName;
! NumPages := NumClasses DIV 9;
! IF (Numclasses MOD 9) <> 0 THEN NumPages := NumPages + 1;
            FOR I := 1 TO NumPages DO
                      BEGIN
                      PAGE(Output);
--- 1217,1224 -----
                      WITH SymbolTable[I] DO
                                IF SymbolTag = ClassSymbol THEN
                                          ClassNames[ClassNum] := SymbolName;
! NumPages := NumClasses DIV 6;
! IF (Numclasses MOD 6) <> 0 THEN NumPages := NumPages + 1;
            FOR I := 1 TO NumPages DO
                      BEGIN
                      PAGE(Output);
**************
*** 1223,1230
                      BEGIN
                      PAGE(Output);
                      WRITE(' ');
! Lo := (i-1)*9+1;
! IF (I*9) <= NumClasses THEN Hi := I*9
                                ELSE Hi := NumClasses;
                      FOR C := Lo TO Hi DO
                                WRITE(ClassNames[C]:12,' ');
--- 1223,1230 -----
                      BEGIN
                      PAGE(Output);
                      WRITE(' ');
! Lo := (i-1)*6+1;
! IF (I*6) <= NumClasses THEN Hi := I*6
                                ELSE Hi := NumClasses;
                      FOR C := Lo TO Hi DO
                                WRITE(ClassNames[C]:12,' ');
**************
*** 1728,1734
                      P : Subset;
                      First : BOOLEAN;
                      ConflictFlag,Found : BOOLEAN;
! Name : String;
                      LastTossFlag : TossSave;
                      S : INTEGER;
                      State : NDFAState;
--- 1728,1734 -----
                      P : Subset;
                      First : BOOLEAN;
                      ConflictFlag,Found : BOOLEAN;
! (*?Name : String;*)
                      LastTossFlag : TossSave;
                      S : INTEGER;
                      State : NDFAState;
**************
*** 2153,2159
    VAR
            CurrentState,NextState,NewState : DFAState;
            C : CharClass;
! CurrentGroup : 0..MaxDFAState;
            NewTrans,Trans : Transition;
            MoveTrans : BOOLEAN;
    BEGIN
--- 2153,2159 -----
    VAR
            CurrentState,NextState,NewState : DFAState;
            C : CharClass;
! (*?CurrentGroup : 0..MaxDFAState;*)
            NewTrans,Trans : Transition;
            MoveTrans : BOOLEAN;
    BEGIN
**************
*** 2405,2411
    VAR
            T : Transition;
            R : ReservedWordIndex;
! C : Char;
            Cl : CharClass;
            D : DFAState;
            S : SymbolIndex;
--- 2405,2411 -----
    VAR
            T : Transition;
            R : ReservedWordIndex;
! (*?C : Char;*)
            Cl : CharClass;
            D : DFAState;
            S : SymbolIndex;


--


Post a followup to this message

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