home *** CD-ROM | disk | FTP | other *** search
- PROGRAM PRETTYPRINT (* FROM PROGIN TO PROGOUT *);
- CONST
- MAXSYMBOLSIZE = 200; (* THE MAXIMUM SIZE (IN CHARACTERS) OF A *)
- (* SYMBOL SCANNED BY THE LEXICAL SCANNER. *)
- MAXSTACKSIZE = 100; (* THE MAXIMUM NUMBER OF SYMBOLS CAUSING *)
- (* INDENTATION THAT MAY BE STACKED. *)
- MAXKEYLENGTH = 10; (* THE MAXIMUM LENGTH (IN CHARACTERS) OF A *)
- (* PASCAL RESERVED KEYWORD. *)
- MAXLINESIZE = 79; (* THE MAXIMUM SIZE (IN CHARACTERS) OF A *)
- (* LINE OUTPUT BY THE PRETTYPRINTER. *)
- SLOFAIL1 = 77; (* UP TO THIS COLUMN POSITION, EACH TIME *)
- (* "INDENTBYTAB" IS INVOKED, THE MARGIN *)
- (* WILL BE INDENTED BY "INDENT1". *)
- SLOFAIL2 = 79; (* UP TO THIS COLUMN POSITION, EACH TIME *)
- (* "INDENTBYTAB" IS INVOKED, THE MARGIN *)
- (* WILL BE INDENTED BY "INDENT2". BEYOND *)
- (* THIS, NO INDENTATION OCCURS. *)
- INDENT1 = 2;
- INDENT2 = 1;
- SPACE = ' ';
- TYPE
- KEYSYMBOL = ( PROGSYM, FUNCSYM, PROCSYM,
- LABELSYM, CONSTSYM, TYPESYM, VARSYM,
- BEGINSYM, REPEATSYM, RECORDSYM,
- CASESYM, CASEVARSYM, OFSYM,
- FORSYM, WHILESYM, WITHSYM, DOSYM,
- IFSYM, THENSYM, ELSESYM,
- ENDSYM, UNTILSYM,
- BECOMES, OPENCOMMENT, CLOSECOMMENT,
- SEMICOLON, COLON, EQUALS,
- OPENPAREN, CLOSEPAREN, PERIOD,
- ENDOFFILE,
- OTHERSYM );
- OPTION = ( CRSUPPRESS,
- CRBEFORE,
- BLANKLINEBEFORE,
- DINDENTONKEYS,
- DINDENT,
- SPACEBEFORE,
- SPACEAFTER,
- GOBBLESYMBOLS,
- INDENTBYTAB,
- INDENTTOCLP,
- CRAFTER );
- OPTIONSET = SET OF OPTION;
- KEYSYMSET = SET OF KEYSYMBOL;
- TABLEENTRY = RECORD
- OPTIONSSELECTED : OPTIONSET;
- DINDENTSYMBOLS : KEYSYMSET;
- GOBBLETERMINATORS: KEYSYMSET
- END;
- OPTIONTABLE = ARRAY [ KEYSYMBOL ] OF TABLEENTRY;
- KEY = PACKED ARRAY [ 1..MAXKEYLENGTH ] OF CHAR;
- KEYWORDTABLE = ARRAY [ PROGSYM..UNTILSYM ] OF KEY;
- SPECIALCHAR = PACKED ARRAY [ 1..2 ] OF CHAR;
- DBLCHRSET = SET OF BECOMES..OPENCOMMENT;
- DBLCHARTABLE = ARRAY [ BECOMES..OPENCOMMENT ] OF SPECIALCHAR;
- SGLCHARTABLE = ARRAY [ SEMICOLON..PERIOD ] OF CHAR;
- STRINGY = ARRAY [ 1..MAXSYMBOLSIZE ] OF CHAR;
- SYMBOL = RECORD
- NAME : KEYSYMBOL;
- VALYOO : STRINGY;
- LENGTH : INTEGER;
- SPACESBEFORE: INTEGER;
- CRSBEFORE : INTEGER
- END;
- SYMBOLINFO = ^SYMBOL;
- CHARNAME = ( LETTER, DIGIT, BLANK, QUOTE,
- ENDOFLINE, FILEMARK, OTHERCHAR );
- CHARINFO = RECORD
- NAME : CHARNAME;
- VALYOO: CHAR
- END;
- STACKENTRY = RECORD
- INDENTSYMBOL: KEYSYMBOL;
- PREVMARGIN : INTEGER
- END;
- SYMBOLSTACK = ARRAY [ 1..MAXSTACKSIZE ] OF STACKENTRY;
- VAR
- SAWCOMOPEN, SAWCOMCLOSE, SAWQUOTEDSTRING, INACOMMENT : BOOLEAN;
- PROGIN, PROGOUT : STRING(20);
- RECORDSEEN: BOOLEAN;
- CURRCHAR,
- NEXTCHAR: CHARINFO;
- CURRSYM,
- NEXTSYM: SYMBOLINFO;
- CRPENDING: BOOLEAN;
- PPOPTION: OPTIONTABLE;
- KEYWORD: KEYWORDTABLE;
- DBLCHARS: DBLCHRSET;
- DBLCHAR: DBLCHARTABLE;
- SGLCHAR: SGLCHARTABLE;
- STACK: SYMBOLSTACK;
- TOP : INTEGER;
- STARTPOS, (* STARTING POSITION OF LAST SYMBOL WRITTEN *)
- CURRLINEPOS,
- CURRMARGIN : INTEGER;
- FIN, FOUT : TEXT;
- PROCEDURE GETCHAR(
- (* UPDATING *) VAR NEXTCHAR : CHARINFO;
- (* RETURNING *) VAR CURRCHAR : CHARINFO );
- BEGIN (* GETCHAR *)
- CURRCHAR := NEXTCHAR;
- WITH NEXTCHAR DO
- BEGIN
- IF EOF(FIN)
- THEN
- NAME := FILEMARK
- ELSE IF EOLN(FIN)
- THEN
- NAME := ENDOFLINE
- ELSE IF ( ( FIN^ IN [ 'a' .. 'z'] ) AND (NOT SAWQUOTEDSTRING) )
- THEN BEGIN
- FIN^ := CHR ( ORD ( FIN^ ) - 32 );
- NAME := LETTER
- END
- ELSE IF SAWCOMOPEN THEN
- BEGIN
- SAWCOMOPEN := FALSE;
- FIN^ := '*';
- NAME := OTHERCHAR
- END
- ELSE IF SAWCOMCLOSE THEN
- BEGIN
- SAWCOMCLOSE := FALSE;
- FIN^ := ')';
- NAME := OTHERCHAR
- END
- ELSE IF FIN^ = '{' THEN
- BEGIN
- SAWCOMOPEN := TRUE;
- INACOMMENT := TRUE;
- FIN^ := '(';
- NAME := OTHERCHAR
- END
- ELSE IF FIN^ = '}' THEN
- BEGIN
- SAWCOMCLOSE := TRUE;
- INACOMMENT := FALSE;
- FIN^ := '*';
- NAME := OTHERCHAR
- END
- ELSE IF FIN^ IN ['A' .. 'Z'] THEN
- NAME := LETTER
- ELSE IF FIN^ IN ['0'..'9'] THEN
- NAME := DIGIT
- ELSE IF ( FIN^ = '''') AND ( NOT INACOMMENT ) THEN
- IF SAWQUOTEDSTRING THEN
- BEGIN
- NAME := QUOTE;
- SAWQUOTEDSTRING := FALSE
- END
- ELSE
- BEGIN
- NAME := QUOTE;
- SAWQUOTEDSTRING := TRUE
- END
- ELSE IF FIN^ = SPACE THEN
- NAME := BLANK
- ELSE NAME := OTHERCHAR;
- IF NAME IN [ FILEMARK, ENDOFLINE ] THEN
- VALYOO := SPACE
- ELSE
- VALYOO := FIN^;
- IF (NAME <> FILEMARK) AND (NOT SAWCOMOPEN) AND (NOT SAWCOMCLOSE)
- THEN GET(FIN)
- END (* WITH *)
- END; (* GETCHAR *)
- PROCEDURE STORENEXTCHAR(
- (* UPDATING *) VAR LENGTH : INTEGER;
- VAR CURRCHAR,
- NEXTCHAR : CHARINFO;
- (* PLACING IN *) VAR VALYOO : STRINGY );
- BEGIN (* STORENEXTCHAR *)
- GETCHAR(
- (* UPDATING *) NEXTCHAR,
- (* RETURNING *) CURRCHAR );
- IF LENGTH < MAXSYMBOLSIZE THEN
- BEGIN
- LENGTH := LENGTH + 1;
- VALYOO [LENGTH] := CURRCHAR.VALYOO
- END
- END; (* STORENEXTCHAR *)
- PROCEDURE SKIPSPACES(
- (* UPDATING *) VAR CURRCHAR,
- NEXTCHAR : CHARINFO;
- (* RETURNING *) VAR SPACESBEFORE,
- CRSBEFORE : INTEGER );
- BEGIN (* SKIPSPACES *)
- SPACESBEFORE := 0;
- CRSBEFORE := 0;
- WHILE NEXTCHAR.NAME IN [ BLANK, ENDOFLINE ] DO
- BEGIN
- GETCHAR(
- (* UPDATING *) NEXTCHAR,
- (* RETURNING *) CURRCHAR );
- CASE CURRCHAR.NAME OF
- BLANK : SPACESBEFORE := SPACESBEFORE + 1;
- ENDOFLINE : BEGIN
- CRSBEFORE := CRSBEFORE + 1;
- SPACESBEFORE := 0
- END
- END (* CASE *)
- END (* WHILE *)
- END; (* SKIPSPACES *)
- PROCEDURE GETCOMMENT(
- (* UPDATING *) VAR CURRCHAR,
- NEXTCHAR : CHARINFO;
- VAR NAME : KEYSYMBOL;
- VAR VALYOO : STRINGY;
- VAR LENGTH : INTEGER );
- BEGIN (* GETCOMMENT *)
- INACOMMENT := TRUE;
- NAME := OPENCOMMENT;
- WHILE NOT( ((CURRCHAR.VALYOO = '*') AND (NEXTCHAR.VALYOO = ')'))
- OR (NEXTCHAR.NAME = ENDOFLINE)
- OR (NEXTCHAR.NAME = FILEMARK)) DO
- STORENEXTCHAR(
- (* UPDATING *) LENGTH,
- CURRCHAR,
- NEXTCHAR,
- (* IN *) VALYOO );
- IF (CURRCHAR.VALYOO = '*') AND (NEXTCHAR.VALYOO = ')') THEN
- BEGIN
- STORENEXTCHAR(
- (* UPDATING *) LENGTH,
- CURRCHAR,
- NEXTCHAR,
- (* IN *) VALYOO );
- NAME := CLOSECOMMENT;
- INACOMMENT := FALSE
- END
- END; (* GETCOMMENT *)
- FUNCTION IDTYPE( (* OF *) VALYOO : STRINGY;
- (* USING *) LENGTH : INTEGER )
- (* RETURNING *) : KEYSYMBOL;
- VAR
- I: INTEGER;
- KEYVALYOO: KEY;
- HIT: BOOLEAN;
- THISKEY: KEYSYMBOL;
- BEGIN (* IDTYPE *)
- IDTYPE := OTHERSYM;
- IF LENGTH <= MAXKEYLENGTH THEN
- BEGIN
- FOR I := 1 TO LENGTH DO
- KEYVALYOO [I] := VALYOO [I];
- FOR I := LENGTH+1 TO MAXKEYLENGTH DO
- KEYVALYOO [I] := SPACE;
- THISKEY := PROGSYM;
- HIT := FALSE;
- WHILE NOT(HIT OR (THISKEY = SUCC(UNTILSYM))) DO
- IF KEYVALYOO = KEYWORD [THISKEY] THEN
- HIT := TRUE
- ELSE
- THISKEY := SUCC(THISKEY);
- IF HIT THEN IDTYPE := THISKEY
- END;
- END; (* IDTYPE *)
- PROCEDURE GETIDENTIFIER(
- (* UPDATING *) VAR CURRCHAR,
- NEXTCHAR : CHARINFO;
- (* RETURNING *) VAR NAME : KEYSYMBOL;
- VAR VALYOO : STRINGY;
- VAR LENGTH : INTEGER );
- BEGIN (* GETIDENTIFIER *)
- WHILE NEXTCHAR.NAME IN [ LETTER, DIGIT ] DO
- STORENEXTCHAR( (* UPDATING *) LENGTH,
- CURRCHAR,
- NEXTCHAR,
- (* IN *) VALYOO );
- NAME := IDTYPE( (* OF *) VALYOO, (* USING *) LENGTH );
- IF NAME IN [ RECORDSYM, CASESYM, ENDSYM ] THEN
- CASE NAME OF
- RECORDSYM : RECORDSEEN := TRUE;
- CASESYM : IF RECORDSEEN THEN
- NAME := CASEVARSYM;
- ENDSYM : RECORDSEEN := FALSE
- END (* CASE *)
- END; (* GETIDENTIFIER *)
- PROCEDURE GETNUMBER(
- (* UPDATING *) VAR CURRCHAR,
- NEXTCHAR : CHARINFO;
- (* RETURNING *) VAR NAME : KEYSYMBOL;
- VAR VALYOO : STRINGY;
- VAR LENGTH : INTEGER );
- BEGIN (* GETNUMBER *)
- WHILE NEXTCHAR.NAME = DIGIT DO
- STORENEXTCHAR(
- (* UPDATING *) LENGTH,
- CURRCHAR,
- NEXTCHAR,
- (* IN *) VALYOO );
- NAME := OTHERSYM
- END; (* GETNUMBER *)
- PROCEDURE GETCHARLITERAL(
- (* UPDATING *) VAR CURRCHAR,
- NEXTCHAR : CHARINFO;
- (* RETURNING *) VAR NAME : KEYSYMBOL;
- VAR VALYOO : STRINGY;
- VAR LENGTH : INTEGER );
- BEGIN (* GETCHARLITERAL *)
- WHILE NEXTCHAR.NAME = QUOTE DO
- BEGIN
- STORENEXTCHAR(
- (* UPDATING *) LENGTH,
- CURRCHAR,
- NEXTCHAR,
- (* IN *) VALYOO );
- WHILE NOT(NEXTCHAR.NAME IN [ QUOTE, ENDOFLINE, FILEMARK ]) DO
- STORENEXTCHAR(
- (* UPDATING *) LENGTH,
- CURRCHAR,
- NEXTCHAR,
- (* IN *) VALYOO );
- IF NEXTCHAR.NAME = QUOTE
- THEN
- STORENEXTCHAR(
- (* UPDATING *) LENGTH,
- CURRCHAR,
- NEXTCHAR,
- (* IN *) VALYOO )
- END;
- NAME := OTHERSYM
- END; (* GETCHARLITERAL *)
- FUNCTION CHARTYPE( (* OF *) CURRCHAR,
- NEXTCHAR : CHARINFO )
- (* RETURNING *) : KEYSYMBOL;
- VAR
- NEXTTWOCHARS: SPECIALCHAR;
- HIT: BOOLEAN;
- THISCHAR: KEYSYMBOL;
- BEGIN (* CHARTYPE *)
- NEXTTWOCHARS[1] := CURRCHAR.VALYOO;
- NEXTTWOCHARS[2] := NEXTCHAR.VALYOO;
- THISCHAR := BECOMES;
- HIT := FALSE;
- WHILE NOT(HIT OR (THISCHAR = CLOSECOMMENT)) DO
- IF NEXTTWOCHARS = DBLCHAR [THISCHAR] THEN
- HIT := TRUE
- ELSE
- THISCHAR := SUCC(THISCHAR);
- IF NOT HIT THEN
- BEGIN
- THISCHAR := SEMICOLON;
- WHILE NOT(HIT OR (PRED(THISCHAR) = PERIOD)) DO
- IF CURRCHAR.VALYOO = SGLCHAR [THISCHAR] THEN
- HIT := TRUE
- ELSE
- THISCHAR := SUCC(THISCHAR)
- END;
- IF HIT THEN
- CHARTYPE := THISCHAR
- ELSE
- CHARTYPE := OTHERSYM
- END; (* CHARTYPE *)
- PROCEDURE GETSPECIALCHAR(
- (* UPDATING *) VAR CURRCHAR,
- NEXTCHAR : CHARINFO;
- (* RETURNING *) VAR NAME : KEYSYMBOL;
- VAR VALYOO : STRINGY;
- VAR LENGTH : INTEGER );
- BEGIN (* GETSPECIALCHAR *)
- STORENEXTCHAR(
- (* UPDATING *) LENGTH,
- CURRCHAR,
- NEXTCHAR,
- (* IN *) VALYOO );
- NAME := CHARTYPE( (* OF *) CURRCHAR,
- NEXTCHAR );
- IF NAME IN DBLCHARS
- THEN
- STORENEXTCHAR(
- (* UPDATING *) LENGTH,
- CURRCHAR,
- NEXTCHAR,
- (* IN *) VALYOO )
- END; (* GETSPECIALCHAR *)
- PROCEDURE GETNEXTSYMBOL(
- (* UPDATING *) VAR CURRCHAR,
- NEXTCHAR : CHARINFO;
- (* RETURNING *) VAR NAME : KEYSYMBOL;
- VAR VALYOO : STRINGY;
- VAR LENGTH : INTEGER );
- BEGIN (* GETNEXTSYMBOL *)
- CASE NEXTCHAR.NAME OF