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


1.3
date	2022.02.13.07.50.35;	author gtoal;	state Exp;
branches;
next	1.2;

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

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


desc
@update_astcode.c
@


1.3
log
@fixed bugs with comment handling
@
text
@#include <stdio.h>
#include <stdlib.h>

#define DEBUG_PARSER 1
#define WANT_COMMENT 1
#define WANT_SEMANTIC_TABLE 1
#include INCLUDE

#ifndef SEMANTIC_NAME
#endif

#define NO_WHITESPACE_PHRASES 1

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

// 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)
int main(int argc, char **argv)
{
  int p, i, gp, alts, altno;

  //\\ # LEVEL 0 - Atoms

  // too lazy to work out how to extract these from grammar for now.
  for (i = 0; i < MAX_BIP; i++) {
    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++;
      }
    }
    fprintf(stdout, "//\\\\ B<%s> = %d;\n", phrasename[i], i);
  }

  p = PHRASE_BASE;
  gp = 0;

#ifdef SEMANTIC_NAME
  fprintf(stdout, "\n//\\\\ C<%s>", SEMANTIC_NAME);
  if (*SEMANTIC_HEADER != '\0') {
    char *p = SEMANTIC_HEADER;
    fprintf(stdout, " = {");
    while (*p != '\0') {
      fprintf(stdout, "%c", *p);
      if (*p == '\n') fprintf(stdout, "//\\\\ ");
      p++;
    }
    fprintf(stdout, "}", SEMANTIC_HEADER);
  }
  fprintf(stdout, ";\n");
#endif
  
  for (;;) { // All phrases in grammar, sequentially
    int savegp = gp, savep = p;
    alts = gram[gp];
    fprintf(stdout, "\n");
    if (comment[p-512]) { // -MAX_BIP
      int lastch = '\n';
      char *s = comment[p-512]; // -MAX_BIP
      while (*s != '\0') {
        if (lastch == '\n') fprintf(stdout, "//\\\\ #%c", *s); else fprintf(stdout, "%c", *s);
        lastch = *s++;
      }
    }
    fprintf(stdout, "\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++];
      // without this unused parameter here, the output file is seriously corrupted!:
      fprintf(stdout, "\n//\\\\   ", gp);
      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) {
          if ((phrase == '\'') || (phrase == '\\')) {
            fprintf(stdout, " '\\%c'", phrase);
          } else {
            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]);
#ifdef 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]);
          }
#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]);
          }
#endif
#ifdef SEMANTIC_NAME
        } else {
          // SEMANTIC
          fprintf(stdout, " <%s:", SEMANTIC_NAME);
          escape(stdout, semantic_code[phrase-SEMANTIC]);
          fprintf(stdout, ">");
#endif
        }
        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; altno = 1;
      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;
#ifdef NO_WHITESPACE_PHRASES
        if (phrase != WHITESPACE) fprintf(stdout, "\n  ");
#else
        fprintf(stdout, "\n  ");
