static int parser_compare_nodes(node *left, node *right) { int j; if (TYPE(left) < TYPE(right)) return (-1); if (TYPE(right) < TYPE(left)) return (1); if (ISTERMINAL(TYPE(left))) return (strcmp(STR(left), STR(right))); if (NCH(left) < NCH(right)) return (-1); if (NCH(right) < NCH(left)) return (1); for (j = 0; j < NCH(left); ++j) { int v = parser_compare_nodes(CHILD(left, j), CHILD(right, j)); if (v != 0) return (v); } return (0); }
static void list1node(FILE *fp, node *n) { if (n == NULL) return; if (ISNONTERMINAL(TYPE(n))) { int i; for (i = 0; i < NCH(n); i++) list1node(fp, CHILD(n, i)); } else if (ISTERMINAL(TYPE(n))) { switch (TYPE(n)) { case INDENT: ++level; break; case DEDENT: --level; break; default: if (atbol) { int i; for (i = 0; i < level; ++i) fprintf(fp, "\t"); atbol = 0; } if (TYPE(n) == NEWLINE) { if (STR(n) != NULL) fprintf(fp, "%s", STR(n)); fprintf(fp, "\n"); atbol = 1; } else fprintf(fp, "%s ", STR(n)); break; } } else fprintf(fp, "? "); }
static void calcfirstset(grammar *g, dfa *d) { int i, j; state *s; arc *a; int nsyms; int *sym; int nbits; static bitset dummy; bitset result; int type; dfa *d1; label *l0; if (Py_DebugFlag) printf("Calculate FIRST set for '%s'\n", d->d_name); if (dummy == NULL) dummy = newbitset(1); if (d->d_first == dummy) { fprintf(stderr, "Left-recursion for '%s'\n", d->d_name); return; } if (d->d_first != NULL) { fprintf(stderr, "Re-calculating FIRST set for '%s' ???\n", d->d_name); } d->d_first = dummy; l0 = g->g_ll.ll_label; nbits = g->g_ll.ll_nlabels; result = newbitset(nbits); sym = (int *)PyObject_MALLOC(sizeof(int)); if (sym == NULL) Py_FatalError("no mem for new sym in calcfirstset"); nsyms = 1; sym[0] = findlabel(&g->g_ll, d->d_type, (char *)NULL); s = &d->d_state[d->d_initial]; for (i = 0; i < s->s_narcs; i++) { a = &s->s_arc[i]; for (j = 0; j < nsyms; j++) { if (sym[j] == a->a_lbl) break; } if (j >= nsyms) { /* New label */ sym = (int *)PyObject_REALLOC(sym, sizeof(int) * (nsyms + 1)); if (sym == NULL) Py_FatalError( "no mem to resize sym in calcfirstset"); sym[nsyms++] = a->a_lbl; type = l0[a->a_lbl].lb_type; if (ISNONTERMINAL(type)) { d1 = PyGrammar_FindDFA(g, type); if (d1->d_first == dummy) { fprintf(stderr, "Left-recursion below '%s'\n", d->d_name); } else { if (d1->d_first == NULL) calcfirstset(g, d1); mergebitset(result, d1->d_first, nbits); } } else if (ISTERMINAL(type)) { addbit(result, a->a_lbl); } } } d->d_first = result; if (Py_DebugFlag) { printf("FIRST set for '%s': {", d->d_name); for (i = 0; i < nbits; i++) { if (testbit(result, i)) printf(" %s", PyGrammar_LabelRepr(&l0[i])); } printf(" }\n"); } PyObject_FREE(sym); }
static PyObject* node2tuple(node *n, /* node to convert */ SeqMaker mkseq, /* create sequence */ SeqInserter addelem, /* func. to add elem. in seq. */ int lineno, /* include line numbers? */ int col_offset) /* include column offsets? */ { PyObject *result = NULL, *w; if (n == NULL) { Py_RETURN_NONE; } if (ISNONTERMINAL(TYPE(n))) { int i; result = mkseq(1 + NCH(n) + (TYPE(n) == encoding_decl)); if (result == NULL) goto error; w = PyLong_FromLong(TYPE(n)); if (w == NULL) goto error; (void) addelem(result, 0, w); for (i = 0; i < NCH(n); i++) { w = node2tuple(CHILD(n, i), mkseq, addelem, lineno, col_offset); if (w == NULL) goto error; (void) addelem(result, i+1, w); } if (TYPE(n) == encoding_decl) { w = PyUnicode_FromString(STR(n)); if (w == NULL) goto error; (void) addelem(result, i+1, w); } } else if (ISTERMINAL(TYPE(n))) { result = mkseq(2 + lineno + col_offset); if (result == NULL) goto error; w = PyLong_FromLong(TYPE(n)); if (w == NULL) goto error; (void) addelem(result, 0, w); w = PyUnicode_FromString(STR(n)); if (w == NULL) goto error; (void) addelem(result, 1, w); if (lineno) { w = PyLong_FromLong(n->n_lineno); if (w == NULL) goto error; (void) addelem(result, 2, w); } if (col_offset) { w = PyLong_FromLong(n->n_col_offset); if (w == NULL) goto error; (void) addelem(result, 2 + lineno, w); } } else { PyErr_SetString(PyExc_SystemError, "unrecognized parse tree node type"); return ((PyObject*) NULL); } return result; error: Py_XDECREF(result); return NULL; }