#include <stdio.h> #include <stdlib.h> #define DEBUG_PARSER 1 #include "c.h" #define DROP_SPECIAL_BITS ((1<<14)-1) #define NEGATED_PHRASE (1<<15) #define OPTIONAL_PHRASE (1<<14) // Reconstitute grammar from tables. // Parsing code is very similar, except recursing from PHRASE_BASE // rather than scanning sequentially from there. // const char *comment = "//\\\\ "; // for when we embed a grammar in a C file. const char *comment = ""; int main(int argc, char **argv) { int p, i, gp, alts; p = PHRASE_BASE; gp = 0; for (i = 0; i < MAX_BIP; i++) { fprintf(stdout, "B<%s> = %d;\n", phrasename[i], i); } for (;;) { // All phrases in grammar, sequentially alts = gram[gp]; fprintf(stdout, "\n%sP<%s> = ", comment, 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%s ", comment); 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 } p++; fprintf(stdout, "\n"); if (p == (512+MAX_PHRASE)) break; } fprintf(stdout, "\n%sE\n", comment); exit(0); }