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.

250 lines
6.8 KiB

36 years ago
36 years ago
36 years ago
36 years ago
36 years ago
36 years ago
36 years ago
36 years ago
36 years ago
36 years ago
36 years ago
36 years ago
36 years ago
36 years ago
36 years ago
36 years ago
36 years ago
36 years ago
  1. /* Grammar implementation */
  2. #include "Python.h"
  3. #include "pgenheaders.h"
  4. #include <ctype.h>
  5. #include "token.h"
  6. #include "grammar.h"
  7. extern int Py_DebugFlag;
  8. grammar *
  9. newgrammar(int start)
  10. {
  11. grammar *g;
  12. g = (grammar *)PyObject_MALLOC(sizeof(grammar));
  13. if (g == NULL)
  14. Py_FatalError("no mem for new grammar");
  15. g->g_ndfas = 0;
  16. g->g_dfa = NULL;
  17. g->g_start = start;
  18. g->g_ll.ll_nlabels = 0;
  19. g->g_ll.ll_label = NULL;
  20. g->g_accel = 0;
  21. return g;
  22. }
  23. dfa *
  24. adddfa(grammar *g, int type, const char *name)
  25. {
  26. dfa *d;
  27. g->g_dfa = (dfa *)PyObject_REALLOC(g->g_dfa,
  28. sizeof(dfa) * (g->g_ndfas + 1));
  29. if (g->g_dfa == NULL)
  30. Py_FatalError("no mem to resize dfa in adddfa");
  31. d = &g->g_dfa[g->g_ndfas++];
  32. d->d_type = type;
  33. d->d_name = strdup(name);
  34. d->d_nstates = 0;
  35. d->d_state = NULL;
  36. d->d_initial = -1;
  37. d->d_first = NULL;
  38. return d; /* Only use while fresh! */
  39. }
  40. int
  41. addstate(dfa *d)
  42. {
  43. state *s;
  44. d->d_state = (state *)PyObject_REALLOC(d->d_state,
  45. sizeof(state) * (d->d_nstates + 1));
  46. if (d->d_state == NULL)
  47. Py_FatalError("no mem to resize state in addstate");
  48. s = &d->d_state[d->d_nstates++];
  49. s->s_narcs = 0;
  50. s->s_arc = NULL;
  51. s->s_lower = 0;
  52. s->s_upper = 0;
  53. s->s_accel = NULL;
  54. s->s_accept = 0;
  55. return Py_SAFE_DOWNCAST(s - d->d_state, Py_intptr_t, int);
  56. }
  57. void
  58. addarc(dfa *d, int from, int to, int lbl)
  59. {
  60. state *s;
  61. arc *a;
  62. assert(0 <= from && from < d->d_nstates);
  63. assert(0 <= to && to < d->d_nstates);
  64. s = &d->d_state[from];
  65. s->s_arc = (arc *)PyObject_REALLOC(s->s_arc, sizeof(arc) * (s->s_narcs + 1));
  66. if (s->s_arc == NULL)
  67. Py_FatalError("no mem to resize arc list in addarc");
  68. a = &s->s_arc[s->s_narcs++];
  69. a->a_lbl = lbl;
  70. a->a_arrow = to;
  71. }
  72. int
  73. addlabel(labellist *ll, int type, const char *str)
  74. {
  75. int i;
  76. label *lb;
  77. for (i = 0; i < ll->ll_nlabels; i++) {
  78. if (ll->ll_label[i].lb_type == type &&
  79. strcmp(ll->ll_label[i].lb_str, str) == 0)
  80. return i;
  81. }
  82. ll->ll_label = (label *)PyObject_REALLOC(ll->ll_label,
  83. sizeof(label) * (ll->ll_nlabels + 1));
  84. if (ll->ll_label == NULL)
  85. Py_FatalError("no mem to resize labellist in addlabel");
  86. lb = &ll->ll_label[ll->ll_nlabels++];
  87. lb->lb_type = type;
  88. lb->lb_str = strdup(str);
  89. if (Py_DebugFlag)
  90. printf("Label @ %8p, %d: %s\n", ll, ll->ll_nlabels,
  91. PyGrammar_LabelRepr(lb));
  92. return Py_SAFE_DOWNCAST(lb - ll->ll_label, Py_intptr_t, int);
  93. }
  94. /* Same, but rather dies than adds */
  95. int
  96. findlabel(labellist *ll, int type, const char *str)
  97. {
  98. int i;
  99. for (i = 0; i < ll->ll_nlabels; i++) {
  100. if (ll->ll_label[i].lb_type == type /*&&
  101. strcmp(ll->ll_label[i].lb_str, str) == 0*/)
  102. return i;
  103. }
  104. fprintf(stderr, "Label %d/'%s' not found\n", type, str);
  105. Py_FatalError("grammar.c:findlabel()");
  106. return 0; /* Make gcc -Wall happy */
  107. }
  108. /* Forward */
  109. static void translabel(grammar *, label *);
  110. void
  111. translatelabels(grammar *g)
  112. {
  113. int i;
  114. #ifdef Py_DEBUG
  115. printf("Translating labels ...\n");
  116. #endif
  117. /* Don't translate EMPTY */
  118. for (i = EMPTY+1; i < g->g_ll.ll_nlabels; i++)
  119. translabel(g, &g->g_ll.ll_label[i]);
  120. }
  121. static void
  122. translabel(grammar *g, label *lb)
  123. {
  124. int i;
  125. if (Py_DebugFlag)
  126. printf("Translating label %s ...\n", PyGrammar_LabelRepr(lb));
  127. if (lb->lb_type == NAME) {
  128. for (i = 0; i < g->g_ndfas; i++) {
  129. if (strcmp(lb->lb_str, g->g_dfa[i].d_name) == 0) {
  130. if (Py_DebugFlag)
  131. printf(
  132. "Label %s is non-terminal %d.\n",
  133. lb->lb_str,
  134. g->g_dfa[i].d_type);
  135. lb->lb_type = g->g_dfa[i].d_type;
  136. free(lb->lb_str);
  137. lb->lb_str = NULL;
  138. return;
  139. }
  140. }
  141. for (i = 0; i < (int)N_TOKENS; i++) {
  142. if (strcmp(lb->lb_str, _PyParser_TokenNames[i]) == 0) {
  143. if (Py_DebugFlag)
  144. printf("Label %s is terminal %d.\n",
  145. lb->lb_str, i);
  146. lb->lb_type = i;
  147. free(lb->lb_str);
  148. lb->lb_str = NULL;
  149. return;
  150. }
  151. }
  152. printf("Can't translate NAME label '%s'\n", lb->lb_str);
  153. return;
  154. }
  155. if (lb->lb_type == STRING) {
  156. if (isalpha(Py_CHARMASK(lb->lb_str[1])) ||
  157. lb->lb_str[1] == '_') {
  158. char *p;
  159. char *src;
  160. char *dest;
  161. size_t name_len;
  162. if (Py_DebugFlag)
  163. printf("Label %s is a keyword\n", lb->lb_str);
  164. lb->lb_type = NAME;
  165. src = lb->lb_str + 1;
  166. p = strchr(src, '\'');
  167. if (p)
  168. name_len = p - src;
  169. else
  170. name_len = strlen(src);
  171. dest = (char *)malloc(name_len + 1);
  172. if (!dest) {
  173. printf("Can't alloc dest '%s'\n", src);
  174. return;
  175. }
  176. strncpy(dest, src, name_len);
  177. dest[name_len] = '\0';
  178. free(lb->lb_str);
  179. lb->lb_str = dest;
  180. }
  181. else if (lb->lb_str[2] == lb->lb_str[0]) {
  182. int type = (int) PyToken_OneChar(lb->lb_str[1]);
  183. if (type != OP) {
  184. lb->lb_type = type;
  185. free(lb->lb_str);
  186. lb->lb_str = NULL;
  187. }
  188. else
  189. printf("Unknown OP label %s\n",
  190. lb->lb_str);
  191. }
  192. else if (lb->lb_str[2] && lb->lb_str[3] == lb->lb_str[0]) {
  193. int type = (int) PyToken_TwoChars(lb->lb_str[1],
  194. lb->lb_str[2]);
  195. if (type != OP) {
  196. lb->lb_type = type;
  197. free(lb->lb_str);
  198. lb->lb_str = NULL;
  199. }
  200. else
  201. printf("Unknown OP label %s\n",
  202. lb->lb_str);
  203. }
  204. else if (lb->lb_str[2] && lb->lb_str[3] && lb->lb_str[4] == lb->lb_str[0]) {
  205. int type = (int) PyToken_ThreeChars(lb->lb_str[1],
  206. lb->lb_str[2],
  207. lb->lb_str[3]);
  208. if (type != OP) {
  209. lb->lb_type = type;
  210. free(lb->lb_str);
  211. lb->lb_str = NULL;
  212. }
  213. else
  214. printf("Unknown OP label %s\n",
  215. lb->lb_str);
  216. }
  217. else
  218. printf("Can't translate STRING label %s\n",
  219. lb->lb_str);
  220. }
  221. else
  222. printf("Can't translate label '%s'\n",
  223. PyGrammar_LabelRepr(lb));
  224. }