Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

335 lines
6.4 KiB

  1. /** opprec.c - compute operator predecence function values
  2. * R. A. Garmoe 89/05/09
  3. */
  4. /* This program accepts a directed graph (in matrix form) and calculates
  5. * the operator precedence function values f(op) and g(op). For more
  6. * information see Compilers: Principles, Techniques and Tools, by Aho,
  7. * Sethi and Ullman [Addison-Wesley], Section 4.6. A value of 1 in the
  8. * matrix indicates an edge; a value of 0 indicates no edge. Note
  9. * also that the entries fx -> fy and gx -> gy are only present as
  10. * placeholders (to make the matrix easier to read in); these values
  11. * should always be zero.
  12. *
  13. * To use this program, first generate the directed graph file expr2.z and
  14. * run it through the C preprocessor to remove comments:
  15. *
  16. * cl -P expr2.z
  17. *
  18. * This will produce the file expr2.i, which can then be run through
  19. * opprec.exe:
  20. *
  21. * graph {option} expr2.i > expr2.out
  22. *
  23. * The output file expr2.out then contains the precedence function
  24. * values in either assembler or C format.
  25. */
  26. /* Call
  27. *
  28. * opprec vca file
  29. *
  30. * where
  31. * v include operator values in output as comments
  32. * c generate C compilable output
  33. * a generate MASM assemblable output
  34. * file input file stripped of comments
  35. */
  36. #include <stdio.h>
  37. #include <stdlib.h>
  38. #include <malloc.h>
  39. #include <stdlib.h>
  40. #include <string.h>
  41. #include <ctype.h>
  42. #include "opprec.h"
  43. struct token {
  44. struct token *next;
  45. char precstr[17];
  46. char type[17];
  47. char tclass[17];
  48. char bind[17];
  49. char eval[17];
  50. };
  51. struct token *tokhead = NULL;
  52. struct token *toktail = NULL;
  53. int asmout = FALSE; //output assembler form if true
  54. int verbose = FALSE; //output operator group data if true
  55. void cdecl main(int argc, char **argv)
  56. {
  57. int i;
  58. int j;
  59. int d;
  60. int *pMat;
  61. int *pPrec;
  62. char **pStr;
  63. int cEnt;
  64. FILE *fh;
  65. char *p, *q;
  66. int len, f, g;
  67. struct token *pt;
  68. int ntoken = 0;
  69. char str[200];
  70. // check arguments
  71. if (argc != 3) {
  72. printf ("Usage: graph -vca file\n");
  73. exit (1);
  74. }
  75. for (i = 0; argv[1][i] != 0; i++) {
  76. switch (argv[1][i]) {
  77. case 'a':
  78. asmout = TRUE;
  79. break;
  80. case 'c':
  81. asmout = FALSE;
  82. break;
  83. case 'v':
  84. verbose = TRUE;
  85. break;
  86. default:
  87. printf ("Unknown argument %c\n", argv[1][i]);
  88. exit (1);
  89. }
  90. }
  91. if ((fh = fopen (argv[2], "r")) == NULL) {
  92. printf ("Unable to open '%s'\n", argv[1]);
  93. exit (1);
  94. }
  95. // read and print token class definitions
  96. for (;;) {
  97. if ((p = SkipBlank (fh, str, 200)) == NULL) {
  98. printf ("EOF reached\n");
  99. exit (1);
  100. }
  101. while (isspace (*p)) {
  102. p++;
  103. }
  104. q = strpbrk (p, " \t");
  105. if ( q )
  106. *q = 0;
  107. if (strcmp (p, "END") == 0) {
  108. break;
  109. }
  110. if (asmout) {
  111. printf ("OPCDAT %s\n", p);
  112. }
  113. else {
  114. printf ("OPCDAT (%s)\n", p);
  115. }
  116. }
  117. printf ("\n");
  118. // read token definitions
  119. for (;;) {
  120. if ((p = SkipBlank (fh, str, 200)) == NULL) {
  121. printf ("EOF reached\n");
  122. exit (1);
  123. }
  124. while (isspace (*p)) {
  125. p++;
  126. }
  127. if (strcmp (p, "END") == 0) {
  128. break;
  129. }
  130. if ((q = strpbrk (p, " \t")) == NULL) {
  131. printf ("Bad format (%s)\n", str);
  132. exit (1);
  133. }
  134. *q = 0;
  135. ntoken++;
  136. if ((pt = (struct token *)malloc (sizeof (struct token))) == NULL) {
  137. printf ("insufficient memory\n");
  138. exit (2);
  139. }
  140. pt->next = NULL;
  141. strcpy (pt->precstr, p);
  142. p = q + 1;
  143. while (isspace (*p)) {
  144. p++;
  145. }
  146. if ((q = strpbrk (p, " \t")) == NULL) {
  147. printf ("Bad format (%s)\n", str);
  148. exit (1);
  149. }
  150. *q = 0;
  151. strcpy (pt->type, p);
  152. p = q + 1;
  153. while (isspace (*p)) {
  154. p++;
  155. }
  156. if ((q = strpbrk (p, " \t")) != NULL) {
  157. *q = 0;
  158. }
  159. strcpy (pt->tclass, p);
  160. p = q + 1;
  161. while (isspace (*p)) {
  162. p++;
  163. }
  164. if ((q = strpbrk (p, " \t")) != NULL) {
  165. *q = 0;
  166. }
  167. strcpy (pt->bind, p);
  168. p = q + 1;
  169. while (isspace (*p)) {
  170. p++;
  171. }
  172. if ((q = strpbrk (p, " \t")) != NULL) {
  173. *q = 0;
  174. }
  175. strcpy (pt->eval, p);
  176. if (tokhead == NULL) {
  177. tokhead = pt;
  178. toktail = pt;
  179. }
  180. else {
  181. toktail->next = pt;
  182. toktail = pt;
  183. }
  184. }
  185. if (asmout) {
  186. printf ("OPCNT COPS_EXPR,\t%d\n\n", ntoken);
  187. }
  188. else {
  189. printf ("OPCNT (COPS_EXPR,\t%d\t)\n\n", ntoken);
  190. }
  191. // read dimension of matrix. note that the upper left and lower right
  192. // quadrants of the matrix must be zero.
  193. if (SkipBlank (fh, str, 200) == NULL) {
  194. printf ("EOF reached\n");
  195. exit (1);
  196. }
  197. cEnt = atoi (str);
  198. // allocate space for the matrix and the description strings
  199. pMat = (int *)malloc (cEnt * cEnt * sizeof(int));
  200. pStr = malloc (cEnt * sizeof (char *));
  201. pPrec = (int *)malloc (cEnt * sizeof (int));
  202. if ((pMat == NULL) || (pStr == NULL) || (pPrec == NULL)) {
  203. printf ("insufficient memory\n");
  204. exit (2);
  205. }
  206. ReadMat (fh, pMat, pStr, cEnt);
  207. AddClosure (pMat, cEnt);
  208. // check for acyclic graph
  209. for (i = 0; i < cEnt; ++i) {
  210. if (pMat[i * cEnt + i] != 0) {
  211. printf ("Graph is cyclic for %s!!!\n", pStr[i]);
  212. exit(3);
  213. }
  214. }
  215. // print precedence function values
  216. for (i = 0; i < cEnt; ++i) {
  217. d = 0;
  218. for (j = 0; j < cEnt; ++j) {
  219. if (pMat[i * cEnt + j] > d) {
  220. d = pMat[i * cEnt + j];
  221. }
  222. }
  223. pPrec[i] = d;
  224. if (verbose) {
  225. if (asmout) {
  226. printf (";%-4s : %3d\n", pStr[i], d);
  227. }
  228. else {
  229. printf ("/*%-4s : %3d*/\n", pStr[i], d);
  230. }
  231. }
  232. }
  233. // print token definitions
  234. for (pt = tokhead; pt != NULL; pt = pt->next) {
  235. len = strlen (pt->precstr);
  236. // search for F string in list of precedence groupings
  237. for (i = 0; i < cEnt; i++) {
  238. if ((p = strstr(pStr[i], pt->precstr)) &&
  239. ((*(p + len) == 0) || (*(p + len) == 'G'))) {
  240. break;
  241. }
  242. }
  243. if (i == cEnt) {
  244. printf ("F precedence string \"%s\" not found\n", pt->precstr);
  245. exit (4);
  246. }
  247. else {
  248. f = pPrec[i];
  249. }
  250. // search for G string in list of precedence groupings
  251. *pt->precstr = 'G';
  252. for (i = 0; i < cEnt; i++) {
  253. // search for string in list of precedence groupings
  254. if ((p = strstr(pStr[i], pt->precstr)) && (*(p + len) == 0)) {
  255. break;
  256. }
  257. }
  258. if (i == cEnt) {
  259. printf ("G precedence string \"%s\" not found\n", pt->precstr);
  260. exit (4);
  261. }
  262. else {
  263. g = pPrec[i];
  264. }
  265. if (asmout) {
  266. printf ("OPDAT %-16s,%4d,%4d,\t%-16s\n", pt->type, f, g,pt->tclass);
  267. }
  268. else {
  269. printf ("OPDAT (%-16s,%4d,%4d,\t%-16s,%-16s,%-16s\t)\n",
  270. pt->type, f, g,pt->tclass, pt->bind, pt->eval);
  271. }
  272. }
  273. fclose (fh);
  274. }
  275. char *SkipBlank (FILE *fh, char *pStr, int cnt)
  276. {
  277. int len;
  278. for (;;) {
  279. if (fgets (pStr, cnt, fh) == NULL) {
  280. return (NULL);
  281. }
  282. len = strlen (pStr);
  283. if ((len == 1) || (*pStr == '#')) {
  284. continue;
  285. }
  286. *(pStr + len - 1) = 0;
  287. return (pStr);
  288. }
  289. }