From 24e9e9de7f0467386b61b27319e28e40454e9616 Mon Sep 17 00:00:00 2001
From: Mikael Vejdemo-Johansson <michiexile@gmail.com>
Date: Wed, 8 Apr 2015 15:29:32 +0200
Subject: [PATCH] support naming of generating functions, and 0-weighting of
 symbols

---
 examples/explore_singular.c | 152 ------------------------------------
 examples/ties.c             |  52 ++++++++++--
 2 files changed, 45 insertions(+), 159 deletions(-)
 delete mode 100644 examples/explore_singular.c

diff --git a/examples/explore_singular.c b/examples/explore_singular.c
deleted file mode 100644
index 5127c7c4..00000000
--- a/examples/explore_singular.c
+++ /dev/null
@@ -1,152 +0,0 @@
-//
-// Created by Mikael Vejdemo Johansson on 4/7/15.
-//
-// Intention: read in a parser, generate the system of equations for its
-// generating functions
-//
-
-#include <inttypes.h>
-#include "../src/backends/contextfree.h"
-#include "../src/backends/lr.h"
-#include <stdio.h>
-
-static const char *nonterminal_name(const HCFGrammar *g, const HCFChoice *nt)
-{
-  static char buf[16] = {0}; // 14 characters in base 26 are enough for 64 bits
-
-  // find nt's number in g
-  size_t n = (uintptr_t)h_hashtable_get(g->nts, nt);
-
-  // NB the start symbol (number 0) is always "A".
-  int i;
-  for(i=14; i>=0 && (n>0 || i==14); i--) {
-    buf[i] = 'A' + n%26;
-    n = n/26;   // shift one digit
-  }
-
-  return buf+i+1;
-}
-
-
-
-void readsequence(FILE *file, uint32_t *count, uint32_t *length,
-		  const HCFGrammar *g, const HCFSequence *seq) {
-  // tally up numbers of choices, and lengths of emitted strings.
-  // Immediately emit any nonterminals encountered.
-  HCFChoice** x = seq->items;
-  
-  if (*x == NULL) {
-    return;
-  } else {
-    fprintf(file, "1");
-    HCharset cs;
-    unsigned int i, cscount=0;
-    for(; *x; x++) {
-      switch((*x)->type) {
-      case HCF_CHAR:
-	(*length)++;
-	break;
-      case HCF_END:
-	break;
-      case HCF_CHARSET:
-	cs = (*x)->charset;
-	for(i=0; i<256; i++) {
-	  if (charset_isset(cs, i)) {
-	    cscount++;
-	  }
-	}
-	*count *= cscount;
-	break;
-      default: // HCF_CHOICE, non-terminal symbol
-	fprintf(file, "*%s(t)", nonterminal_name(g, *x));
-	break;
-      }
-    }
-  }
-}
-
-// For each nt in g->nts
-//     For each choice in nt->key->seq
-//          For all elements in sequence
-//              Accumulate counts 
-//              Accumulate string lengths
-//              Emit count*t^length
-void h_pprint_gfeqns(FILE *file, const HCFGrammar *g) {
-  if (g->nts->used < 1) {
-    return;
-  }
-
-  // determine maximum string length of symbol names
-  int len;
-  size_t s;
-  for(len=1, s=26; s < g->nts->used; len++, s*=26); 
-
-  // iterate over g->nts
-  size_t i;
-  HHashTableEntry *hte;
-  for(i=0; i < g->nts->capacity; i++) {
-    for(hte = &g->nts->contents[i]; hte; hte = hte->next) {
-      if (hte->key == NULL) {
-        continue;
-      }
-
-      const HCFChoice *nt = hte->key;
-      fprintf(file, "%s(t) = ", nonterminal_name(g, nt));
-
-      
-      for(HCFSequence **seq = nt->seq; *seq; seq++) {
-	if (seq != nt->seq) {
-	  fprintf(file, " + ");
-	}
-	uint32_t count=1, length=0;
-	readsequence(file, &count, &length, g, *seq);
-	if(count == 1) {
-	  if(length == 1) {
-	    fprintf(file, "*t");
-	  }
-	  if(length > 1) {
-	    fprintf(file, "*t^%d", length);
-	  }
-	} else if(count > 1) {
-	  if(length == 0) {
-	    fprintf(file, "*%d", count);
-	  }
-	  if(length == 1) {
-	    fprintf(file, "*%d*t", count);
-	  }
-	  if (length > 1) {
-	    fprintf(file, "*%d*t^%d", count, length);
-	  } 
-	}
-      }
-
-      fprintf(file, "\n");
-    }
-  }
-}
-
-
-
-
-int main(int argc, char **argv)
-{
-  HAllocator *mm__ = &system_allocator;
-
-  HParser *n = h_ch('n');
-  HParser *E = h_indirect();
-  HParser *T = h_choice(h_sequence(h_ch('('), E, h_ch(')'), NULL), n, NULL);
-  HParser *E_ = h_choice(h_sequence(E, h_ch('-'), T, NULL), T, NULL);
-  h_bind_indirect(E, E_);
-  HParser *p = E;
-
-  HCFGrammar *g = h_cfgrammar_(mm__, h_desugar_augmented(mm__, p));
-  if (g == NULL) {
-    fprintf(stderr, "h_cfgrammar failed\n");
-    return 1;
-  }
-  printf("\n==== Generating functions ====\n");
-  h_pprint_gfeqns(stdout, g);
-
-  printf("\n==== Grammar ====\n");
-  h_pprint_grammar(stdout, g, 0);
-}
diff --git a/examples/ties.c b/examples/ties.c
index e4ca2117..a379b5c7 100644
--- a/examples/ties.c
+++ b/examples/ties.c
@@ -10,8 +10,30 @@
 #include "../src/backends/lr.h"
 #include <stdio.h>
 
