topgen.g 6.1 KB

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