char* string;
Tree tree;
Stringlist stringlist;
+ char* stringpair[2];
}
%term TERMINAL
%term START
%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
;
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; }
{
union
{
- char* name;
+ const char* name;
struct term t;
struct nonterm nt;
} sym;
#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;
}
/* lookup - lookup symbol name */
-static void* lookup(char* name)
+static void* lookup(const char* name)
{
struct entry* p = table[hash(name) % HASHSIZE];
}
/* 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;
}
/* nonterm - create a new terminal id, if necessary */
-Nonterm nonterm(char* id)
+Nonterm nonterm(const char* id)
{
Nonterm p = lookup(id), * q = &nts;
}
/* 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;
}
/* 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);
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;
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: */