home *** CD-ROM | disk | FTP | other *** search
/ cs.rhul.ac.uk / www.cs.rhul.ac.uk.zip / www.cs.rhul.ac.uk / pub / rdp / rdp_cs3460.tar / minicalc.bnf < prev    next >
Text File  |  1998-05-07  |  3KB  |  78 lines

  1. (*******************************************************************************
  2. *
  3. * RDP release 1.50 by Adrian Johnstone (A.Johnstone@rhbnc.ac.uk) 20 December 1997
  4. *
  5. * minicalc.bnf - a decorated mini calculator grammar with interpreter semantics
  6. *
  7. * This file may be freely distributed. Please mail improvements to the author.
  8. *
  9. *******************************************************************************)
  10. TITLE("Minicalc interpreter V1.50 (c) Adrian Johnstone 1997")
  11. SUFFIX("m")
  12. USES("math.h")
  13.  
  14. SYMBOL_TABLE(mini 101 31
  15.              symbol_compare_string
  16.              symbol_hash_string
  17.              symbol_print_string
  18.              [* char* id; integer i; *]
  19.             )
  20.  
  21. program   ::= {[var_dec | statement ] ';' }.
  22.  
  23. var_dec   ::= 'int'
  24.               ( ID:name [ '=' e1:val ]
  25.                 [* mini_cast(symbol_insert_key(mini, &name, sizeof(char*), sizeof(mini_data)))
  26.                    ->i = val; 
  27.                 *]
  28.               )@','.
  29.  
  30. statement ::= ID:name
  31.               [* if (symbol_lookup_key(mini, &name, NULL) == NULL)
  32.                  {
  33.                    text_message(TEXT_ERROR, "Undeclared variable '%s'\n", name);
  34.                    symbol_insert_key(mini, &name, sizeof(char*), sizeof(mini_data));
  35.                  }
  36.               *]
  37.               '=' e1:val
  38.               [* mini_cast(symbol_lookup_key(mini, &name, NULL))->i = val; *] |
  39.  
  40.               'print' '(' ( e1:val [* printf("%li", val); *] |
  41.                             String:str [* printf("%s", str); *]
  42.                           )@','
  43.                       ')'.
  44.  
  45. e1:integer ::= e2:result {'+' e2:right [* result += right; *] |          (* Add *)
  46.                           '-' e2:right [* result -= right; *] }.         (* Subtract *)
  47.  
  48. e2:integer ::= e3:result {'*' e3:right [* result *= right; *] |          (* Multiply *)
  49.                           '/' e3:right [* if (result == 0) 
  50.                text_message(TEXT_FATAL_ECHO, "Divide by zero attempted\n"); else result /= right; *] 
  51.                          }.                                              (* Divide *)
  52.  
  53. e3:integer ::= '+' e3:result |                                           (* Posite *)
  54.                '-' e3:result [* result = -result; *] |                   (* Negate *)
  55.                e4:result.
  56.  
  57. e4:integer ::= e5:result [ '**' e4:right 
  58.                            [* result = (integer) pow((double) result, (double) right); *] 
  59.                          ]                                               (* Exponentiate *).
  60.  
  61. e5:integer ::= ID:name 
  62.                [* if (symbol_lookup_key(mini, &name, NULL) == NULL)
  63.                  {
  64.                    text_message(TEXT_ERROR, "Undeclared variable '%s'\n", name);
  65.                    symbol_insert_key(mini, &name, sizeof(char*), sizeof(mini_data));
  66.                  }
  67.               *]
  68.                [* result = mini_cast(symbol_lookup_key(mini, &name, NULL))->i; *] | (* Variable *)
  69.                INTEGER:result |                                          (* Numeric literal *)
  70.                '(' e1:result ')'.                                        (* Do-first *)
  71.  
  72. comment    ::= COMMENT_NEST('(*' '*)').                                  (* Comments *)
  73.  
  74. String: char * ::= STRING_ESC('"' '\\'):result.                          (* Strings for print *)
  75.  
  76. (* End of minicalc.bnf *)
  77.  
  78.