home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
modula2
/
alexcoco
/
taste.atg
< prev
next >
Wrap
Text File
|
1987-04-14
|
14KB
|
346 lines
-- Attributed grammar of the Taste-compiler
----------------------------------------------------------------------------
GRAMMAR taste
-- Taste = PROGRAM ident ";" Body ident ".".
-- Body = {Decl} BEGIN StatSeq END.
-- Decl = VarDecl | PROCEDURE ident ";" Body ";".
-- VarDecl = VAR {ident ":" TypeId ";"}.
-- TypeId = INTEGER | BOOLEAN.
-- StatSeq = Stat {";" Stat}.
-- Stat = [ ident [":=" Expression]
-- | IF Expression THEN StatSeq [ELSE StatSeq] END
-- | WHILE Expression DO StatSeq END
-- | READ ident
-- | Write Expression
-- ].
-- Expression = SimExpr [RO SimExpr].
-- SimExpr = Term {AO Term}.
-- Term = Factor {MO Factor}.
-- Factor = ident | TRUE | FALSE | number | "-" Factor.
-- AO = "+" | "-".
-- MO = "*" | "/".
-- RO = "=" | "<" | ">".
EXTERNAL DECLARATIONS
---------------------
FROM tastesym IMPORT
Object, Type, Objectkind, undefobj,
NewObj, EnterScope, LeaveScope, Find, FindLocal, EnterProcStart;
FROM tastecode IMPORT
Instruction, pc, progstart, EmitOp, Emit, Fixup;
FROM tastesyn IMPORT
line,col;
FROM tastelex IMPORT
GetVal;
FROM Errors IMPORT
SemErr;
INTERNAL DECLARATIONS
---------------------
CONST
dummyadr = 0;
VAR
obj: Object; (*auxiliary used to store objects*)
obj1: Object; (*auxiliary*)
procobj: Object; (*procedure object*)
spix,spix1: CARDINAL; (*auxiliary to store a name (spelling index)*)
progspix: CARDINAL; (*program name*)
main: BOOLEAN; (*TRUE if body of main program*)
val: CARDINAL; (*spix of a digit string*)
addop: (plus,minus); (*addition operators*)
mulop: (times,slash); (*multiplikation operators*)
relop: (equ,lss,gtr); (*relational operators*)
typ,typ1,typ2,typ3: Type; (*types in expressions*)
fix: CARDINAL; (*fixup address*)
loopstart: CARDINAL; (*start address of while loop*)
n: CARDINAL; (*auxiliary*)
stack: ARRAY[1..20] OF CARDINAL;
sp: CARDINAL; (*stack pointer*)
PROCEDURE Error(nr:CARDINAL);
BEGIN SemErr(nr,line,col) END Error;
PROCEDURE Declare(spix:CARDINAL; kind:Objectkind; VAR obj:Object);
BEGIN
FindLocal(!spix,^obj);
IF obj=NIL
THEN NewObj(!spix,!kind,^obj);
ELSE Error(1);
END;
END Declare;
PROCEDURE StringToCard(strp:CARDINAL; VAR val:CARDINAL);
VAR
str: ARRAY[1..10] OF CHAR;
len,i: CARDINAL;
n: CARDINAL;
BEGIN
GetVal(!strp,^str,^len);
n:=0;
FOR i:= 1 TO len DO
n:=10*n + ORD(str[i]) - ORD("0");
END;
val:=n;
END StringToCard;
PROCEDURE Push(val:CARDINAL);
BEGIN
IF sp<20 THEN INC(sp); stack[sp]:=val ELSE HALT END;
END Push;
PROCEDURE Pop(VAR val:CARDINAL);
BEGIN
IF sp>0 THEN val:=stack[sp]; DEC(sp) ELSE HALT END;
END Pop;
TERMINALS
---------
eofsy -- 0
BEGIN -- 1
BOOLEAN -- 2
DO -- 3
ELSE -- 4
END -- 5
FALSE -- 6
IF -- 7
INTEGER -- 8
PROGRAM -- 9
PROCEDURE -- 10
READ -- 11
THEN -- 12
TRUE -- 13
VAR -- 14
WHILE -- 15
WRITE -- 16
"+" -- 17
"-" -- 18
"*" -- 19
"/" -- 20
"=" -- 21
"<" -- 22
">" -- 23
"." -- 24
";" -- 25
":" -- 26
ident <out:spix> -- 27
number <out:val> -- 28
PRAGMAS
eolsy -- 29
NONTERMINALS
------------
AO <out:addop>
Body <in:main>
Decl
Expression <out:typ>
Factor <out:typ3>
MO <out:mulop>
RO <out:relop>
SimExpr <out:typ1>
Stat
StatSeq
taste
Term <out:typ2>
TypeId <out:typ>
VarDecl
ENDFILE = eofsy
ENDLINE = eolsy
INPUT FROM tastelex.GetSy
ERRORS TO Errors.SyntaxError
RULES
----------------------------------------------------------------------------
AO<out:addop> =
"+" sem addop:=plus endsem
| "-" sem addop:=minus endsem.
----------------------------------------------------------------------------
Body<in:main> =
sem Push(!ORD(main)) endsem
{Decl}
BEGIN sem EnterProcStart(!pc);
Pop(^n); main:=n=1;
IF main THEN progstart:=pc END;
endsem
StatSeq
END.
----------------------------------------------------------------------------
Decl =
VarDecl
| PROCEDURE
ident<out:spix> sem Declare(!spix,!procs,^obj);
obj^.typ:=undef;
EnterScope(!obj); Push(!spix);
endsem
";" Body<in:FALSE> sem EmitOp(RET); LeaveScope endsem
ident<out:spix1> ";" sem Pop(^spix);
IF spix<>spix1 THEN Error(9) END
endsem.
----------------------------------------------------------------------------
Expression<out:typ> =
SimExpr<out:typ>
[ RO<out:relop>
SimExpr<out:typ1> sem IF (typ<>typ1) THEN Error(7) END;
CASE relop OF
equ: EmitOp(EQU);
| lss: EmitOp(LSS);
| gtr: EmitOp(GTR);
END;
typ:=bool
endsem
].
----------------------------------------------------------------------------
Factor<out:typ3> =
( ident<out:spix> sem Find(!spix,^obj);
IF obj=NIL THEN
Error(2); obj:=undefobj;
END;
EmitOp(LOAD); Emit(obj^.addr);
typ3:=obj^.typ
endsem
| TRUE sem EmitOp(LIT); Emit(1); typ3:=bool endsem
| FALSE sem EmitOp(LIT); Emit(0); typ3:=bool endsem
| number<out:val> sem StringToCard(!val,^n);
EmitOp(LIT); Emit(n);
typ3:=int;
endsem
| "-" Factor<out:typ3> sem IF typ3<>int THEN
Error(8); typ3:=int;
END;
EmitOp(NEG);
endsem
).
----------------------------------------------------------------------------
MO<out:mulop> =
"*" sem mulop:=times endsem
| "/" sem mulop:=slash endsem.
----------------------------------------------------------------------------
RO<out:relop> =
"=" sem relop:=equ endsem
| "<" sem relop:=lss endsem
| ">" sem relop:=gtr endsem.
----------------------------------------------------------------------------
SimExpr<out:typ1> =
Term<out:typ1>
{ AO<out:addop>
Term<out:typ2> sem IF typ1<>typ2 THEN Error(7) END;
CASE addop OF
plus:
IF typ1<>int THEN Error(8) END;
EmitOp(ADD);
| minus:
IF typ1<>int THEN Error(8) END;
EmitOp(SUB);
END;
endsem
}.
----------------------------------------------------------------------------
Stat =
[ ident<out:spix> sem Find(!spix,^obj1);
IF obj1=NIL THEN
Error(2); obj1:=undefobj;
END;
endsem
( ":" "=" sem IF obj1^.kind<>vars THEN
Error(3);
END;
EmitOp(LIT); Emit(obj1^.addr);
endsem
Expression<out:typ> sem IF typ<>obj1^.typ THEN
Error(4);
END;
EmitOp(STO);
endsem
| eps sem IF obj1^.kind<>procs THEN
Error(5);
END;
EmitOp(!CALL); Emit(obj1^.start);
endsem
)
| IF Expression<out:typ> sem IF typ<>bool THEN Error(6) END;
Push(pc+1); --fix
EmitOp(!FJMP); Emit(!dummyadr);
endsem
THEN StatSeq
( ELSE sem Pop(^fix); Fixup(!fix,!pc);
Push(pc+1); --fix
EmitOp(!JMP); Emit(!dummyadr);
endsem
StatSeq
| eps
)
END sem Pop(^fix); Fixup(!fix,!pc);
endsem
| WHILE sem Push(!pc) endsem
Expression<out:typ> sem IF typ<>bool THEN Error(6) END;
Push(!pc+1); --fix
EmitOp(!FJMP); Emit(!dummyadr);
endsem
DO StatSeq sem Pop(^fix); Pop(^loopstart);
EmitOp(!JMP); Emit(!loopstart);
Fixup(!fix,!pc);
endsem
END
| READ ident<out:spix> sem Find(!spix,^obj);
IF obj=NIL THEN
Error(2); obj:=undefobj;
END;
IF obj^.typ<>int THEN Error(8) END;
EmitOp(!READ); Emit(!obj^.addr)
endsem
| WRITE Expression<out:typ> sem IF typ<>int THEN Error(8) END;
EmitOp(!WRITE)
endsem
].
----------------------------------------------------------------------------
StatSeq =
Stat {";" Stat}.
----------------------------------------------------------------------------
taste =
PROGRAM
ident<out:progspix> ";" sem NewObj(!progspix,!procs,^obj);
obj^.typ:=undef;
EnterScope(!obj);
sp:=0;
endsem
Body<in:TRUE> sem EmitOp(HALTc) endsem
ident<out:spix> sem IF spix<>progspix THEN Error(9) END endsem
".".
----------------------------------------------------------------------------
Term<out:typ2> =
Factor<out:typ2>
{ MO<out:mulop>
Factor<out:typ3> sem IF typ2<>typ3 THEN Error(7) END;
CASE mulop OF
times:
IF typ2<>int THEN Error(8) END;
EmitOp(MUL);
| slash:
IF typ3<>int THEN Error(8) END;
EmitOp(DIVc);
END;
endsem
}.
----------------------------------------------------------------------------
TypeId<out:typ> =
INTEGER sem typ:=int endsem
| BOOLEAN sem typ:=bool endsem.
----------------------------------------------------------------------------
VarDecl =
VAR
{ ident<out:spix> ":"
TypeId<out:typ> ";" sem Declare(!spix,!vars,^obj); obj^.typ:=typ
endsem
}.
----------------------------------------------------------------------------
ENDGRAM