-static const char *nonterminal_name(const HCFGrammar *g, const HCFChoice *nt)
-{
+
+HAllocator *mm__;
+
+// If a parser has user_data set, the generating function systems will try
+// to interpret it as a string:
+//
+// If this string for an h_ch starts with the character 0, then that character
+// will have weight 0 in the generating function.
+//
+// Use the remaining string to set the preferred name of that parser in the
+// generating function.
+
+
+
+static const char *nonterminal_name(const HCFGrammar *g, const HCFChoice *nt) {
+  if(nt->user_data != NULL) {
+    if(*(char*)(nt->user_data) != '0') {
+      // user_data is a non-empty string
+      return nt->user_data;
+    } else {
+      return nt->user_data+1;
+    }
+  }
+  
   static char buf[16] = {0}; // 14 characters in base 26 are enough for 64 bits
 
   // find nt's number in g
@@ -38,13 +60,16 @@ void readsequence(FILE *file, uint32_t *count, uint32_t *length,
   if (*x == NULL) {
     return;
   } else {
+    char has_user_data = (*x)->user_data != NULL && *(char*)(*x)->user_data != 0;
     fprintf(file, "1");
     HCharset cs;
     unsigned int i, cscount=0;
     for(; *x; x++) {
       switch((*x)->type) {
       case HCF_CHAR:
-	(*length)++;
+	if(!(has_user_data && *(char*)(*x)->user_data == '0')) {
+	  (*length)++;
+	}
 	break;
       case HCF_END:
 	break;
@@ -182,7 +207,21 @@ HParser* finkmaoTW() {
 			     h_epsilon_p(),
 			      NULL);
   h_bind_indirect(pairstar, pstar_);
-  return h_sequence(prefix, pairstar, tuck, NULL);
+
+  HParser* tie = h_sequence(prefix, pairstar, tuck, NULL);
+  h_desugar_augmented(mm__, tie);
+
+  
+  T->desugared->user_data = "T";
+  W->desugared->user_data = "W";
+  U->desugared->user_data = "0U";
+  prefix->desugared->user_data = "prefix";
+  pair->desugared->user_data = "pair";
+  tuck->desugared->user_data = "tuck";
+  pstar_->desugared->user_data = "pairstar";
+  tie->desugared->user_data = "tie";
+  
+  return tie;
 }
 
 HParser* depth1TW() {
@@ -341,9 +380,8 @@ HParser* depthNTW() {
 }
 
 
-int main(int argc, char **argv)
-{
-  HAllocator *mm__ = &system_allocator;
+int main(int argc, char **argv) {
+  mm__ = &system_allocator;
 
   HParser *p = finkmaoTW();
   HCFGrammar *g = h_cfgrammar_(mm__, h_desugar_augmented(mm__, p));
-- 
GitLab