Add support for labelled tree nodes.

This commit is contained in:
David Given 2016-09-24 12:11:30 +02:00
parent 6643d39b2c
commit 960259f0b0
3 changed files with 30 additions and 20 deletions

View file

@ -16,6 +16,7 @@ static int nextern = 0;
char* string; char* string;
Tree tree; Tree tree;
Stringlist stringlist; Stringlist stringlist;
char* stringpair[2];
} }
%term TERMINAL %term TERMINAL
%term START %term START
@ -27,15 +28,17 @@ static int nextern = 0;
%term EMIT %term EMIT
%term COST %term COST
%token <n> INT
%token <string> ID %token <string> ID
%token <string> CFRAGMENT %token <string> CFRAGMENT
%token <n> INT
%type <string> lhs
%type <tree> rhs
%type <n> cost %type <n> cost
%type <stringlist> when %type <string> label
%type <string> lhs
%type <stringlist> stringlist %type <stringlist> stringlist
%type <stringlist> when
%type <tree> rhs
%type <stringpair> labelledid
%% %%
spec spec
: decls PPERCENT patterns : decls PPERCENT patterns
@ -78,11 +81,16 @@ lhs
; ;
rhs rhs
: ID { $$ = tree($1, NULL, NULL); } : labelledid { $$ = tree($1[1], $1[0], NULL, NULL); }
| ID '(' rhs ')' { $$ = tree($1, $3, NULL); } | labelledid '(' rhs ')' { $$ = tree($1[1], $1[0], $3, NULL); }
| ID '(' rhs ',' rhs ')' { $$ = tree($1, $3, $5); } | labelledid '(' rhs ',' rhs ')' { $$ = tree($1[1], $1[0], $3, $5); }
; ;
labelledid
: ID { $$[0] = NULL; $$[1] = $1; }
| ID ':' ID { $$[0] = $1; $$[1] = $3; }
;
when when
: /* nothing */ { $$ = NULL; } : /* nothing */ { $$ = NULL; }
| WHEN stringlist { $$ = $2; } | WHEN stringlist { $$ = $2; }

View file

@ -151,7 +151,7 @@ struct entry
{ {
union union
{ {
char* name; const char* name;
struct term t; struct term t;
struct nonterm nt; struct nonterm nt;
} sym; } sym;
@ -160,7 +160,7 @@ struct entry
#define HASHSIZE (sizeof table / sizeof table[0]) #define HASHSIZE (sizeof table / sizeof table[0])
/* hash - return hash number for str */ /* hash - return hash number for str */
static unsigned hash(char* str) static unsigned hash(const char* str)
{ {
unsigned h = 0; unsigned h = 0;
@ -170,7 +170,7 @@ static unsigned hash(char* str)
} }
/* lookup - lookup symbol name */ /* lookup - lookup symbol name */
static void* lookup(char* name) static void* lookup(const char* name)
{ {
struct entry* p = table[hash(name) % HASHSIZE]; struct entry* p = table[hash(name) % HASHSIZE];
@ -181,7 +181,7 @@ static void* lookup(char* name)
} }
/* install - install symbol name */ /* install - install symbol name */
static void* install(char* name) static void* install(const char* name)
{ {
struct entry* p = calloc(1, sizeof *p); struct entry* p = calloc(1, sizeof *p);
int i = hash(name) % HASHSIZE; int i = hash(name) % HASHSIZE;
@ -193,7 +193,7 @@ static void* install(char* name)
} }
/* nonterm - create a new terminal id, if necessary */ /* nonterm - create a new terminal id, if necessary */
Nonterm nonterm(char* id) Nonterm nonterm(const char* id)
{ {
Nonterm p = lookup(id), * q = &nts; 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 - 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; 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 - 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); Tree t = calloc(1, sizeof *t);
Term p = lookup(id); Term p = lookup(id);
@ -267,6 +267,7 @@ Tree tree(char* id, Tree left, Tree right)
if (p->kind == TERM && arity != p->arity) if (p->kind == TERM && arity != p->arity)
yyerror("inconsistent arity for terminal `%s'\n", id); yyerror("inconsistent arity for terminal `%s'\n", id);
t->op = p; t->op = p;
t->label = label;
t->nterms = p->kind == TERM; t->nterms = p->kind == TERM;
if (t->left = left) if (t->left = left)
t->nterms += left->nterms; t->nterms += left->nterms;

View file

@ -41,17 +41,18 @@ struct nonterm
Rule chain; /* chain rules w/non-terminal on rhs */ Rule chain; /* chain rules w/non-terminal on rhs */
Nonterm link; /* next terminal in number order */ Nonterm link; /* next terminal in number order */
}; };
extern Nonterm nonterm(char* id); extern Nonterm nonterm(const char* id);
extern Term term(char* id, int esn); extern Term term(const char* id, int esn);
typedef struct tree* Tree; typedef struct tree* Tree;
struct tree struct tree
{ /* tree patterns: */ { /* tree patterns: */
void* op; /* a terminal or non-terminal */ void* op; /* a terminal or non-terminal */
Tree left, right; /* operands */ const char* label; /* user label for this node */
int nterms; /* number of terminal nodes in this tree */ 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 struct rule
{ /* rules: */ { /* rules: */