topgen.g 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. /* $Id$ */
  2. /*
  3. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  4. * See the copyright notice in the ACK home directory, in the file "Copyright".
  5. */
  6. /* t o p g e n . g
  7. *
  8. * Grammar of optimizer description, and some code generation
  9. */
  10. %token LETTER, DIGIT, OTHER, SPACE;
  11. %token LINE_TERMINATOR, OPERAND_SEPARATOR, INSTRUCTION_SEPARATOR,
  12. PATTERN_SEPARATOR, OPEN_BRACKET, CLOSE_BRACKET;
  13. %lexical LLlex;
  14. %start LLparse, optim_description;
  15. {
  16. #include <stdlib.h>
  17. #include <stdio.h>
  18. #include <string.h>
  19. #include "token.h"
  20. #include "symtab.h"
  21. #include "misc.h"
  22. char idbuf[BUFSIZ], buf[BUFSIZ];
  23. int countid; /* # of variables */
  24. int countpat; /* # of patterns */
  25. static int patlen; /* Maximum number of instructions in pattern */
  26. static int maxoperand; /* Maximum number of operands of instruction */
  27. extern FILE *input; /* file descriptor of inputfile */
  28. }
  29. optim_description
  30. { struct symtab *p; } :
  31. SPACE* parameter_line*
  32. { p = findident("MAXOP",LOOKING,&deftable);
  33. if (p == 0) maxoperand = 2; /* default */
  34. else maxoperand = p->s_num;
  35. }
  36. separator SPACE* mode_definitions
  37. separator SPACE* patterns
  38. separator
  39. { register int c;
  40. fprintf(genc, linedir, lineno, inpfile);
  41. while ((c = getc(input)) != EOF) {
  42. putc(c,genc);
  43. }
  44. }
  45. ;
  46. parameter_line
  47. { struct symtab *p;} :
  48. identifier
  49. { p = findident(idbuf,ENTERING,&deftable);}
  50. SPACE
  51. value
  52. { p->s_num = atoi(buf);}
  53. /* This action in fact only needed for MAXOP */
  54. LINE_TERMINATOR
  55. SPACE*
  56. { fprintf(genh,"#define %s %s\n",p->s_name,buf);}
  57. ;
  58. value
  59. { char *p1 = buf;} :
  60. [
  61. [ OPEN_BRACKET
  62. | CLOSE_BRACKET
  63. | OPERAND_SEPARATOR
  64. | PATTERN_SEPARATOR
  65. | INSTRUCTION_SEPARATOR
  66. | SPACE
  67. | LETTER
  68. | DIGIT
  69. | OTHER
  70. | '%'
  71. ]
  72. { *p1++ = dot.t_attrib;}
  73. ]*
  74. { *p1 = '\0';}
  75. ;
  76. mode_definitions
  77. { int lin; } :
  78. { fputs("tok_chk(varno) {\n\tint r;\n", genc);
  79. fputs("\tchar *VAL;\n\n",genc);
  80. fputs("\tVAL = var[varno].value;\n",genc);
  81. fputs("\tswitch(varno) {\n",genc);
  82. }
  83. [
  84. token_list
  85. constraint(&lin)
  86. { fprintf(genc,linedir,lin,inpfile);
  87. fprintf(genc,"\t\tr = (%s); break;\n",buf);
  88. }
  89. LINE_TERMINATOR
  90. SPACE*
  91. ]*
  92. { fputs("\tdefault :\n\t\tassert(0);\n",genc);
  93. fputs("\t}\n\treturn r;\n}\n\n",genc);
  94. }
  95. ;
  96. token_list :
  97. new_identifier
  98. SPACE*
  99. [
  100. OPERAND_SEPARATOR
  101. SPACE*
  102. new_identifier
  103. SPACE*
  104. ]*
  105. ;
  106. new_identifier
  107. { struct symtab *p;} :
  108. identifier
  109. { p = findident(idbuf,ENTERING,&idtable);
  110. p->s_num = ++countid;
  111. fprintf(genc,"\tcase %d:\n", countid);
  112. }
  113. ;
  114. constraint (int *lin;)
  115. { char *p = buf; } :
  116. OPEN_BRACKET
  117. { *lin = lineno;}
  118. [
  119. [ LINE_TERMINATOR
  120. | OPERAND_SEPARATOR
  121. | PATTERN_SEPARATOR
  122. | INSTRUCTION_SEPARATOR
  123. | LETTER
  124. | DIGIT
  125. | SPACE
  126. | OTHER
  127. | '%'
  128. ]
  129. { *p++ = dot.t_attrib;}
  130. ]*
  131. { *p = '\0';
  132. if (onlyspace(buf)) strcpy(buf,"TRUE");
  133. }
  134. CLOSE_BRACKET
  135. SPACE*
  136. ;
  137. patterns
  138. { int lin;
  139. char *constr;
  140. int np, nr;
  141. } :
  142. [
  143. { countpat++;
  144. constr = (char *) 0;
  145. fprintf(genc,"struct instr_descr pat%d[] = {\n",
  146. countpat);
  147. }
  148. instruction_list(&np)
  149. { if (np > patlen) patlen = np;
  150. fputs("\n};\n\n",genc);
  151. }
  152. [
  153. constraint(&lin)
  154. { /* Save the constraint, we need it later on */
  155. constr = malloc((unsigned)(strlen(buf)+1));
  156. strcpy(constr,buf);
  157. }
  158. ]?
  159. PATTERN_SEPARATOR
  160. { fprintf(genc,"struct instr_descr rep%d[] = {\n",
  161. countpat);
  162. }
  163. replacement(&nr)
  164. { fputs("\n};\n\n",genc);}
  165. LINE_TERMINATOR
  166. SPACE*
  167. { addpattern(constr,lin,np,nr);}
  168. ]*
  169. { printhashtable();
  170. printpatterns();
  171. fprintf(genh,"#define NRVARS %d\n",countid);
  172. fprintf(genh,"#define NRPATTERNS %d\n",countpat);
  173. fprintf(genh,"#define MIN_WINDOW_SIZE %d\n",
  174. patlen+3);
  175. fclose(genh);
  176. }
  177. ;
  178. instruction_list(int *n;) :
  179. instruction(1)
  180. { *n = 1;}
  181. [
  182. INSTRUCTION_SEPARATOR
  183. { fputs(",\n",genc);}
  184. SPACE*
  185. instruction(0)
  186. { *n += 1;}
  187. ]*
  188. ;
  189. instruction(int opt;)
  190. { int count = 0;} :
  191. opcode(opt)
  192. { if (strcmp(buf,"ANY") != 0) {
  193. fprintf(genc,"\t{\"%s\", {",buf);
  194. }
  195. else fputs("\t{(char *) 0, {",genc);
  196. count = 0;
  197. }
  198. [
  199. operand(' ')
  200. { count = 1;}
  201. [
  202. OPERAND_SEPARATOR
  203. { count++;}
  204. SPACE*
  205. operand(',')
  206. ]*
  207. { if (count > maxoperand) {
  208. error("Too many operands");
  209. }
  210. }
  211. ]?
  212. { while (count++ < maxoperand) {
  213. fprintf(genc,"%c{\"\",-1,\"\"}",count == 1 ? ' ' : ',');
  214. }
  215. putc('}',genc);
  216. putc('}',genc);
  217. }
  218. ;
  219. opcode(int opt;)
  220. { char *p = buf;} :
  221. [
  222. [ LETTER
  223. | DIGIT
  224. | OTHER
  225. ]
  226. { *p++ = dot.t_attrib;}
  227. ]+
  228. SPACE+
  229. { *p = '\0';
  230. if (opt) addtohashtable(buf,countpat);
  231. }
  232. ;
  233. operand(int c;)
  234. { register struct symtab *p = 0;} :
  235. { fprintf(genc, "%c{\"", c);}
  236. [
  237. identifier
  238. { if (!p) {
  239. p = findident(idbuf,LOOKING,&idtable);
  240. if (p) fprintf(genc,"\",%d,\"",p->s_num);
  241. else fputs(idbuf,genc);
  242. }
  243. else fputs(idbuf,genc);
  244. }
  245. | DIGIT
  246. { putc(dot.t_attrib,genc);}
  247. | OTHER
  248. { putc(dot.t_attrib,genc);}
  249. ]+
  250. { if (p) fputs("\"}",genc);
  251. else fputs("\",0,\"\"}",genc);
  252. }
  253. SPACE*
  254. ;
  255. replacement (int *n;)
  256. {register i;} :
  257. SPACE*
  258. { *n = 0;}
  259. [
  260. instruction(0)
  261. { *n = 1;}
  262. [
  263. INSTRUCTION_SEPARATOR
  264. { fputs(",\n", genc);}
  265. SPACE*
  266. instruction(0)
  267. { *n += 1;}
  268. ]*
  269. | /* empty replacement, but there must be a
  270. * structure initializer anyway
  271. */
  272. { fputs("\t{\"\", {",genc);
  273. for (i = 0; i < maxoperand; i++) {
  274. fprintf(genc, "%c{\"\",-1,\"\"}",i?',':' ');
  275. }
  276. fputs("}}",genc);
  277. }
  278. ]
  279. ;
  280. identifier
  281. { char *p = idbuf; } :
  282. LETTER
  283. { *p++ = dot.t_attrib;}
  284. [ %while (1)
  285. LETTER { *p++ = dot.t_attrib;}
  286. | DIGIT { *p++ = dot.t_attrib;}
  287. ]*
  288. { *p = '\0';}
  289. ;
  290. separator :
  291. '%' '%' SPACE* LINE_TERMINATOR
  292. ;