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 / minicond.bnf < prev    next >
Text File  |  1998-05-07  |  5KB  |  108 lines

  1. (*******************************************************************************
  2. *
  3. * RDP release 1.50 by Adrian Johnstone (A.Johnstone@rhbnc.ac.uk) 20 December 1997
  4. *
  5. * minicond.bnf - a decorated mini-conditional grammar with interpreter semantics
  6. *
  7. * This file may be freely distributed. Please mail improvements to the author.
  8. *
  9. *******************************************************************************)
  10. TITLE("Minicond interpreter V1.50 (c) Adrian Johnstone 1997")
  11. SUFFIX("m")
  12. USES("math.h")
  13.  
  14. SYMBOL_TABLE(minicond 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(1) | statement(1)] ';'}.
  22.  
  23. (* semantic rules - implemented as macros in the C code *)
  24. _insert(id)       ::= [* if (interpret) 
  25.                            symbol_insert_key(minicond, &id, sizeof(char*), 
  26.                                              sizeof(minicond_data)); 
  27.                       *].
  28. _lookup(id ret)   ::= [* {
  29.                            void * sym = symbol_lookup_key(minicond, &id, NULL);
  30.                            if (sym == NULL) /* not found! */
  31.                            {
  32.                              text_message(TEXT_ERROR_ECHO, "Undeclared variable, '%s'\n", id);
  33.                              sym = symbol_insert_key(minicond, &id, 
  34.                                                      sizeof(char*), sizeof(minicond_data));
  35.                            }
  36.                            ret = minicond_cast(sym)->i;
  37.                          }
  38.                        *].
  39. _update(id val)   ::= [* if (interpret)
  40.                          {
  41.                            void * sym = symbol_lookup_key(minicond, &id, NULL);
  42.                            if (sym == NULL) /* not found! */
  43.                            {
  44.                              text_message(TEXT_ERROR_ECHO, "Undeclared variable, '%s'\n", id);
  45.                              sym = symbol_insert_key(minicond, &id, 
  46.                                                      sizeof(char*), sizeof(minicond_data));
  47.                            }
  48.                            minicond_cast(sym)->i = val;
  49.                          }
  50.                       *].
  51. _and(dst a b)     ::= [* dst = a && b;  *].
  52. _and_not(dst a b) ::= [* dst = !a && b; *].
  53. _local_int(a)     ::= [* integer a; *].
  54.  
  55. var_dec(interpret:integer) ::=
  56.   'int' ( ID:name _insert(name)                                  (* Declaration *)
  57.       ['=' e0:val _update(name val) ]                        (* Initialisation *)
  58.     )@','.
  59.  
  60. statement(interpret:integer) ::=
  61.   ID:name '=' e0:value _update(name value) |                     (* Assignment *) 
  62.  
  63.   _local_int(flag)
  64.   'if' e0:cnd 'then' _and(flag cnd interpret) statement(flag)    (* if statement *)
  65.      [ 'else' _and_not(flag cnd interpret) statement(flag) ] |
  66.  
  67.   'print' '(' ( e0:value [* if (interpret) printf("%li", value); *] | (* output *)
  68.         String:str [* if (interpret) printf("%s", str); *]
  69.           )@','
  70.           ')'.
  71.  
  72. e0:integer ::=
  73.   e1:result ['>' e1:right  [* result = result > right; *] |      (* Greater than *)
  74.          '<' e1:right  [* result = result < right; *] |      (* Less than *)
  75.              '>=' e1:right [* result = result >= right; *] |     (* Greater than or equal *)
  76.          '<=' e1:right [* result = result <= right; *] |     (* Less than or equal *)
  77.              '==' e1:right [* result = result == right; *] |     (* Equal *)
  78.              '!=' e1:right [* result = result != right; *] ].    (* Not equal *)
  79.  
  80. e1:integer ::= e2:result {'+' e2:right [* result += right; *] |  (* Add *)
  81.                           '-' e2:right [* result -= right; *] }. (* Subtract *)
  82.  
  83. e2:integer ::= e3:result {'*' e3:right [* result *= right; *] |  (* Multiply *)
  84.                           '/' e3:right                           (* Divide *) 
  85.                           [* if (result == 0)       
  86.                                text_message(TEXT_FATAL_ECHO, "Divide by zero attempted\n"); 
  87.                              else result /= right; 
  88.                           *] 
  89.                          }. 
  90.  
  91. e3:integer ::= '+' e3:result |                                   (* Posite *)
  92.                '-' e3:result [* result = -result; *] |           (* Negate *)
  93.                e4:result.
  94.  
  95. e4:integer ::= e5:result [ '**' e4:right                         (* Exponentiate *)
  96.                            [* result = (integer) pow((double) result, (double) right); *] 
  97.                          ].
  98.  
  99. e5:integer ::= ID:name _lookup(name result) |                    (* Variable access *)
  100.                INTEGER:result |                                  (* Numeric literal *)
  101.                '(' e1:result ')'.                                (* Parenthesised expression *)
  102.  
  103. comment    ::= COMMENT_NEST('(*' '*)').                          (* Comments *)
  104.  
  105. String: char* ::= STRING_ESC('"' '\\'):result.                   (* Strings for print *)
  106.  
  107. (* End of minicond.bnf *)
  108.