// 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);
}