home *** CD-ROM | disk | FTP | other *** search
- \ CALCC -- A simple four-function calculator grammar
- \ which allows variable assignments.
- \ Includes embedded semantics driven directly from the
- \ production apply actions.
-
- #begin apply_locals
-
- /* These are useful shorthands for stack manipulation */
- #define SYMP(n) TOS(n)->usem.symp
- #define FREE(n) free((char *) TOS(n))
-
- /* This facilitates direct evaluation of DOUBLE values */
- #define CCBINOP(op) { tsemp= new_sem(FLOAT,REALVAR); \
- tsemp->usem.rval= TOS(2)->usem.rval op TOS(0)->usem.rval;\
- FREE(0); FREE(2); }
-
- #end apply_locals
-
- Goal -> Stmts QUIT <eol> #QUIT
- Stmts -> Stmts Stmt
- -> <empty>
- Stmt -> Expr <eol> #PRTVAL
- {
- printf("%lg\n", TOS(1)->usem.rval);
- FREE(1);
- }
- -> <identifier> := Expr <eol> #ASSIGN1
- {
- SYMP(3)->usym.rval= TOS(1)->usem.rval;
- SYMP(3)->symt= REALVAR;
- printf("%lg\n", TOS(1)->usem.rval);
- FREE(1); FREE(3);
- }
- -> <eol> \ allow an empty line
- Expr -> Expr + Term #PLUS
- {
- CCBINOP(+);
- }
- -> Expr - Term #MINUS
- {
- CCBINOP(-);
- }
- -> Term
- Term -> Term * Fact #MPY
- {
- CCBINOP(*);
- }
- -> Term / Fact #DIVIDE
- {
- tsemp= new_sem(FLOAT,REALVAR);
- if (TOS(0)->usem.rval == 0.0) {
- printf("**divide by 0: %g/0.0\n", TOS(0)->usem.rval);
- tsemp->usem.rval= 1.0;
- }
- else tsemp->usem.rval= TOS(2)->usem.rval / TOS(0)->usem.rval;
- FREE(0); FREE(2);
- }
- -> Fact
- Fact -> Primary
- -> - Primary #UMINUS
- {
- tsemp= new_sem(FLOAT,REALVAR);
- tsemp->usem.rval= - (TOS(0)->usem.rval);
- FREE(0);
- }
- Primary -> ( Expr ) #PARENS
- {
- tsemp= TOS(1);
- }
- -> <identifier> #VARIABLE
- {
- tsemp= new_sem(FLOAT,REALVAR);
- if (SYMP(0)->symt == REALVAR)
- tsemp->usem.rval= SYMP(0)->usym.rval;
- else {
- printf("**unknown identifier: %s\n",
- SYMP(0)->sym);
- tsemp->usem.rval= 1.0;
- }
- FREE(0);
- }
- -> <real> #REALVAL
- {
- tsemp= TOS(0);
- }
- -> <integer> #INTVAL
- {
- tsemp= new_sem(FLOAT,REALVAR);
- tsemp->usem.rval= TOS(0)->usem.numval;
- FREE(0);
- }