home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / dtx9202 / pretty / prparser.mod < prev    next >
Encoding:
Modula Implementation  |  1991-02-18  |  23.0 KB  |  797 lines

  1.  
  2. IMPLEMENTATION MODULE PRPARSER;
  3. (*****************************************************************************)
  4. (*                              Modula-2 Parser                              *)
  5. (*                       (c) Peter Engels       1990                         *)
  6. (*****************************************************************************)
  7.  
  8. FROM PRFILES IMPORT Comments;
  9.  
  10. FROM PRSCAN IMPORT SymbolTyp,TokenTyp,GetToken,ReadChar,ReadAgain,InitScanner;
  11.  
  12. FROM PRHASH IMPORT SearchInHashTable;
  13.  
  14. FROM FIO IMPORT OpenRead,Create,Close,EOF,RdChar,File,Rename,Erase,
  15.                 PrinterDevice,PathStr,Exists,AssignBuffer,IOcheck,IOresult,
  16.                 WrChar,WrStr,WrLn,WrCharRep,StandardOutput;
  17.  
  18. IMPORT IO;
  19.  
  20. FROM FIOR IMPORT ChangeExtension;
  21.  
  22. FROM Str IMPORT Copy,Compare;
  23.  
  24. FROM Lib IMPORT FatalError;
  25.  
  26. CONST BufferSize = 10 * 512;
  27.  
  28. VAR WriteBuffer,ReadBuffer : ARRAY [1..BufferSize] OF BYTE;
  29.  
  30.   PROCEDURE MakePretty (sourcename,destname : ARRAY OF CHAR);
  31.  
  32.   TYPE termset = SET OF SymbolTyp;
  33.  
  34.   CONST shift = 2; (* Einruecktiefe *)
  35.         maxwidth = 77;
  36.         terminators = termset {semicolon,bar,endsy,ifsy,elsifsy,elsesy,casesy,
  37.                       loopsy,repeatsy,untilsy,withsy,whilesy,forsy};
  38.         BlankBefore = termset {abssy..withsy,alias,colon,define,equal..lpar,
  39.                       notequal,operationsy,shiftl,shiftr};
  40.         Test = FALSE; (* für Testzwecke auf TRUE - Ausgabe auf Schirm *)
  41.  
  42.   VAR ColNum,lastpos : CARDINAL;
  43.       nocr,defmodule : BOOLEAN;
  44.       source,destination : File;
  45.       token : TokenTyp;
  46.       lastsymbol : SymbolTyp;
  47.       writename : PathStr;
  48.  
  49.     PROCEDURE closefiles (error : BOOLEAN);
  50.  
  51.     VAR errorcode : CARDINAL;
  52.  
  53.     BEGIN
  54.       Close (source);
  55. (*%F Test *)
  56.       IF destination # PrinterDevice THEN
  57.         Close (destination);
  58.         IF NOT error THEN
  59.           IF Exists (destname) THEN
  60.             Erase (destname)
  61.           END;
  62.           errorcode := IOresult ();
  63.           IF errorcode = 0 THEN
  64.             Rename (writename,destname)
  65.           ELSIF errorcode = 5 THEN
  66.             IO.WrLn;
  67.             IO.WrStr ('Access denied' + CHR (7));
  68.             IO.WrLn;
  69.             Erase (writename)
  70.           ELSE
  71.             IO.WrLn;
  72.             IO.WrStr ('IO-Error' + CHR (7));
  73.             IO.WrLn;
  74.             Erase (writename)
  75.           END;
  76.         END
  77.       END
  78. (*%E*)
  79.     END closefiles;
  80.  
  81.     PROCEDURE errorhandler (msg : ARRAY OF CHAR);
  82.  
  83.     BEGIN
  84.       closefiles (TRUE);
  85.       IO.WrChar (7C);
  86.       FatalError (msg)
  87.     END errorhandler;
  88.  
  89.     PROCEDURE SetCol (f : File;
  90.                       pos : CARDINAL);
  91.  
  92.     BEGIN
  93.       WrCharRep (f,' ',pos);
  94.       INC (ColNum,pos)
  95.     END SetCol;
  96.  
  97.     PROCEDURE crlf (depth : CARDINAL);
  98.  
  99.     BEGIN
  100.       lastpos := depth + token.length;
  101.       IF nocr THEN
  102.         nocr := FALSE
  103.       ELSE
  104.         WrLn (destination);
  105.         ColNum := 0;
  106.         SetCol (destination,depth);
  107.         lastsymbol := notallowed
  108.       END
  109.     END crlf;
  110.  
  111.     PROCEDURE blankline (depth : CARDINAL);
  112.  
  113.     BEGIN
  114.       WrLn (destination);
  115.       ColNum := 0;
  116.       crlf (depth);
  117.     END blankline;
  118.  
  119.     PROCEDURE store (VAR token : TokenTyp);
  120.  
  121.     VAR len : CARDINAL;
  122.  
  123.     BEGIN
  124.       WITH token DO
  125.         len := length;
  126.         IF (len + ColNum > maxwidth) & (symbol # semicolon) & (symbol # comma
  127.            ) THEN
  128.           WrLn (destination);
  129.           ColNum := 0;
  130.           lastsymbol := notallowed;
  131.           IF len + lastpos >= maxwidth THEN
  132.             IF len <= maxwidth THEN
  133.               SetCol (destination,maxwidth - len)
  134.             END
  135.           ELSE
  136.             SetCol (destination,lastpos + 1)
  137.           END
  138.         END;
  139.         IF ((lastsymbol < alias) OR (lastsymbol IN termset {alias,colon,equal,
  140.            define,operationsy,less,lesseq,gr,greq,notequal,rbk,rpar,rbr,bar,
  141.            drefsy,shiftl,shiftr})) & (symbol IN BlankBefore) THEN
  142.           WrChar (destination,' ');
  143.           INC (ColNum);
  144.         END;
  145.         WrStr (destination,value);
  146.         INC (ColNum,length);
  147.         lastsymbol := symbol
  148.       END
  149.     END store;
  150.  
  151.     PROCEDURE getsym (VAR token : TokenTyp);
  152.  
  153.       PROCEDURE getcomment;
  154.  
  155.       VAR ch : CHAR;
  156.           posi : CARDINAL;
  157.           commentdepth : CARDINAL;
  158.  
  159.         PROCEDURE writestr (msg : ARRAY OF CHAR);
  160.  
  161.         BEGIN
  162.           IF Comments THEN
  163.             WrStr (destination,msg)
  164.           END
  165.         END writestr;
  166.  
  167.         PROCEDURE writech (ch : CHAR);
  168.  
  169.         BEGIN
  170.           IF Comments THEN
  171.             WrChar (destination,ch);
  172.           END
  173.         END writech;
  174.  
  175.       BEGIN
  176.         commentdepth := 1;
  177.         posi := ColNum;
  178.         IF token.value [0] # CHR (13) THEN
  179.           writech (' ')
  180.         END;
  181.         writestr (token.value);
  182.         REPEAT
  183.           ReadChar (source,ch);
  184.           writech (ch);
  185.           IF ch = '*' THEN
  186.             ReadChar (source,ch);
  187.             IF ch = ')' THEN
  188.               DEC (commentdepth);
  189.               writech (ch)
  190.             ELSE
  191.               ReadAgain
  192.             END
  193.           ELSIF ch = '(' THEN
  194.             ReadChar (source,ch);
  195.             IF ch = '*' THEN
  196.               INC (commentdepth);
  197.               writech (ch)
  198.             ELSE
  199.               ReadAgain
  200.             END
  201.           END
  202.         UNTIL (commentdepth = 0) OR EOF;
  203.         IF EOF THEN
  204.           errorhandler ('Unexpected End of Source!')
  205.         END;
  206.         lastsymbol := closecom;
  207.         token.symbol := notallowed
  208.       END getcomment;
  209.  
  210.     BEGIN
  211.       IF token.symbol # notallowed THEN
  212.         store (token)
  213.       END;
  214.       GetToken (source,token);
  215.       WITH token DO
  216.         CASE symbol OF
  217.         | notallowed : errorhandler ('Unexpected Token found!')
  218.         | identifier : SearchInHashTable (token);
  219.         | opencom : getcomment;
  220.                     getsym (token)
  221.         END
  222.       END
  223.     END getsym;
  224.  
  225.     PROCEDURE program;
  226.  
  227.       PROCEDURE skipto (terminators : termset);
  228.  
  229.       BEGIN
  230.         WHILE NOT (token.symbol IN terminators) DO
  231.           getsym (token)
  232.         END
  233.       END skipto;
  234.  
  235.       PROCEDURE skipover (symbol : SymbolTyp);
  236.  
  237.       BEGIN
  238.         WHILE token.symbol # symbol DO
  239.           getsym (token)
  240.         END;
  241.         getsym (token)
  242.       END skipover;
  243.  
  244.       PROCEDURE proceduredeclaration (depth : CARDINAL;
  245.                                       isinline : BOOLEAN;
  246.                                       inclass : BOOLEAN); FORWARD;
  247.  
  248.       PROCEDURE moduledeclaration (depth : CARDINAL); FORWARD;
  249.  
  250.       PROCEDURE block (depth : CARDINAL);
  251.  
  252.         PROCEDURE multiplechoice (depth : CARDINAL); FORWARD;
  253.  
  254.         PROCEDURE statementsequence (depth : CARDINAL);
  255.  
  256.           PROCEDURE statement (depth : CARDINAL);
  257.  
  258.           BEGIN
  259.             WITH token DO
  260.               CASE symbol OF
  261.               | ifsy : crlf (depth);
  262.                        skipover (thensy);
  263.                        statementsequence (depth + shift);
  264.                        WHILE symbol = elsifsy DO
  265.                          crlf (depth);
  266.                          skipover (thensy);
  267.                          statementsequence (depth + shift)
  268.                        END;
  269.                        IF symbol = elsesy THEN
  270.                          crlf (depth);
  271.                          getsym (token);
  272.                          statementsequence (depth + shift)
  273.                        END;
  274.                        crlf (depth);
  275.                        getsym (token)
  276.               | casesy : crlf (depth);
  277.                          skipover (ofsy);
  278.                          multiplechoice (depth);
  279.                          crlf (depth);
  280.                          getsym (token);
  281.               | forsy,withsy,whilesy : crlf (depth);
  282.                                        skipover (dosy);
  283.                                        statementsequence (depth + shift);
  284.                                        crlf (depth);
  285.                                        getsym (token)
  286.               | loopsy : crlf (depth);
  287.                          getsym (token);
  288.                          statementsequence (depth + shift);
  289.                          crlf (depth);
  290.                          getsym (token)
  291.               | repeatsy : crlf (depth);
  292.                            WHILE symbol # untilsy DO
  293.                              getsym (token);
  294.                              statement (depth + shift);
  295.                            END;
  296.                            crlf (depth);
  297.                            getsym (token);
  298.                            skipto (terminators)
  299.               ELSE
  300.                 IF NOT (symbol IN terminators) THEN
  301.                   crlf (depth);
  302.                   getsym (token);
  303.                   IF token.symbol = colon THEN
  304.                     getsym (token);
  305.                     statement (depth)
  306.                   ELSE
  307.                     skipto (terminators)
  308.                   END
  309.                 ELSE
  310.                   nocr := FALSE
  311.                 END
  312.               END
  313.             END
  314.           END statement;
  315.  
  316.         BEGIN
  317.           statement (depth);
  318.           WHILE token.symbol = semicolon DO
  319.             getsym (token);
  320.             statement (depth)
  321.           END
  322.         END statementsequence;
  323.  
  324.         PROCEDURE multiplechoice (depth : CARDINAL);
  325.  
  326.         BEGIN
  327.           WITH token DO
  328.             IF (symbol # elsesy) & (symbol # endsy) THEN
  329.               IF symbol = bar THEN
  330.                 crlf (depth)
  331.               ELSE
  332.                 crlf (depth + shift)
  333.               END;
  334.               skipover (colon);
  335.               IF symbol # bar THEN
  336.                 nocr := TRUE;
  337.                 statementsequence (ColNum + 1)
  338.               END;
  339.               WHILE symbol = bar DO
  340.                 crlf (depth);
  341.                 skipover (colon);
  342.                 IF (symbol # bar) & (symbol # elsesy) THEN
  343.                   nocr := TRUE;
  344.                   statementsequence (ColNum + 1)
  345.                 END
  346.               END
  347.             END;
  348.             IF symbol = elsesy THEN
  349.               crlf (depth);
  350.               getsym (token);
  351.               statementsequence (depth + shift)
  352.             END
  353.           END
  354.         END multiplechoice;
  355.  
  356.         PROCEDURE anytype (depth : CARDINAL);
  357.  
  358.         VAR posi : CARDINAL;
  359.  
  360.           PROCEDURE fieldlistsequence (depth : CARDINAL);
  361.  
  362.             PROCEDURE fieldlist (depth : CARDINAL);
  363.  
  364.               PROCEDURE variant;
  365.  
  366.               BEGIN
  367.                 WITH token DO
  368.                   IF (symbol # elsesy) & (symbol # endsy) THEN
  369.                     skipover (colon);
  370.                     lastpos := ColNum;
  371.                     fieldlistsequence (lastpos + 1)
  372.                   END;
  373.                   IF symbol = semicolon THEN
  374.                     getsym (token)
  375.                   END
  376.                 END
  377.               END variant;
  378.  
  379.             BEGIN
  380.               WITH token DO
  381.                 CASE symbol OF
  382.                 | identifier : skipover (colon);
  383.                                anytype (depth);
  384.                 | procsy : proceduredeclaration (depth,FALSE,TRUE);
  385.                 | casesy : skipover (ofsy);
  386.                            IF symbol = bar THEN
  387.                              crlf (depth);
  388.                              getsym (token)
  389.                            ELSE
  390.                              crlf (depth + shift)
  391.                            END;
  392.                            variant;
  393.                            WHILE symbol = bar DO
  394.                              crlf (depth);
  395.                              getsym (token);
  396.                              variant;
  397.                            END;
  398.                            IF symbol = elsesy THEN
  399.                              crlf (depth);
  400.                              getsym (token);
  401.                              fieldlist (depth + shift)
  402.                            END;
  403.                            crlf (depth);
  404.                            getsym (token)
  405.                 END
  406.               END
  407.             END fieldlist;
  408.  
  409.           BEGIN
  410.             WITH token DO
  411.               fieldlist (depth);
  412.               WHILE symbol IN termset {semicolon,procsy} DO
  413.                 IF symbol = semicolon THEN
  414.                   getsym (token)
  415.                 END;
  416.                 IF symbol # endsy THEN
  417.                   IF NOT (symbol IN termset {bar,elsesy,procsy}) THEN
  418.                     crlf (depth)
  419.                   END;
  420.                   fieldlist (depth)
  421.                 END
  422.               END
  423.             END
  424.           END fieldlistsequence;
  425.  
  426.           PROCEDURE simpletype;
  427.  
  428.           BEGIN
  429.             WITH token DO
  430.               IF symbol = lpar THEN
  431.                 lastpos := ColNum + 1;
  432.                 skipover (rpar)
  433.               ELSIF symbol = lbk THEN
  434.                 lastpos := ColNum + 1;
  435.                 skipover (rbk)
  436.               ELSE
  437.                 getsym (token);
  438.                 IF symbol = period THEN
  439.                   getsym (token);
  440.                   getsym (token)
  441.                 ELSIF symbol = lbk THEN
  442.                   lastpos := ColNum + 1;
  443.                   skipover (rbk)
  444.                 END
  445.               END
  446.             END
  447.           END simpletype;
  448.  
  449.         BEGIN
  450.           WITH token DO
  451.             CASE symbol OF
  452.             | pointersy : skipover (tosy);
  453.                           anytype (depth)
  454.             | arraysy : getsym (token);
  455.                         simpletype;
  456.                         WHILE symbol = comma DO
  457.                           getsym (token);
  458.                           simpletype
  459.                         END;
  460.                         getsym (token);
  461.                         lastpos := ColNum;
  462.                         anytype (lastpos + 1)
  463.             | setsy : getsym (token);
  464.                       getsym (token);
  465.                       simpletype
  466.             | procsy : skipover (rpar);
  467.                        skipto (termset {semicolon})
  468.             | recordsy : posi := ColNum + 1;
  469.                          getsym (token);
  470.                          crlf (posi + shift);
  471.                          fieldlistsequence (posi + shift);
  472.                          crlf (posi);
  473.                          getsym (token)
  474.             | classsy : posi := ColNum + 1;
  475.                         getsym (token);
  476.                         IF token.symbol = lpar THEN
  477.                           skipover (rpar)
  478.                         END;
  479.                         crlf (posi + shift);
  480.                         fieldlistsequence (posi + shift);
  481.                         crlf (posi);
  482.                         getsym (token)
  483.             ELSE
  484.               simpletype
  485.             END
  486.           END
  487.         END anytype;
  488.  
  489.         PROCEDURE typedeclaration (depth : CARDINAL);
  490.  
  491.         VAR posi : CARDINAL;
  492.  
  493.         BEGIN
  494.           blankline (depth);
  495.           getsym (token);
  496.           lastpos := ColNum;
  497.           posi := lastpos + 1;
  498.           WITH token DO
  499.             WHILE symbol = identifier DO
  500.               getsym (token);
  501.               IF symbol # semicolon THEN
  502.                 getsym (token);
  503.                 anytype (posi)
  504.               ELSIF NOT defmodule THEN
  505.                 errorhandler ('TYPE Identifier expected!')
  506.               END;
  507.               getsym (token);
  508.               IF symbol = identifier THEN
  509.                 crlf (posi)
  510.               END
  511.             END
  512.           END
  513.         END typedeclaration;
  514.  
  515.         PROCEDURE constdeclaration (depth : CARDINAL);
  516.  
  517.         VAR posi : CARDINAL;
  518.  
  519.         BEGIN
  520.           blankline (depth);
  521.           getsym (token);
  522.           posi := ColNum + 1;
  523.           WITH token DO
  524.             WHILE symbol = identifier DO
  525.               getsym (token);
  526.               getsym (token);
  527.               lastpos := ColNum;
  528.               skipover (semicolon);
  529.               IF symbol = identifier THEN
  530.                 crlf (posi)
  531.               END
  532.             END
  533.           END
  534.         END constdeclaration;
  535.  
  536.         PROCEDURE variabledeclaration (depth : CARDINAL);
  537.  
  538.         VAR posi : CARDINAL;
  539.  
  540.         BEGIN
  541.           blankline (depth);
  542.           getsym (token);
  543.           lastpos := ColNum;
  544.           posi := lastpos + 1;
  545.           WITH token DO
  546.             WHILE symbol = identifier DO
  547.               getsym (token);
  548.               IF symbol = lbk THEN
  549.                 skipover (rbk)
  550.               END;
  551.               WHILE symbol = comma DO
  552.                 getsym (token);
  553.                 getsym (token)
  554.               END;
  555.               getsym (token);
  556.               anytype (posi);
  557.               getsym (token);
  558.               IF symbol = identifier THEN
  559.                 crlf (posi)
  560.               END
  561.             END
  562.           END
  563.         END variabledeclaration;
  564.  
  565.         PROCEDURE labellist (depth : CARDINAL);
  566.  
  567.         VAR posi : CARDINAL;
  568.  
  569.         BEGIN
  570.           blankline (depth);
  571.           getsym (token);
  572.           lastpos := ColNum;
  573.           posi := lastpos + 1;
  574.           WITH token DO
  575.             WHILE symbol = identifier DO
  576.               getsym (token);
  577.               WHILE symbol = comma DO
  578.                 getsym (token);
  579.                 getsym (token)
  580.               END
  581.             END
  582.           END;
  583.           getsym (token)
  584.         END labellist;
  585.  
  586.       BEGIN
  587.         WITH token DO
  588.           WHILE (symbol # beginsy) & (symbol # endsy) DO
  589.             CASE symbol OF
  590.             | typesy : typedeclaration (depth)
  591.             | constsy : constdeclaration (depth)
  592.             | varsy : variabledeclaration (depth)
  593.             | labelsy : labellist (depth)
  594.             | inlinesy : IF defmodule THEN
  595.                            proceduredeclaration (depth + shift,TRUE,FALSE)
  596.                          ELSE
  597.                            errorhandler ('INLINE Symbol recognized!')
  598.                          END
  599.             | procsy : proceduredeclaration (depth + shift,FALSE,FALSE)
  600.             | modulesy : moduledeclaration (depth + shift)
  601.             ELSE
  602.               errorhandler ('Error In Block')
  603.             END
  604.           END;
  605.           blankline (depth);
  606.           IF symbol = beginsy THEN
  607.             getsym (token);
  608.             statementsequence (depth + shift);
  609.             crlf (depth)
  610.           END;
  611.           getsym (token);
  612.           getsym (token);
  613.         END
  614.       END block;
  615.  
  616.       PROCEDURE moduledeclaration (depth : CARDINAL);
  617.  
  618.       VAR help : TokenTyp;
  619.  
  620.         PROCEDURE importdeclaration (depth : CARDINAL);
  621.  
  622.         BEGIN
  623.           WITH token DO
  624.             IF symbol = fromsy THEN
  625.               blankline (depth);
  626.               getsym (token);
  627.               getsym (token);
  628.               getsym (token);
  629.               lastpos := ColNum;
  630.               WHILE token.symbol # semicolon DO
  631.                 getsym (token)
  632.               END;
  633.               getsym (token)
  634.             ELSIF symbol = importsy THEN
  635.               blankline (depth);
  636.               getsym (token);
  637.               lastpos := ColNum;
  638.               LOOP
  639.                 getsym (token);
  640.                 IF symbol = semicolon THEN
  641.                   EXIT
  642.                 END;
  643.                 getsym (token)
  644.               END;
  645.               getsym (token)
  646.             ELSIF symbol = exportsy THEN
  647.               blankline (depth);
  648.               getsym (token);
  649.               lastpos := ColNum;
  650.               LOOP
  651.                 getsym (token);
  652.                 IF symbol = semicolon THEN
  653.                   EXIT
  654.                 END;
  655.                 getsym (token)
  656.               END;
  657.               getsym (token)
  658.             END
  659.           END
  660.         END importdeclaration;
  661.  
  662.       BEGIN
  663.         WITH token DO
  664.           IF depth > 0 THEN
  665.             blankline (depth)
  666.           END;
  667.           skipover (semicolon);
  668.           WHILE symbol IN termset {fromsy,importsy,exportsy} DO
  669.             importdeclaration (depth)
  670.           END;
  671.           block (depth);
  672.           IF symbol = semicolon THEN
  673.             getsym (token)
  674.           END
  675.         END
  676.       END moduledeclaration;
  677.  
  678.       PROCEDURE proceduredeclaration (depth : CARDINAL;
  679.                                       isinline : BOOLEAN;
  680.                                       inclass : BOOLEAN);
  681.  
  682.         PROCEDURE varlist;
  683.  
  684.         VAR posi : CARDINAL;
  685.  
  686.         BEGIN
  687.           WITH token DO
  688.             IF symbol = lpar THEN
  689.               lastpos := ColNum + 1;
  690.               posi := lastpos + 1;
  691.               REPEAT
  692.                 getsym (token);
  693.                 IF symbol = semicolon THEN
  694.                   getsym (token);
  695.                   crlf (posi);
  696.                 END
  697.               UNTIL symbol = rpar;
  698.               getsym (token)
  699.             END;
  700.             IF symbol = colon THEN
  701.               getsym (token);
  702.               getsym (token)
  703.             END
  704.           END
  705.         END varlist;
  706.  
  707.       BEGIN
  708.         IF inclass & defmodule THEN
  709.           crlf (depth)
  710.         ELSE
  711.           blankline (depth)
  712.         END;
  713.         IF isinline THEN
  714.           getsym (token)
  715.         END;
  716.         getsym (token);
  717.         getsym (token);
  718.         varlist;
  719.         WITH token DO
  720.           IF symbol = semicolon THEN
  721.             getsym (token);
  722.             IF inclass THEN
  723.               IF symbol = virtualsy THEN
  724.                 WrChar (destination,' ');
  725.                 getsym (token);
  726.                 IF NOT defmodule THEN
  727.                   getsym (token)
  728.                 END
  729.               END
  730.             END;
  731.             IF symbol = forwardsy THEN
  732.               WrChar (destination,' ');
  733.               getsym (token)
  734.             ELSIF symbol = insy THEN
  735.               WrChar (destination,' ');
  736.               skipto (termset {semicolon})
  737.             ELSIF NOT defmodule THEN
  738.               block (depth);
  739.             END
  740.           ELSIF symbol = equal THEN
  741.             lastpos := ColNum + 1;
  742.             skipto (termset {semicolon})
  743.           END
  744.         END;
  745.         IF NOT defmodule THEN
  746.           getsym (token)
  747.         END
  748.       END proceduredeclaration;
  749.  
  750.     BEGIN (* program *)
  751.       WITH token DO
  752.         symbol := notallowed;
  753.         lastsymbol := notallowed;
  754.         getsym (token);
  755.         nocr := FALSE;
  756.         WrLn (destination);
  757.         ColNum := 0;
  758.         IF (symbol = implsy) OR (symbol = defsy) THEN
  759.           defmodule := symbol = defsy;
  760.           getsym (token)
  761.         ELSE
  762.           defmodule := FALSE;
  763.         END
  764.       END;
  765.       moduledeclaration (0);
  766.       store (token);
  767.     END program;
  768.  
  769.   BEGIN
  770.     InitScanner;
  771.     IOcheck := FALSE;
  772.     source := OpenRead (sourcename);
  773.     IF IOresult () # 0 THEN
  774.       errorhandler ("Can't open Source!")
  775.     END;
  776.     AssignBuffer (source,ReadBuffer);
  777.     IF Compare (destname,'PRN') # 0 THEN
  778. (*%F Test*)
  779.       Copy (writename,destname);
  780.       ChangeExtension (writename,'$$$');
  781.       destination := Create (writename);
  782.       IF IOresult () # 0 THEN
  783.         errorhandler ("Can't create Destination-File!")
  784.       END;
  785.       AssignBuffer (destination,WriteBuffer);
  786. (*%E*)
  787. (*%T Test*)
  788.       destination := StandardOutput
  789. (*%E*)
  790.     ELSE
  791.       destination := PrinterDevice;
  792.     END;
  793.     program;
  794.     closefiles (FALSE);
  795.   END MakePretty;
  796.  
  797. END PRPARSER.