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