1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
|
COMPILER Calc
FROM CalcManager IMPORT NewVar, GetVar, SetVar, ReadVal, WriteVal;
TYPE
String = ARRAY [0 .. 100] OF CHAR;
PROCEDURE GetNumber (VAR Int : INTEGER);
(* Convert latest token to integer value Int *)
VAR
I : CARDINAL;
String : ARRAY [0 .. 20] OF CHAR;
BEGIN
CalcS.GetString(CalcS.pos, CalcS.len, String);
I := 0; Int := 0;
WHILE String[I] # 0C DO
Int := 10 * Int + VAL(INTEGER, ORD(String[I]) - ORD('0')); INC(I)
END;
END GetNumber;
PROCEDURE GetSpix (VAR spix : INTEGER);
(* Compute hash total for latest spelling *)
VAR
IdentName : ARRAY [0 .. 20] OF CHAR;
BEGIN
CalcS.GetName(CalcS.pos, CalcS.len, IdentName);
spix := 17 * ORD(IdentName[0]) + ORD(IdentName[1])
END GetSpix;
IGNORE CASE
CHARACTERS
letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".
digit = "0123456789".
eol = CHR(13) .
COMMENTS
FROM '--' TO eol
TOKENS
ident = letter {letter | digit} .
number = digit {digit} .
PRODUCTIONS
Calc =
[Declarations] StatSeq .
Declarations (. VAR spix: INTEGER; .)
= "VAR"
Ident <spix> (. NewVar(spix) .)
{ ',' Ident <spix> (. NewVar(spix) .)
} ';'.
StatSeq =
Stat {';' Stat}.
Stat (. VAR spix, val: INTEGER; .)
= "READ" Ident <spix> (. ReadVal(spix) .)
| "WRITE" Expr <val> (. WriteVal(val) .)
| Ident <spix> ":=" Expr <val> (. SetVar(spix, val) .) .
Expr <VAR exprVal: INTEGER> (. VAR termVal: INTEGER; .)
= Term <exprVal>
{ '+' Term <termVal> (. exprVal := exprVal + termVal .)
| '-' Term <termVal> (. exprVal := exprVal - termVal .)
} .
Term <VAR termVal: INTEGER> (. VAR factVal: INTEGER; .)
= Fact <termVal>
{ '*' Fact <factVal> (. termVal := termVal * factVal .)
| '/' Fact <factVal> (. termVal := termVal DIV factVal .)
} .
Fact <VAR factVal: INTEGER> (. VAR spix: INTEGER; .)
= Ident <spix> (. factVal := GetVar(spix) .)
| number (. GetNumber(factVal) .)
| '(' Expr <factVal> ')' .
Ident <VAR spix : INTEGER>
= ident (. GetSpix(spix) .) .
END Calc.
|