// TO DO: Output //\\ B<...> = n; #include <stdio.h> #include <stdlib.h> #define DEBUG_PARSER 1 #include "grammar.h" // Reconstitute grammar from tables. // Parsing code will be very similar, except recursing from PHRASE_BASE // rather than scanning sequentially from there. char *uline(char *s) { static char T[128]; char *tp = T; int c; for (;;) { c = *s++; if (c == '-') c = '_'; *tp++ = c; if (c == '\0') return T; } } #define DROP_SPECIAL_BITS ((1<<14)-1) #define NEGATED_PHRASE (1<<15) #define OPTIONAL_PHRASE (1<<14) int main(int argc, char **argv) { int p, i, gp, alts; p = PHRASE_BASE; gp = 0; for (;;) { // All phrases in grammar, sequentially int savegp = gp, savep = p; alts = gram[gp]; fprintf(stdout, "\n \n//\\\\ P<%s> = ", phrasename[p-512]); gp++; // gp now points to first element (length) of first alt fflush(stdout); for (i = 0; i < alts; i++) { int each, phrases = gram[gp++]; fprintf(stdout, "\n//\\\\ "); for (each = 0; each < phrases; each++) { int phrase = gram[gp] & DROP_SPECIAL_BITS; int optional_phrase = gram[gp] & OPTIONAL_PHRASE; int negated_phrase = gram[gp] & NEGATED_PHRASE; if (phrase < 256) { fprintf(stdout, " '%c'", phrase); } else if (phrase < 512) { fprintf(stdout, " \"%s\"", keyword[phrase-256]); } else if (phrase < 512+MAX_BIP) { fprintf(stdout, " <"); if (optional_phrase) fprintf(stdout, "?"); if (negated_phrase) fprintf(stdout, "!"); fprintf(stdout, "%s>", phrasename[phrase-512]); } else { fprintf(stdout, " <"); if (optional_phrase) fprintf(stdout, "?"); if (negated_phrase) fprintf(stdout, "!"); fprintf(stdout, "%s>", phrasename[phrase-512]); } gp++; // move over element fflush(stdout); } if (i+1 < alts) fprintf(stdout, ","); else fprintf(stdout, ";"); // gp now points to first element (length) of next alt, or start of next phrase } fprintf(stdout, "\n\n"); gp = savegp; p = savep; alts = gram[gp]; fprintf(stdout, "case P_%s:", uline(phrasename[p-512])/*, phrasename[p-512], p, alts*/); // fprintf(stdout, "(pi=%d gp=%d) ", phrase_starT[p-512-MAX_BIP], gp); gp++; // gp now points to first element (length) of first alt fflush(stdout); for (i = 0; i < alts; i++) { int each, phrases = gram[gp++], next; if (alts > 1) { if (i == 0) { fprintf(stdout, "\n if (alt == %d) {", i); } else if (i + 1 < alts) { fprintf(stdout, "\n } else if (alt == %d) {", i); } else { fprintf(stdout, "\n } else {"); } } next = 0; for (each = 0; each < phrases; each++) { int phrase = gram[gp] & DROP_SPECIAL_BITS; int optional_phrase = gram[gp] & OPTIONAL_PHRASE; int negated_phrase = gram[gp] & NEGATED_PHRASE; fprintf(stdout, "\n "); if (alts > 1) fprintf(stdout, " "); if (phrase < 256) { fprintf(stdout, "T[%d] = lit('%c');", each+1, phrase); } else if (phrase < 512) { fprintf(stdout, "T[%d] = kw(/*\"%s\"*/ %d);", each+1, keyword[phrase-256], phrase-256); } else if (phrase < 512+MAX_BIP) { fprintf(stdout, "T[%d] = %s(ap+%d);", each+1, uline(phrasename[phrase-512]), next++); } else { if (negated_phrase || optional_phrase) { fprintf(stdout, "T[%d] = -1; // <%c%s>", each+1, (negated_phrase ? '!' : '?'), phrasename[phrase-512]); next += 1; } else { fprintf(stdout, "T[%d] = build_ast(A[ap+%d], depth+1); // <%s>", each+1, next++, phrasename[phrase-512]); } } gp++; // move over element fflush(stdout); } if (alts == 0) { fprintf(stdout, "\n return -1;\n }\n\n"); } else { if (alts > 1) { fprintf(stdout, "\n T[0] = "); } else { // alts == 1 fprintf(stdout, "\n return "); } fprintf(stdout, "mktuple(phrase /*P_%s*/, alt /*%d*/, /*phrases*/ %d", uline(phrasename[p-512]), i+1, phrases); /*if (each)*/ fprintf(stdout, ", T /*"); for (each = 0; each < phrases; each++) { fprintf(stdout, "T[%d]", each+1); if (each+1<phrases) fprintf(stdout, ", "); } fprintf(stdout, "*/);"); // gp now points to first element (length) of next alt, or start of next phrase if (alts > 1) { if (i + 1 == alts) fprintf(stdout, "\n }\n return T[0];\n\n"); } else fprintf(stdout, "\n"); } } p++; fprintf(stdout, "\n"); if (p == (512+MAX_PHRASE)) break; } exit(0); }