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_cs3470.tar / miniloop.bnf < prev    next >
Text File  |  1998-05-07  |  5KB  |  115 lines

  1. (*******************************************************************************
  2. *
  3. * RDP release 1.50 by Adrian Johnstone (A.Johnstone@rhbnc.ac.uk) 20 December 1997
  4. *
  5. * miniloop.bnf - a decorated mini loop grammar with single pass compiler semantics
  6. *
  7. * This file may be freely distributed. Please mail improvements to the author.
  8. *
  9. *******************************************************************************)
  10. TITLE("Miniloop compiler V1.50 (c) Adrian Johnstone 1997")
  11. SUFFIX("m")
  12. TREE
  13. PARSER(program)
  14. USES("ml_aux.h")
  15. TREE
  16. OUTPUT_FILE("miniloop.mvm")
  17.  
  18. SYMBOL_TABLE(mini 101 31
  19.          symbol_compare_string
  20.          symbol_hash_string
  21.          symbol_print_string
  22.          [* char* id; *]
  23.         )
  24.  
  25. check_declared ::= [* if (symbol_lookup_key(mini, &dst, NULL) == NULL)
  26.               {
  27.                 text_message(TEXT_ERROR, "Undeclared variable '%s'\n", dst);
  28.                 symbol_insert_key(mini, &dst, sizeof(char*), sizeof(mini_data));
  29.               }
  30.                *].
  31.  
  32. program   ::=  [* emit_open(rdp_sourcefilename, rdp_outputfilename); *]
  33.                { [var_dec | statement] ';'} 
  34.                [* emit_close(); *].
  35.  
  36. var_dec ::= 'int' ( ID:dst 
  37.                     [* emitf(" \n DATA\n%s: WORD 1\n\n CODE\n",dst); *]
  38.                     ['=' e0:left [* emit("CPY", "", dst, left, NULL); *] ] 
  39.                     [* symbol_insert_key(mini, &dst, sizeof(char*), sizeof(mini_data)); 
  40.                        if (*dst == '_' && *(dst+1) == '_')
  41.                          text_message(TEXT_ERROR_ECHO, "variable names must not begin with two underscores\n");
  42.                     *]
  43.                   )@','.                       (* Declaration *)
  44.  
  45. statement ::= ID:dst check_declared
  46.               '=' e0:left [* emit("CPY", "", dst, left, NULL); *] |                                     (* Assignment *)
  47.  
  48.               [* integer label = new_label(); *]        (* if statement *)
  49.               [* emitf("__IF_%lu:\n", label); *]
  50.               'if' e0:left
  51.               [* emitf(" BEQ  %s,__ELSE_%lu\t;ifn %s go to __ELSE_%lu \n",left,label,left, label); *]
  52.               'then' statement
  53.               [* emitf(" BRA  __FI_%lu\t;go to __FI_%lu\n__ELSE_%lu:\n", label, label, label); *]
  54.               [ 'else' statement ]
  55.               [* emitf("__FI_%lu:\n", label); *] |
  56.  
  57.               [* integer label = new_label(); *]        (* while do statement *)
  58.               [* emitf("__DO_%lu:\n", label); *]
  59.               'while' e0:left
  60.               [* emitf(" BEQ  %s,__OD_%lu\t;ifn %s go to __OD_%lu \n",left,label,left, label); *]
  61.               'do' statement
  62.               [* emitf(" BRA  __DO_%lu\t;go to __DO_%lu\n__OD_%lu:\n", label, label, label); *] |
  63.  
  64.               'print' '(' ( e0:left [* emit_print('I', left); *] |
  65.                             String:left [* emit_print('S', left); *]
  66.                           )@',' ')' |            (* print statement *)
  67.  
  68.               'begin' (statement)@';' 'end'.  (* compound statement *)
  69.  
  70. e0:char* ::= [* char* dst; *] e1:left [ [* dst = new_temporary(); *]
  71.                ('>' e1:right [* emit("GT ", ">", dst, left, right); *]  |  (* Greater than *)
  72.                 '<' e1:right [* emit("LT ", "<", dst, left, right); *]  |  (* Less than *)
  73.                 '>=' e1:right [* emit("GE ", ">=", dst, left, right); *]|  (* Greater than or equal *)
  74.                 '<=' e1:right [* emit("LE ", ">=", dst, left, right); *]|  (* Less than or equal *)
  75.                 '==' e1:right [* emit("EQ ", "==", dst, left, right); *]|  (* Equal *)
  76.                 '!=' e1:right [* emit("NE ", "!=", dst, left, right); *]   (* Not equal *)
  77.                ) [* left = dst; *]
  78.              ] [* result = left; *].
  79.  
  80. e1:char* ::= [* char* dst; *] e2:left { [* dst = new_temporary(); *]
  81.                ( '+' e2:right [* emit("ADD", "+", dst, left, right); *] |   (* Add *)
  82.                  '-' e2:right [* emit("SUB", "-", dst, left, right); *]     (* Subtract *)
  83.                )
  84.                [* left = dst; *]
  85.              } [* result = left; *].
  86.  
  87. e2:char* ::= [* char* dst; *] e3:left { [* dst = new_temporary(); *]
  88.                ( '*' e3:right [* emit("MUL", "*", dst, left, right); *] |   (* Multiply *)
  89.                  '/' e3:right [* emit("DIV", "/", dst, left, right); *]     (* Divide *)
  90.                )
  91.                [* left = dst; *]
  92.              } [* result = left; *].
  93.  
  94. e3:char* ::= [* int negate = 0; char* dst;*]
  95.  
  96.              {('+'|'-' [* negate ^= 1; *])} e4:result (* Posite or negate *)
  97.              [* if (negate) {dst = new_temporary(); emit("SUB", "-", dst, "0", result); result = dst; } *].
  98.  
  99. e4:char* ::= [* char *dst; *]
  100.              e5:left
  101.              [ [* dst = new_temporary(); *]
  102.                '**' e4:right [* emit("EXP", "**", dst, left, right);  *] (* Exponentiate *)
  103.                [* left = dst; *]
  104.              ] [* result = left; *].
  105.  
  106. e5:char* ::= ID:dst check_declared [* result = dst; *] |           (* Variable access *)
  107.              INTEGER:val [* result = (char*) mem_malloc(12); sprintf(result, "#%lu", val); *] |      (* Numeric literal *)
  108.             '(' e1:result ')'.    (* Parenthesised expression *)
  109.  
  110. comment ::= COMMENT_NEST('(*' '*)').  (* Comments: stripped by lexer *)
  111. String:char*  ::= STRING_ESC('"' '\\'):result.     (* Strings for print *)
  112.  
  113. (* End of miniloop.bnf *)
  114.  
  115.