home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / modula2 / alexcoco / taste.atg < prev    next >
Text File  |  1987-04-14  |  14KB  |  346 lines

  1. -- Attributed grammar of the Taste-compiler
  2. ----------------------------------------------------------------------------
  3. GRAMMAR taste
  4.  
  5. --  Taste      = PROGRAM ident ";" Body ident ".".
  6. --  Body       = {Decl} BEGIN StatSeq END.
  7. --  Decl       = VarDecl | PROCEDURE ident ";" Body ";".
  8. --  VarDecl    = VAR {ident ":" TypeId ";"}.
  9. --  TypeId     = INTEGER | BOOLEAN.
  10. --  StatSeq    = Stat {";" Stat}.
  11. --  Stat       = [ ident [":=" Expression]
  12. --               | IF Expression THEN StatSeq [ELSE StatSeq] END
  13. --               | WHILE Expression DO StatSeq END
  14. --               | READ ident
  15. --               | Write Expression
  16. --               ].
  17. --  Expression = SimExpr [RO SimExpr].
  18. --  SimExpr    = Term {AO Term}.
  19. --  Term       = Factor {MO Factor}.
  20. --  Factor     = ident | TRUE | FALSE | number | "-" Factor.
  21. --  AO         = "+" | "-".
  22. --  MO         = "*" | "/".
  23. --  RO         = "=" | "<" | ">".
  24.  
  25. EXTERNAL DECLARATIONS
  26. ---------------------
  27.   FROM tastesym IMPORT
  28.     Object, Type, Objectkind, undefobj,
  29.     NewObj, EnterScope, LeaveScope, Find, FindLocal, EnterProcStart;
  30.   FROM tastecode IMPORT
  31.     Instruction, pc, progstart, EmitOp, Emit, Fixup;
  32.   FROM tastesyn IMPORT
  33.     line,col;
  34.   FROM tastelex IMPORT
  35.     GetVal;
  36.   FROM Errors IMPORT
  37.     SemErr;
  38.  
  39. INTERNAL DECLARATIONS
  40. ---------------------
  41. CONST
  42.   dummyadr  = 0;
  43.  
  44. VAR
  45.  obj:           Object;        (*auxiliary used to store objects*)
  46.  obj1:          Object;        (*auxiliary*)
  47.  procobj:       Object;        (*procedure object*)
  48.  spix,spix1:    CARDINAL;      (*auxiliary to store a name (spelling index)*)
  49.  progspix:      CARDINAL;      (*program name*)
  50.  main:          BOOLEAN;       (*TRUE if body of main program*)
  51.  val:           CARDINAL;      (*spix of a digit string*)
  52.  addop:         (plus,minus);  (*addition operators*)
  53.  mulop:         (times,slash); (*multiplikation operators*)
  54.  relop:         (equ,lss,gtr); (*relational operators*)
  55.  typ,typ1,typ2,typ3: Type;     (*types in expressions*)
  56.  fix:           CARDINAL;      (*fixup address*)
  57.  loopstart:     CARDINAL;      (*start address of while loop*)
  58.  n:             CARDINAL;      (*auxiliary*)
  59.  stack:         ARRAY[1..20] OF CARDINAL;
  60.  sp:            CARDINAL;      (*stack pointer*)
  61.  
  62.  
  63. PROCEDURE Error(nr:CARDINAL);
  64. BEGIN SemErr(nr,line,col) END Error;
  65.  
  66.  
  67. PROCEDURE Declare(spix:CARDINAL; kind:Objectkind; VAR obj:Object);
  68. BEGIN
  69.   FindLocal(!spix,^obj);
  70.   IF obj=NIL
  71.     THEN NewObj(!spix,!kind,^obj);
  72.     ELSE Error(1);
  73.     END;
  74.   END Declare;
  75.  
  76.  
  77. PROCEDURE StringToCard(strp:CARDINAL; VAR val:CARDINAL);
  78. VAR
  79.   str:   ARRAY[1..10] OF CHAR;
  80.   len,i: CARDINAL;
  81.   n:     CARDINAL;
  82. BEGIN
  83.   GetVal(!strp,^str,^len);
  84.   n:=0;
  85.   FOR i:= 1 TO len DO
  86.     n:=10*n + ORD(str[i]) - ORD("0");
  87.     END;
  88.   val:=n;
  89.   END StringToCard;
  90.  
  91.  
  92. PROCEDURE Push(val:CARDINAL);
  93. BEGIN
  94.   IF sp<20 THEN INC(sp); stack[sp]:=val ELSE HALT END;
  95.   END Push;
  96.  
  97.  
  98. PROCEDURE Pop(VAR val:CARDINAL);
  99. BEGIN
  100.   IF sp>0 THEN val:=stack[sp]; DEC(sp) ELSE HALT END;
  101.   END Pop;
  102.   
  103.  
  104. TERMINALS
  105. ---------
  106.   eofsy             --  0
  107.   BEGIN             --  1
  108.   BOOLEAN           --  2
  109.   DO                --  3
  110.   ELSE              --  4
  111.   END               --  5
  112.   FALSE             --  6
  113.   IF                --  7
  114.   INTEGER           --  8
  115.   PROGRAM           --  9
  116.   PROCEDURE         -- 10
  117.   READ              -- 11
  118.   THEN              -- 12
  119.   TRUE              -- 13
  120.   VAR               -- 14
  121.   WHILE             -- 15
  122.   WRITE             -- 16
  123.   "+"               -- 17
  124.   "-"               -- 18
  125.   "*"               -- 19
  126.   "/"               -- 20
  127.   "="               -- 21
  128.   "<"               -- 22
  129.   ">"               -- 23
  130.   "."               -- 24
  131.   ";"               -- 25
  132.   ":"               -- 26
  133.   ident  <out:spix> -- 27
  134.   number <out:val>  -- 28
  135.  
  136. PRAGMAS
  137.   eolsy             -- 29
  138.  
  139. NONTERMINALS
  140. ------------
  141.   AO         <out:addop>
  142.   Body       <in:main>
  143.   Decl
  144.   Expression <out:typ>
  145.   Factor     <out:typ3>
  146.   MO         <out:mulop>
  147.   RO         <out:relop>
  148.   SimExpr    <out:typ1>
  149.   Stat
  150.   StatSeq
  151.   taste
  152.   Term       <out:typ2>
  153.   TypeId     <out:typ>
  154.   VarDecl
  155.  
  156. ENDFILE = eofsy
  157. ENDLINE = eolsy
  158. INPUT FROM tastelex.GetSy
  159. ERRORS TO Errors.SyntaxError
  160.  
  161. RULES
  162. ----------------------------------------------------------------------------
  163. AO<out:addop> =
  164.     "+"                                sem addop:=plus endsem
  165.   | "-"                                sem addop:=minus endsem.
  166. ----------------------------------------------------------------------------
  167. Body<in:main> =
  168.                                        sem Push(!ORD(main)) endsem
  169.   {Decl}
  170.   BEGIN                                sem EnterProcStart(!pc);
  171.                                            Pop(^n); main:=n=1;
  172.                                            IF main THEN progstart:=pc END;
  173.                                            endsem
  174.   StatSeq 
  175.   END.
  176. ----------------------------------------------------------------------------
  177. Decl =
  178.     VarDecl
  179.   | PROCEDURE                   
  180.     ident<out:spix>                    sem Declare(!spix,!procs,^obj);
  181.                                            obj^.typ:=undef;
  182.                                            EnterScope(!obj); Push(!spix);
  183.                                            endsem
  184.     ";" Body<in:FALSE>                 sem EmitOp(RET); LeaveScope endsem
  185.     ident<out:spix1> ";"               sem Pop(^spix); 
  186.                                            IF spix<>spix1 THEN Error(9) END
  187.                                            endsem.
  188. ----------------------------------------------------------------------------
  189. Expression<out:typ> =
  190.   SimExpr<out:typ>
  191.   [ RO<out:relop>
  192.     SimExpr<out:typ1>               sem IF (typ<>typ1) THEN Error(7) END;
  193.                                         CASE relop OF
  194.                                           equ: EmitOp(EQU);
  195.                                         | lss: EmitOp(LSS);
  196.                                         | gtr: EmitOp(GTR);
  197.                                           END;
  198.                                         typ:=bool
  199.                                         endsem
  200.     ].
  201. ----------------------------------------------------------------------------
  202. Factor<out:typ3> =
  203.   ( ident<out:spix>                 sem Find(!spix,^obj);
  204.                                         IF obj=NIL THEN 
  205.                                           Error(2); obj:=undefobj;
  206.                                           END;
  207.                                         EmitOp(LOAD); Emit(obj^.addr);
  208.                                         typ3:=obj^.typ
  209.                                         endsem
  210.   | TRUE                            sem EmitOp(LIT); Emit(1); typ3:=bool endsem
  211.   | FALSE                           sem EmitOp(LIT); Emit(0); typ3:=bool endsem
  212.   | number<out:val>                 sem StringToCard(!val,^n);
  213.                                         EmitOp(LIT); Emit(n);
  214.                                         typ3:=int;
  215.                                         endsem
  216.   | "-" Factor<out:typ3>            sem IF typ3<>int THEN 
  217.                                           Error(8); typ3:=int;
  218.                                           END;
  219.                                         EmitOp(NEG);
  220.                                         endsem
  221.   ).
  222. ----------------------------------------------------------------------------
  223. MO<out:mulop> =
  224.     "*"                             sem mulop:=times endsem
  225.   | "/"                             sem mulop:=slash endsem.
  226. ----------------------------------------------------------------------------
  227. RO<out:relop> =
  228.     "="                             sem relop:=equ endsem
  229.   | "<"                             sem relop:=lss endsem
  230.   | ">"                             sem relop:=gtr endsem.
  231. ----------------------------------------------------------------------------
  232. SimExpr<out:typ1> =
  233.   Term<out:typ1>
  234.   { AO<out:addop>
  235.     Term<out:typ2>                  sem IF typ1<>typ2 THEN Error(7) END;
  236.                                         CASE addop OF
  237.                                           plus: 
  238.                                             IF typ1<>int THEN Error(8) END;
  239.                                             EmitOp(ADD);
  240.                                         | minus:
  241.                                             IF typ1<>int THEN Error(8) END;
  242.                                             EmitOp(SUB);
  243.                                           END;
  244.                                         endsem
  245.     }.
  246. ----------------------------------------------------------------------------
  247. Stat =
  248.   [ ident<out:spix>                      sem Find(!spix,^obj1);
  249.                                              IF obj1=NIL THEN
  250.                                                Error(2); obj1:=undefobj;
  251.                                                END;
  252.                                              endsem
  253.     ( ":" "="                            sem IF obj1^.kind<>vars THEN 
  254.                                                Error(3);
  255.                                                END;
  256.                                              EmitOp(LIT); Emit(obj1^.addr);
  257.                                              endsem
  258.       Expression<out:typ>                sem IF typ<>obj1^.typ THEN
  259.                                                Error(4);
  260.                                                END;
  261.                                              EmitOp(STO);
  262.                                              endsem
  263.     | eps                                sem IF obj1^.kind<>procs THEN
  264.                                                Error(5);
  265.                                                END;
  266.                                              EmitOp(!CALL); Emit(obj1^.start);
  267.                                              endsem
  268.     )
  269.   | IF Expression<out:typ>               sem IF typ<>bool THEN Error(6) END;
  270.                                              Push(pc+1); --fix
  271.                                              EmitOp(!FJMP); Emit(!dummyadr);
  272.                                              endsem
  273.     THEN StatSeq
  274.     ( ELSE                               sem Pop(^fix); Fixup(!fix,!pc);
  275.                                              Push(pc+1); --fix 
  276.                                              EmitOp(!JMP); Emit(!dummyadr);
  277.                                              endsem
  278.       StatSeq 
  279.     | eps
  280.     )
  281.     END                                  sem Pop(^fix); Fixup(!fix,!pc);
  282.                                              endsem
  283.   | WHILE                                sem Push(!pc) endsem
  284.     Expression<out:typ>                  sem IF typ<>bool THEN Error(6) END;
  285.                                              Push(!pc+1); --fix
  286.                                              EmitOp(!FJMP); Emit(!dummyadr);
  287.                                              endsem
  288.     DO StatSeq                           sem Pop(^fix); Pop(^loopstart);
  289.                                              EmitOp(!JMP); Emit(!loopstart);
  290.                                              Fixup(!fix,!pc);
  291.                                              endsem
  292.     END
  293.   | READ ident<out:spix>                 sem Find(!spix,^obj);
  294.                                              IF obj=NIL THEN 
  295.                                                Error(2); obj:=undefobj;
  296.                                                END;
  297.                                              IF obj^.typ<>int THEN Error(8) END;
  298.                                              EmitOp(!READ); Emit(!obj^.addr)
  299.                                              endsem
  300.   | WRITE Expression<out:typ>            sem IF typ<>int THEN Error(8) END;
  301.                                              EmitOp(!WRITE)
  302.                                              endsem
  303.   ].
  304. ----------------------------------------------------------------------------
  305. StatSeq =
  306.   Stat {";" Stat}.
  307. ----------------------------------------------------------------------------
  308. taste =
  309.   PROGRAM
  310.   ident<out:progspix> ";"           sem NewObj(!progspix,!procs,^obj);
  311.                                         obj^.typ:=undef;
  312.                                         EnterScope(!obj);
  313.                                         sp:=0;
  314.                                         endsem
  315.   Body<in:TRUE>                     sem EmitOp(HALTc) endsem
  316.   ident<out:spix>                   sem IF spix<>progspix THEN Error(9) END endsem
  317.   ".".
  318. ----------------------------------------------------------------------------
  319. Term<out:typ2> =
  320.   Factor<out:typ2>
  321.   { MO<out:mulop>
  322.     Factor<out:typ3>                 sem IF typ2<>typ3 THEN Error(7) END;
  323.                                          CASE mulop OF
  324.                                            times:
  325.                                              IF typ2<>int THEN Error(8) END;
  326.                                              EmitOp(MUL);
  327.                                          | slash:
  328.                                              IF typ3<>int THEN Error(8) END;
  329.                                              EmitOp(DIVc);
  330.                                            END;
  331.                                          endsem
  332.     }.
  333. ----------------------------------------------------------------------------
  334. TypeId<out:typ> =
  335.     INTEGER                          sem typ:=int endsem
  336.   | BOOLEAN                          sem typ:=bool endsem.
  337. ----------------------------------------------------------------------------
  338. VarDecl =
  339.   VAR 
  340.   { ident<out:spix> ":"
  341.     TypeId<out:typ> ";"              sem Declare(!spix,!vars,^obj); obj^.typ:=typ
  342.                                          endsem
  343.     }.
  344. ----------------------------------------------------------------------------
  345. ENDGRAM
  346.