head	1.2;
access;
symbols;
locks
	gtoal:1.2; strict;
comment	@ * @;


1.2
date	2022.02.19.02.46.37;	author gtoal;	state Exp;
branches;
next	1.1;

1.1
date	2022.02.15.00.57.39;	author gtoal;	state Exp;
branches;
next	;


desc
@@


1.2
log
@*** empty log message ***
@
text
@#include <stdio.h>
#include <stdlib.h>

#define WANT_COMMENT 1
#define DEBUG_PARSER 1
#define WANT_SEMANTIC_TABLE 1
#include TABLE // "parser-*.h"


void escape(FILE *out, char *s) {
  while (*s != '\0') {
    int c = *s++;
    if ((c == '\\') || (c == '\"'))
      fputc('\\', out);
    fputc(c, out);
  }
}

#define NO_WHITESPACE_PHRASES 1

// 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<<29)-1)
#define NEGATED_PHRASE (1<<29)
#define OPTIONAL_PHRASE (1<<30)
#define MAX_PHRASES 1024
#define WHITESPACE (MAX_PHRASES-1)


#define UNWALKED 0
#define WALKING 1
#define WALKED 2
int phrase_state[MAX_PHRASE];

int pstack[1000], gpstack[1000];
int stackp = 0;

void walk(int p, int gp) {
  int i, alts, altno, this_phrase = p;

  if (phrase_state[this_phrase] != UNWALKED) return;
  phrase_state[this_phrase] = WALKING;
  
    int savegp = gp, savep = p;
    alts = gram[gp];
#ifdef WANT_COMMENT
    if (comment[p]) {
      int lastch = '\n';
      char *s = comment[p];
      while (*s != '\0') {
        if (lastch == '\n') fprintf(stdout, "//\\\\ #%c", *s); else fprintf(stdout, "%c", *s);
        lastch = *s++;
      }
    }
#endif
    fprintf(stdout, "\n//\\\\ P<%s> =\n//\\\\   ", phrasename[p]);
    gp++; // gp now points to first element (length) of first alt
    fflush(stdout);
    for (i = 0; i < alts; i++) {
      int each, phrases = gram[gp++];
      // without this unused parameter here, the output file is seriously corrupted!:
      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, " '%s%c'", phrase == '\'' ? "'" : "", 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]);
#if defined(WANT_SEMANTIC_TABLE) && defined(SEMANTIC_NAME)
        } else if ((phrase) < SEMANTIC) {
#else
        } else {
#endif
#ifdef NO_WHITESPACE_PHRASES
          if (phrase != WHITESPACE) {
            fprintf(stdout, " <");
            if (optional_phrase) fprintf(stdout, "?");
            if (negated_phrase) fprintf(stdout, "!");
            fprintf(stdout, "%s>", phrasename[phrase-512]);
            pstack[stackp] = phrase-512; gpstack[stackp] = phrase_start[phrase-512-MAX_BIP]; stackp++;
          }
#else
          fprintf(stdout, " <");
          if (optional_phrase) fprintf(stdout, "?");
          if (negated_phrase) fprintf(stdout, "!");
          if (phrase == WHITESPACE) {
            fprintf(stdout, "sp>");
          } else {
            fprintf(stdout, "%s>", phrasename[phrase-512]);
            pstack[stackp] = phrase-512; gpstack[stackp] = phrase_start[phrase-512-MAX_BIP]; stackp++;
          }
#endif
#if defined(WANT_SEMANTIC_TABLE) && defined(SEMANTIC_NAME)
        } else {
          // SEMANTIC PHRASE
          fprintf (stdout, " <%s%s:", optional_phrase?"?":negated_phrase?"!":"", SEMANTIC_NAME); 
          escape(stdout, semantic_code[phrase-SEMANTIC]);
          fprintf (stdout, ">");
#endif
        }
        
        gp++; // move over element
        fflush(stdout);
      }
      if (i+1 < alts) fprintf(stdout, ",\n//\\\\   "); else fprintf(stdout, ";\n");
      // gp now points to first element (length) of next alt, or start of next phrase
    }
  fprintf(stdout, "\n");
  phrase_state[this_phrase] = WALKED;
}

int main(int argc, char **argv)
{
  int i;
  for (i = 0; i < MAX_BIP; i++) {
#ifdef WANT_COMMENT
    if (comment[i]) {
      int lastch = '\n';
      char *s = comment[i];
      while (*s != '\0') {
        if (lastch == '\n') fprintf(stdout, "//\\\\ #%c", *s); else fprintf(stdout, "%c", *s);
        lastch = *s++;
      }
    }
#endif
    fprintf(stdout, "//\\\\ B<%s> = %d;\n", phrasename[i], BIP[i]); // or phrasename[BIP[i]] ???
  }
#if defined(WANT_SEMANTIC_TABLE) && defined(SEMANTIC_NAME)
  //#define SEMANTIC_NAME "immediate"
  //#define SEMANTIC 10000
  //#define MAX_SEMANTIC 1
  //#define SEMANTIC_HEADER ...
  /*
//\\ C<immediate> = {
//\\ extern int *A;
//\\
//\\ extern int cp;                     // code pointer.  Has to be global state.
//\\ extern int ap;                     // Analysis record pointer.
//\\ int typedef_table[123];// for now
//\\ int push(int val, int *table);
//\\
//\\ int check(int Aval, int *table);
//\\
//\\ };
   */
  fprintf(stdout, "//\\\\ C<%s> = {", SEMANTIC_NAME);
  {
    char *p = SEMANTIC_HEADER;
    for (;;) {
      if (*p == '\0') break;
      p++;
      fputc(*p, stdout);
      if (*p == '\n') fprintf(stdout, "//\\\\");
    }
  }
  fprintf(stdout, "};\n");
#endif
  
  for (i = 0; i < MAX_PHRASE; i++) phrase_state[i] = UNWALKED;
  walk(P_SS-512, phrase_start[P_SS-512-MAX_BIP]);
  while (stackp > 0) {
    stackp -= 1;
    walk(pstack[stackp], gpstack[stackp]);
  }
  for (i = 0; i < MAX_PHRASE; i++) {
    if ((i > MAX_BIP) && (phrase_state[i] == UNWALKED)) {
      fprintf(stdout, "// Unused phrase:\n");
      walk(i, phrase_start[i-MAX_BIP]);
    }
  }
  exit(0);
}
@


1.1
log
@Initial revision
@
text
@d167 11
a177 1
  fprintf(stdout, "//\\\\ C<%s> = {%s};\n", SEMANTIC_NAME, SEMANTIC_HEADER); // need to insert //\\ in SEMANTIC_HEADER lines...
@
