123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311 |
- /* $Id$ */
- /*
- * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
- * See the copyright notice in the ACK home directory, in the file "Copyright".
- */
- /* t o p g e n . g
- *
- * Grammar of optimizer description, and some code generation
- */
- %token LETTER, DIGIT, OTHER, SPACE;
- %token LINE_TERMINATOR, OPERAND_SEPARATOR, INSTRUCTION_SEPARATOR,
- PATTERN_SEPARATOR, OPEN_BRACKET, CLOSE_BRACKET;
- %lexical LLlex;
- %start LLparse, optim_description;
- {
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include "token.h"
- #include "symtab.h"
- #include "misc.h"
- char idbuf[BUFSIZ], buf[BUFSIZ];
- int countid; /* # of variables */
- int countpat; /* # of patterns */
- static int patlen; /* Maximum number of instructions in pattern */
- static int maxoperand; /* Maximum number of operands of instruction */
- extern FILE *input; /* file descriptor of inputfile */
- }
- optim_description
- { struct symtab *p; } :
- SPACE* parameter_line*
- { p = findident("MAXOP",LOOKING,&deftable);
- if (p == 0) maxoperand = 2; /* default */
- else maxoperand = p->s_num;
- }
- separator SPACE* mode_definitions
- separator SPACE* patterns
- separator
- { register int c;
- fprintf(genc, linedir, lineno, inpfile);
- while ((c = getc(input)) != EOF) {
- putc(c,genc);
- }
- }
- ;
- parameter_line
- { struct symtab *p;} :
- identifier
- { p = findident(idbuf,ENTERING,&deftable);}
- SPACE
- value
- { p->s_num = atoi(buf);}
- /* This action in fact only needed for MAXOP */
- LINE_TERMINATOR
- SPACE*
- { fprintf(genh,"#define %s %s\n",p->s_name,buf);}
- ;
- value
- { char *p1 = buf;} :
- [
- [ OPEN_BRACKET
- | CLOSE_BRACKET
- | OPERAND_SEPARATOR
- | PATTERN_SEPARATOR
- | INSTRUCTION_SEPARATOR
- | SPACE
- | LETTER
- | DIGIT
- | OTHER
- | '%'
- ]
- { *p1++ = dot.t_attrib;}
- ]*
- { *p1 = '\0';}
- ;
- mode_definitions
- { int lin; } :
- { fputs("tok_chk(varno) {\n\tint r;\n", genc);
- fputs("\tchar *VAL;\n\n",genc);
- fputs("\tVAL = var[varno].value;\n",genc);
- fputs("\tswitch(varno) {\n",genc);
- }
- [
- token_list
- constraint(&lin)
- { fprintf(genc,linedir,lin,inpfile);
- fprintf(genc,"\t\tr = (%s); break;\n",buf);
- }
- LINE_TERMINATOR
- SPACE*
- ]*
- { fputs("\tdefault :\n\t\tassert(0);\n",genc);
- fputs("\t}\n\treturn r;\n}\n\n",genc);
- }
- ;
- token_list :
- new_identifier
- SPACE*
- [
- OPERAND_SEPARATOR
- SPACE*
- new_identifier
- SPACE*
- ]*
- ;
- new_identifier
- { struct symtab *p;} :
- identifier
- { p = findident(idbuf,ENTERING,&idtable);
- p->s_num = ++countid;
- fprintf(genc,"\tcase %d:\n", countid);
- }
- ;
- constraint (int *lin;)
- { char *p = buf; } :
- OPEN_BRACKET
- { *lin = lineno;}
- [
- [ LINE_TERMINATOR
- | OPERAND_SEPARATOR
- | PATTERN_SEPARATOR
- | INSTRUCTION_SEPARATOR
- | LETTER
- | DIGIT
- | SPACE
- | OTHER
- | '%'
- ]
- { *p++ = dot.t_attrib;}
- ]*
- { *p = '\0';
- if (onlyspace(buf)) strcpy(buf,"TRUE");
- }
- CLOSE_BRACKET
- SPACE*
- ;
- patterns
- { int lin;
- char *constr;
- int np, nr;
- } :
- [
- { countpat++;
- constr = (char *) 0;
- fprintf(genc,"struct instr_descr pat%d[] = {\n",
- countpat);
- }
- instruction_list(&np)
- { if (np > patlen) patlen = np;
- fputs("\n};\n\n",genc);
- }
- [
- constraint(&lin)
- { /* Save the constraint, we need it later on */
- constr = malloc((unsigned)(strlen(buf)+1));
- strcpy(constr,buf);
- }
- ]?
- PATTERN_SEPARATOR
- { fprintf(genc,"struct instr_descr rep%d[] = {\n",
- countpat);
- }
- replacement(&nr)
- { fputs("\n};\n\n",genc);}
- LINE_TERMINATOR
- SPACE*
- { addpattern(constr,lin,np,nr);}
- ]*
- { printhashtable();
- printpatterns();
- fprintf(genh,"#define NRVARS %d\n",countid);
- fprintf(genh,"#define NRPATTERNS %d\n",countpat);
- fprintf(genh,"#define MIN_WINDOW_SIZE %d\n",
- patlen+3);
- fclose(genh);
- }
- ;
- instruction_list(int *n;) :
- instruction(1)
- { *n = 1;}
- [
- INSTRUCTION_SEPARATOR
- { fputs(",\n",genc);}
- SPACE*
- instruction(0)
- { *n += 1;}
- ]*
- ;
- instruction(int opt;)
- { int count = 0;} :
- opcode(opt)
- { if (strcmp(buf,"ANY") != 0) {
- fprintf(genc,"\t{\"%s\", {",buf);
- }
- else fputs("\t{(char *) 0, {",genc);
- count = 0;
- }
- [
- operand(' ')
- { count = 1;}
- [
- OPERAND_SEPARATOR
- { count++;}
- SPACE*
- operand(',')
- ]*
- { if (count > maxoperand) {
- error("Too many operands");
- }
- }
- ]?
- { while (count++ < maxoperand) {
- fprintf(genc,"%c{\"\",-1,\"\"}",count == 1 ? ' ' : ',');
- }
- putc('}',genc);
- putc('}',genc);
- }
- ;
- opcode(int opt;)
- { char *p = buf;} :
- [
- [ LETTER
- | DIGIT
- | OTHER
- ]
- { *p++ = dot.t_attrib;}
- ]+
- SPACE+
- { *p = '\0';
- if (opt) addtohashtable(buf,countpat);
- }
- ;
- operand(int c;)
- { register struct symtab *p = 0;} :
- { fprintf(genc, "%c{\"", c);}
- [
- identifier
- { if (!p) {
- p = findident(idbuf,LOOKING,&idtable);
- if (p) fprintf(genc,"\",%d,\"",p->s_num);
- else fputs(idbuf,genc);
- }
- else fputs(idbuf,genc);
- }
- | DIGIT
- { putc(dot.t_attrib,genc);}
- | OTHER
- { putc(dot.t_attrib,genc);}
- ]+
- { if (p) fputs("\"}",genc);
- else fputs("\",0,\"\"}",genc);
- }
- SPACE*
- ;
- replacement (int *n;)
- {register i;} :
- SPACE*
- { *n = 0;}
- [
- instruction(0)
- { *n = 1;}
- [
- INSTRUCTION_SEPARATOR
- { fputs(",\n", genc);}
- SPACE*
- instruction(0)
- { *n += 1;}
- ]*
- | /* empty replacement, but there must be a
- * structure initializer anyway
- */
- { fputs("\t{\"\", {",genc);
- for (i = 0; i < maxoperand; i++) {
- fprintf(genc, "%c{\"\",-1,\"\"}",i?',':' ');
- }
- fputs("}}",genc);
- }
- ]
- ;
- identifier
- { char *p = idbuf; } :
- LETTER
- { *p++ = dot.t_attrib;}
- [ %while (1)
- LETTER { *p++ = dot.t_attrib;}
- | DIGIT { *p++ = dot.t_attrib;}
- ]*
- { *p = '\0';}
- ;
- separator :
- '%' '%' SPACE* LINE_TERMINATOR
- ;
|