diff --git a/util/mcgg/gram.y b/util/mcgg/gram.y index ea0abbc75..84a899037 100644 --- a/util/mcgg/gram.y +++ b/util/mcgg/gram.y @@ -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 INT %token ID %token CFRAGMENT -%token INT -%type lhs -%type rhs %type cost -%type when +%type label +%type lhs %type stringlist +%type when +%type rhs +%type 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; } diff --git a/util/mcgg/iburg.c b/util/mcgg/iburg.c index 833d3e0d4..cae03e54d 100644 --- a/util/mcgg/iburg.c +++ b/util/mcgg/iburg.c @@ -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; diff --git a/util/mcgg/iburg.h b/util/mcgg/iburg.h index 6b5f9affc..5c5334c79 100644 --- a/util/mcgg/iburg.h +++ b/util/mcgg/iburg.h @@ -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: */