Add support for labelled tree nodes.
This commit is contained in:
parent
6643d39b2c
commit
960259f0b0
|
@ -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; }
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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: */
|
||||||
|
|
Loading…
Reference in a new issue