#endif
        if (alts > 1) fprintf(stdout, "  ");
        if (phrase < 256) {
          if ((phrase == '\'') || (phrase == '\\')) {
            fprintf(stdout, "T[%d] = lit(AST__LIT, '\\%c', A[ap+%d]);", altno, phrase, altno-1);
          } else {
            fprintf(stdout, "T[%d] = lit(AST__LIT, '%c', A[ap+%d]);", altno, phrase, altno-1);
          }
          altno += 1;
        } else if (phrase < 512) {
          fprintf(stdout, "T[%d] = kw(AST__KW, KW_%s, A[ap+%d]);", altno, uline(keyword[phrase-256]), altno-1);
          altno += 1;
        } else if (phrase < 512+MAX_BIP) {
          //fprintf(stdout, "T[%d] = %s(ap+%d);", altno, uline(phrasename[phrase-512]), next++);
          fprintf(stdout, "T[%d] = bip(AST_%s, A[ap+%d]);", altno, uline(phrasename[phrase-512]), altno-1); next++;
          altno += 1;
#ifdef SEMANTIC_NAME
        } else if (phrase < SEMANTIC) {
#else
        } else {
#endif
#ifdef NO_WHITESPACE_PHRASES
          if (phrase != WHITESPACE) {
            if (negated_phrase || optional_phrase) {
              if (optional_phrase) {
                fprintf(stdout, "cur_listing = listing; listing = 0; // suppress source listing for optional items\n");
                fprintf(stdout, "  T[%d] = -build_ast(A[ap+%d], depth+1); // <?%s>  guard phrases return a parse tree but we sort of hide it\n",
                        altno, altno-1, phrasename[phrase-512]); next += 1;
                fprintf(stdout, "  listing = cur_listing;\n");
              } else {
                fprintf(stdout, "T[%d] = -1; // <%c%s>",
	                altno, (negated_phrase ? '!' : '?'), phrasename[phrase-512]); next += 1;
              }
	    } else {
              fprintf(stdout, "T[%d] = build_ast(A[ap+%d], depth+1); // <%s>",
                      altno, altno-1, phrasename[phrase-512]); next += 1;
	    }
            altno += 1;
          }
#else
          if (negated_phrase || optional_phrase) {
            if (phrase == WHITESPACE) {
              fprintf(stdout, "T[%d] = -1; // <%csp>",
		      altno, (negated_phrase ? '!' : '?')); next += 1;
            } else {
              if (optional_phrase) {
                fprintf(stdout, "cur_listing = listing; listing = 0; // suppress source listing for optional items\n");
                fprintf(stdout, "  T[%d] = -build_ast(A[ap+%d], depth+1); // <?%s>  guard phrases return a parse tree but we sort of hide it\n",
                        altno, altno-1, phrasename[phrase-512]); next += 1;
                fprintf(stdout, "  listing = cur_listing;\n");
              } else {
                fprintf(stdout, "T[%d] = -1; // <%c%s>",
  		        altno, (negated_phrase ? '!' : '?'), phrasename[phrase-512]); next += 1;
              }
            }
	  } else {
            fprintf(stdout, "T[%d] = build_ast(A[ap+%d], depth+1); // <%s>",
                            altno, next++, phrasename[phrase-512]);
	  }
          altno += 1;
#endif
#ifdef SEMANTIC_NAME
        } else {
          // SEMANTIC
          fprintf(stdout, "T[%d] = -1; // successful semantic call", altno);
          altno += 1;
#endif
        }
        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(AST_%s, alt /*%d*/, /*phrases*/ %d", uline(phrasename[p-512]), i/*+1*/, altno-1);
        /*if (each)*/ fprintf(stdout, ", T /*");
        for (each = 0; each < altno-1; each++) {
          fprintf(stdout, "T[%d]", each+1); if (each+1<altno-1) 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;
  }
  fprintf(stdout, "//\\\\ E\n");

  exit(0);
}
@


1.2
log
@fixed \\ and \'
@
text
@d14 11
d55 8
d88 1
a88 1
    if (comment[p-512-MAX_BIP]) {
d90 1
a90 1
      char *s = comment[p-512-MAX_BIP];
d145 3
a147 1
          fprintf(stdout, " <%s:%s>", SEMANTIC_NAME, semantic_code[phrase-SEMANTIC]);
d195 1
a195 1
          fprintf(stdout, "T[%d] = kw(AST__KW, %d /* %s */, A[ap+%d]);", altno, phrase-256, uline(keyword[phrase-256]), altno-1);
d211 1
a211 1
                fprintf(stdout, "T[%d] = -build_ast(A[ap+%d], depth+1); // <?%s>  guard phrases return a parse tree but we sort of hide it\n",
d213 1
a213 1
                fprintf(stdout, "listing = cur_listing;\n");
d232 1
a232 1
                fprintf(stdout, "T[%d] = -build_ast(A[ap+%d], depth+1); // <?%s>  guard phrases return a parse tree but we sort of hide it\n",
d234 1
a234 1
                fprintf(stdout, "listing = cur_listing;\n");
@


1.1
log
@Initial revision
@
text
@d89 5
a93 1
          fprintf(stdout, " '%c'", phrase);
d167 5
a171 1
          fprintf(stdout, "T[%d] = lit(AST__LIT, '%c', A[ap+%d]);", altno, phrase, altno-1);
d178 1
a178 1
          fprintf(stdout, "T[%d] = bip(AST_%s, ap+%d);", altno, uline(phrasename[phrase-512]), altno-1); next++;
@
