home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / program / mit2mot1 / parser.y < prev    next >
Encoding:
Lex Description  |  1993-10-23  |  6.2 KB  |  246 lines

  1. %{
  2. extern unsigned long tmp_labels[10][2], tmp_label_cnt;
  3. %}
  4.  
  5. %union {
  6.   long numval;
  7.   char str[256];
  8. }
  9.  
  10. %token NL
  11. %token <str> OP OP_MREG ID STRING REG TMPLABEL TMPLABELfb
  12. %token <str> D_COMM D_LCOMM D_ELIST D_IDLIST D_NONE D_OPTINT D_ORG
  13. %token <str> D_SLIST D_UNS
  14. %token <numval> NUMBER
  15.  
  16. %type <str> operand reglist regrange expr sym_expr size_field
  17. %type <str> expr_list id_list string_list
  18. %type <numval> num_val op
  19.  
  20. %left '+' '-'
  21. %left '&' '^' '!' '|'
  22. %left '*' '/' '%' '>' '<'
  23. %left UMINUS
  24.  
  25. %%
  26.  
  27. prog: linelist;
  28.  
  29. linelist: /* nothing */
  30.         | linelist line {fputc('\n', yyout);}
  31.         ;
  32.  
  33. line: label directive NL
  34.     | label instr NL
  35.     | label NL
  36.     ;
  37.  
  38. label: /* nothing */
  39.      | ID ':' {fprintf(yyout, "%s:", $1);}
  40.      | TMPLABEL {
  41.        int i = $1[0] - '0';
  42.      if (tmp_labels[i][1] == 0)
  43.        tmp_labels[i][0] = ++tmp_label_cnt;
  44.      else
  45.        tmp_labels[i][0] = tmp_labels[i][1];
  46.      tmp_labels[i][1] = 0;
  47.      fprintf(yyout, "LT%lu:", tmp_labels[i][0]);
  48.        }
  49.      ;
  50.  
  51. directive: D_COMM ID ',' num_val {
  52.          fprintf(yyout, "\t%s\t%s, %ld", $1, $2, $4);
  53.        }
  54.      | D_LCOMM ID ',' num_val {
  55.          fprintf(yyout, "%s:%s\t%s\t%ld", $2,
  56.            (strlen($2) <= 6 ? "" : "\n"), $1, $4
  57.          );
  58.        }
  59.      | D_ELIST expr_list {fprintf(yyout, "\t%s\t%s", $1, $2);}
  60.      | D_IDLIST id_list {fprintf(yyout, "\t%s\t%s", $1, $2);}
  61.      | D_NONE {fprintf(yyout, "\t%s", $1);}
  62.      | D_OPTINT {fprintf(yyout, "\t%s", $1);}
  63.      | D_OPTINT num_val {fprintf(yyout, "\t%s", $1);}
  64.      | D_ORG expr {fprintf(yyout, "\t%s\t%s", $1, $2);}
  65.      | D_SLIST string_list {fprintf(yyout, "\t%s\t%s", $1, $2);}
  66.      | D_UNS {yyerror("warning: unsupported assembler directive %s", $1);}
  67.      ;
  68.  
  69. instr: OP {fprintf(yyout, "\t%s", $1);}
  70.      | OP operand {fprintf(yyout, "\t%s\t%s", $1, $2);}
  71.      | OP operand ',' operand {fprintf(yyout, "\t%s\t%s, %s", $1, $2, $4);}
  72.      | OP_MREG reglist ',' operand {
  73.      fprintf(yyout, "\t%s\t%s, %s", $1, $2, $4);
  74.        }
  75.      | OP_MREG operand ',' reglist {
  76.      fprintf(yyout, "\t%s\t%s, %s", $1, $2, $4);
  77.        }
  78.      ;
  79.  
  80. operand: '#' expr {sprintf($$, "#%s", $2);}
  81.        | REG {strcpy($$, $1);}
  82.        | REG '@' {sprintf($$, "(%s)", $1);}
  83.        | REG '@' '+' {sprintf($$, "(%s)+", $1);}
  84.        | REG '@' '-' {sprintf($$, "-(%s)", $1);}
  85.        | REG '@' '(' expr ')' {sprintf($$, "%s(%s)", $4, $1);}
  86.        | REG '@' '(' expr ',' REG size_field ')' {
  87.        sprintf($$, "%s(%s,%s%s)", $4, $1, $6, $7);
  88.      }
  89.        | expr {strcpy($$, $1);}
  90.        ;
  91.  
  92. size_field: /* nothing */  {$$[0] = '\0';}
  93.       | ':' ID {sprintf($$, ".%s", $2);}
  94.       ;
  95.  
  96. reglist: regrange {strcpy($$, $1);}
  97.        | REG '/' REG {sprintf($$, "%s/%s", $1, $3);}
  98.        | REG '/' regrange {sprintf($$, "%s/%s", $1, $3);}
  99.        | reglist '/' REG {sprintf($$, "%s/%s", $1, $3);}
  100.        | reglist '/' regrange {sprintf($$, "%s/%s", $1, $3);}
  101.        ;
  102.  
  103. regrange: REG '-' REG {sprintf($$, "%s-%s", $1, $3);}
  104.     ;
  105.  
  106. expr: num_val {sprintf($$, "%ld", $1);}
  107.     | sym_expr {strcpy($$, $1);}
  108.     ;
  109.  
  110. sym_expr: ID {strcpy($$, $1);}
  111.     | TMPLABELfb {
  112.       int i = $1[0] - '0';
  113.       unsigned long l;
  114.         if ($1[1] == 'f') {
  115.           if (tmp_labels[i][1] == 0)
  116.         tmp_labels[i][1] = ++tmp_label_cnt;
  117.           l = tmp_labels[i][1];
  118.         } else {
  119.           l = tmp_labels[i][0];
  120.           if (l == 0)
  121.         yyerror("Unresolved temporary label %db", i);
  122.         }
  123.         sprintf($$, "LT%lu", l);
  124.       }
  125.     | sym_expr op sym_expr {sprintf($$, "%s%c%s", $1, (char)$2, $3);}
  126.     | num_val op sym_expr {sprintf($$, "%ld%c%s", $1, (char)$2, $3);}
  127.     | sym_expr op num_val {sprintf($$, "%s%c%ld", $1, (char)$2, $3);}
  128.     ;
  129.  
  130. op: '+' {$$ = '+';}
  131.   | '-' {$$ = '-';}
  132.   | '&' {$$ = '&';}
  133.   | '^' {$$ = '^';}
  134.   | '!' {$$ = '!';}
  135.   | '|' {$$ = '|';}
  136.   | '*' {$$ = '&';}
  137.   | '/' {$$ = '/';}
  138.   | '%' {$$ = '%';}
  139.   | '<' {$$ = '<';}
  140.   | '>' {$$ = '>';}
  141.   ;
  142.  
  143. num_val: NUMBER {$$ = $1;}
  144.        | num_val '+' num_val {$$ = $1 + $3;}
  145.        | num_val '-' num_val {$$ = $1 - $3;}
  146.        | num_val '&' num_val {$$ = $1 & $3;}
  147.        | num_val '^' num_val {$$ = $1 ^ $3;}
  148.        | '!' num_val {$$ = !$2;}
  149.        | num_val '|' num_val {$$ = $1 | $3;}
  150.        | num_val '*' num_val {$$ = $1 & $3;}
  151.        | num_val '/' num_val {$$ = $1 / $3;}
  152.        | num_val '%' num_val {$$ = $1 % $3;}
  153.        | num_val '<' num_val {$$ = $1 << $3;}
  154.        | num_val '>' num_val {$$ = $1 >> $3;}
  155.        | '-' num_val %prec UMINUS {$$ = -$2;}
  156.        | '(' num_val ')' {$$ = $2;}
  157.        ;
  158.  
  159. expr_list: expr {strcpy($$, $1);}
  160.      | expr_list ',' expr {sprintf($$, "%s, %s", $1, $3);}
  161.      ;
  162.  
  163. id_list: ID {strcpy($$, $1);}
  164.        | id_list ',' ID {sprintf($$, "%s, %s", $1, $3);}
  165.        ;
  166.  
  167. string_list: STRING {strcpy($$, $1);}
  168.        | string_list ',' STRING {sprintf($$, "%s, %s", $1, $3);}
  169.        ;
  170.  
  171. %%
  172.  
  173. #include <stdarg.h>
  174. #include <string.h>
  175. #include <time.h>
  176. #include "global.h"
  177. #include "patchlev.h"
  178.  
  179. unsigned long tmp_labels[10][2];
  180. unsigned long tmp_label_cnt;
  181.  
  182. main(ac, av)
  183.      int ac;
  184.      char *av[];
  185. {
  186.   char *s, buf[40];
  187.   int i;
  188.   time_t t;
  189.   struct tm *T;
  190.  
  191.   if ((ac != 2) && (ac != 4)) {
  192.     fprintf(stderr, "usage: %s [-o filename] filename\n", av[0]);
  193.     exit(1);
  194.   }
  195.   if (!(yyin = fopen(av[ac - 1], "r"))) {
  196.     fprintf(stderr, "%s: cannot open input file %s\n", av[0], av[ac - 1]);
  197.     exit(1);
  198.   }
  199.   if (ac == 4) {
  200.     strcpy(buf, av[2]);
  201.   } else {
  202.     strcpy(buf, av[ac - 1]);
  203.     s = strrchr(buf, '.');
  204.     if (!s)
  205.       strcat(buf, ".s");
  206.     else
  207.       strcpy(s + 1, "s");
  208.   }
  209.   if (!(yyout = fopen(buf, "w"))) {
  210.     fprintf(stderr, "%s: cannot open output file %s\n", av[0], buf);
  211.     exit(1);
  212.   }
  213.   time(&t);
  214.   T = localtime(&t);
  215.   strftime(buf, 40, "%b %d %Y %H:%M:%S", T);
  216.   fprintf(yyout, "; Generated by mit2mot v%d.%d.%d on %s\n\n",
  217.     M2M_VERSION, M2M_RELEASE, M2M_PATCHLEVEL, buf);
  218.   init_hash();
  219.   yyparse();
  220.   for (i = 0; i < 10; i++)
  221.     if (tmp_labels[i][1] != 0) {
  222.       yyerror("Unresolved temporary label %df", i);
  223.       fprintf(yyout, "LT%lu:\n", tmp_labels[i][1]);
  224.     }
  225.   clear_hash();
  226.   fclose(yyin);
  227.   fclose(yyout);
  228.   return 0;
  229. }
  230.  
  231. void yyerror(s)
  232.      char *s;
  233. {
  234.   va_list ap;
  235.  
  236.   fprintf(stderr, "At line %lu:  ", line_num);
  237.   va_start(ap, s);
  238.   vfprintf(stderr, s, ap);
  239.   va_end(ap);
  240.   fputc('\n', stderr);
  241. }
  242.  
  243. #ifndef yywrap
  244. yywrap() {return 1;}
  245. #endif
  246.