Add support for labelled tree nodes.
authorDavid Given <dg@cowlark.com>
Sat, 24 Sep 2016 10:11:30 +0000 (12:11 +0200)
committerDavid Given <dg@cowlark.com>
Sat, 24 Sep 2016 10:11:30 +0000 (12:11 +0200)
util/mcgg/gram.y
util/mcgg/iburg.c
util/mcgg/iburg.h

index ea0abbc..84a8990 100644 (file)
@@ -16,6 +16,7 @@ static int nextern = 0;
        char* string;
        Tree tree;
     Stringlist stringlist;
+    char* stringpair[2];
 }
 %term TERMINAL
 %term START
@@ -27,15 +28,17 @@ static int nextern = 0;
 %term EMIT
 %term COST
 
+%token <n>          INT
 %token <string>     ID
 %token <string>     CFRAGMENT
-%token <n>          INT
 
-%type  <string>     lhs
-%type  <tree>       rhs
 %type  <n>          cost
-%type  <stringlist> when
+%type  <string>     label
+%type  <string>     lhs
 %type  <stringlist> stringlist
+%type  <stringlist> when
+%type  <tree>       rhs
+%type  <stringpair> labelledid
 %%
 spec
     : decls PPERCENT patterns
@@ -78,11 +81,16 @@ lhs
        ;
 
 rhs
-    : ID                            { $$ = tree($1, NULL, NULL); }
-       | ID '(' rhs ')'                { $$ = tree($1,   $3, NULL); }
-       | ID '(' rhs ',' rhs ')'        { $$ = tree($1,   $3, $5); }
+    : labelledid                      { $$ = tree($1[1], $1[0], NULL, NULL); }
+       | labelledid '(' rhs ')'          { $$ = tree($1[1], $1[0],   $3, NULL); }
+       | labelledid '(' rhs ',' rhs ')'  { $$ = tree($1[1], $1[0],   $3, $5); }
        ;
 
+labelledid
+    : ID                            { $$[0] = NULL; $$[1] = $1; }
+    | ID ':' ID                     { $$[0] = $1; $$[1] = $3; }
+    ;
+
 when
     : /* nothing */                 { $$ = NULL; }
     | WHEN stringlist               { $$ = $2; }
index 833d3e0..cae03e5 100644 (file)
@@ -151,7 +151,7 @@ struct entry
 {
        union
        {
-               char* name;
+               const char* name;
                struct term t;
                struct nonterm nt;
        } sym;
@@ -160,7 +160,7 @@ struct entry
 #define HASHSIZE (sizeof table / sizeof table[0])
 
 /* hash - return hash number for str */
-static unsigned hash(char* str)
+static unsigned hash(const char* str)
 {
        unsigned h = 0;
 
@@ -170,7 +170,7 @@ static unsigned hash(char* str)
 }
 
 /* lookup - lookup symbol name */
-static void* lookup(char* name)
+static void* lookup(const char* name)
 {
        struct entry* p = table[hash(name) % HASHSIZE];
 
@@ -181,7 +181,7 @@ static void* lookup(char* name)
 }
 
 /* install - install symbol name */
-static void* install(char* name)
+static void* install(const char* name)
 {
        struct entry* p = calloc(1, sizeof *p);
        int i = hash(name) % HASHSIZE;
@@ -193,7 +193,7 @@ static void* install(char* name)
 }
 
 /* nonterm - create a new terminal id, if necessary */
-Nonterm nonterm(char* id)
+Nonterm nonterm(const char* id)
 {
        Nonterm p = lookup(id), * q = &nts;
 
@@ -215,7 +215,7 @@ Nonterm nonterm(char* id)
 }
 
 /* term - create a new terminal id with external symbol number esn */
-Term term(char* id, int esn)
+Term term(const char* id, int esn)
 {
        Term p = lookup(id), * q = &terms;
 
@@ -240,7 +240,7 @@ Term term(char* id, int esn)
 }
 
 /* tree - create & initialize a tree node with the given fields */
-Tree tree(char* id, Tree left, Tree right)
+Tree tree(const char* id, const char* label, Tree left, Tree right)
 {
        Tree t = calloc(1, sizeof *t);
        Term p = lookup(id);
@@ -267,6 +267,7 @@ Tree tree(char* id, Tree left, Tree right)
        if (p->kind == TERM && arity != p->arity)
                yyerror("inconsistent arity for terminal `%s'\n", id);
        t->op = p;
+       t->label = label;
        t->nterms = p->kind == TERM;
        if (t->left = left)
                t->nterms += left->nterms;
index 6b5f9af..5c5334c 100644 (file)
@@ -41,17 +41,18 @@ struct nonterm
        Rule chain; /* chain rules w/non-terminal on rhs */
        Nonterm link; /* next terminal in number order */
 };
-extern Nonterm nonterm(char* id);
-extern Term term(char* id, int esn);
+extern Nonterm nonterm(const char* id);
+extern Term term(const char* id, int esn);
 
 typedef struct tree* Tree;
 struct tree
 { /* tree patterns: */
-       void* op; /* a terminal or non-terminal */
-       Tree left, right; /* operands */
-       int nterms; /* number of terminal nodes in this tree */
+       void* op;           /* a terminal or non-terminal */
+       const char* label;  /* user label for this node */
+       Tree left, right;   /* operands */
+       int nterms;         /* number of terminal nodes in this tree */
 };
-extern Tree tree(char* op, Tree left, Tree right);
+extern Tree tree(const char* op, const char* label, Tree left, Tree right);
 
 struct rule
 { /* rules: */