home *** CD-ROM | disk | FTP | other *** search
/ The Education Master 1994 (4th Edition) / EDUCATIONS_MASTER_4TH_EDITION.bin / files / progmisc / qparser2 / cskels / calcc.grm < prev    next >
Encoding:
Text File  |  1993-10-31  |  2.7 KB  |  92 lines

  1.    \  CALCC -- A simple four-function calculator grammar
  2.    \          which allows variable assignments.
  3.    \  Includes embedded semantics driven directly from the
  4.    \    production apply actions.
  5.  
  6. #begin apply_locals
  7.  
  8. /* These are useful shorthands for stack manipulation */
  9. #define SYMP(n)    TOS(n)->usem.symp
  10. #define FREE(n)    free((char *) TOS(n))
  11.  
  12. /* This facilitates direct evaluation of DOUBLE values */
  13. #define CCBINOP(op)  { tsemp= new_sem(FLOAT,REALVAR); \
  14.           tsemp->usem.rval= TOS(2)->usem.rval op TOS(0)->usem.rval;\
  15.           FREE(0); FREE(2); }
  16.  
  17. #end apply_locals
  18.  
  19. Goal    -> Stmts QUIT <eol> #QUIT
  20. Stmts   -> Stmts Stmt
  21.         -> <empty>
  22. Stmt    -> Expr <eol> #PRTVAL
  23.            {
  24.              printf("%lg\n", TOS(1)->usem.rval);
  25.              FREE(1);
  26.              }
  27.         -> <identifier> := Expr <eol> #ASSIGN1 
  28.            {
  29.              SYMP(3)->usym.rval= TOS(1)->usem.rval;
  30.              SYMP(3)->symt= REALVAR;
  31.              printf("%lg\n", TOS(1)->usem.rval);
  32.              FREE(1); FREE(3);
  33.              }
  34.         -> <eol>    \ allow an empty line
  35. Expr    -> Expr + Term #PLUS 
  36.            {
  37.              CCBINOP(+);
  38.              }
  39.         -> Expr - Term #MINUS 
  40.            {
  41.              CCBINOP(-);
  42.              }
  43.         -> Term
  44. Term    -> Term * Fact #MPY 
  45.            {
  46.              CCBINOP(*);
  47.              }
  48.         -> Term / Fact #DIVIDE 
  49.            {
  50.              tsemp= new_sem(FLOAT,REALVAR);
  51.              if (TOS(0)->usem.rval == 0.0) {
  52.                printf("**divide by 0: %g/0.0\n", TOS(0)->usem.rval);
  53.                tsemp->usem.rval= 1.0;
  54.                }
  55.              else tsemp->usem.rval= TOS(2)->usem.rval / TOS(0)->usem.rval;
  56.              FREE(0); FREE(2);
  57.              }
  58.         -> Fact
  59. Fact    -> Primary
  60.         -> - Primary #UMINUS 
  61.            {
  62.              tsemp= new_sem(FLOAT,REALVAR);
  63.              tsemp->usem.rval= - (TOS(0)->usem.rval);
  64.              FREE(0);
  65.              }
  66. Primary -> ( Expr ) #PARENS 
  67.            {
  68.              tsemp= TOS(1);
  69.              }
  70.         -> <identifier> #VARIABLE 
  71.            {
  72.              tsemp= new_sem(FLOAT,REALVAR);
  73.              if (SYMP(0)->symt == REALVAR)
  74.                tsemp->usem.rval= SYMP(0)->usym.rval;
  75.              else {
  76.                printf("**unknown identifier: %s\n",
  77.                       SYMP(0)->sym);
  78.                tsemp->usem.rval= 1.0;
  79.                }
  80.              FREE(0);
  81.              }
  82.         -> <real> #REALVAL 
  83.            {
  84.              tsemp= TOS(0);
  85.              }
  86.         -> <integer> #INTVAL 
  87.            {
  88.              tsemp= new_sem(FLOAT,REALVAR);
  89.              tsemp->usem.rval= TOS(0)->usem.numval;
  90.              FREE(0);
  91.              }
  92.