Massive grammar overhaul and refactor. Hacked in support for predicates, where

instructions can be turned on and off based on their parameters. New lexer
using a lexer. Now quite a lot of the way towards being a real instruction
selector.
This commit is contained in:
David Given 2016-09-21 00:43:10 +02:00
parent 2183c6c622
commit 4546dd5f22
7 changed files with 360 additions and 168 deletions

View file

@ -27,6 +27,7 @@ cprogram {
"modules/src/read_em+lib_kv", "modules/src/read_em+lib_kv",
"modules/src/system+lib", "modules/src/system+lib",
"./*.h", "./*.h",
"util/mcgg+mcgg",
}, },
vars = { vars = {
["+cflags"] = { ["+cflags"] = {

25
util/mcgg/build.lua Normal file
View file

@ -0,0 +1,25 @@
include("first/yacc.lua")
flex {
name = "flex",
srcs = { "./*.l" },
}
yacc {
name = "yacc",
srcs = { "./*.y" },
}
cprogram {
name = "mcgg",
srcs = {
"./*.c",
matching(filenamesof("+flex"), "%.c$"),
matching(filenamesof("+yacc"), "%.c$")
},
deps = {
"./*.h",
"+yacc"
}
}

View file

@ -3,65 +3,105 @@
#include <stdio.h> #include <stdio.h>
#include <limits.h> #include <limits.h>
#include "iburg.h" #include "iburg.h"
#define YYDEBUG 1
static char rcsid[] = "$Id$"; static char rcsid[] = "$Id$";
static int yylineno = 0; static int nextesn = 0;
static int nextern = 0;
%} %}
%union { %union {
int n; int n;
char *string; char* string;
Tree tree; Tree tree;
Stringlist stringlist;
} }
%term TERMINAL %term TERMINAL
%term START %term START
%term PPERCENT %term PPERCENT
%token <string> ID %term PATTERNS
%token <n> INT %term PAT
%type <string> lhs %term WHEN
%type <tree> tree %term EMIT
%type <n> cost %term COST
%token <string> ID
%token <string> CFRAGMENT
%token <n> INT
%type <string> lhs
%type <tree> rhs
%type <n> cost
%type <stringlist> when
%type <stringlist> stringlist
%% %%
spec : decls PPERCENT rules { yylineno = 0; } spec
| decls { yylineno = 0; } : decls PPERCENT patterns
| decls
; ;
decls : /* lambda */ decls : /* lambda */
| decls decl | decls decl
; ;
decl : TERMINAL blist '\n' decl
| START lhs '\n' { : TERMINAL blist ';'
if (nonterm($2)->number != 1) | START lhs ';'
yyerror("redeclaration of the start symbol\n"); {
} if (nonterm($2)->number != 1)
| '\n' yyerror("redeclaration of the start symbol\n");
| error '\n' { yyerrok; } }
| ';'
| error ';' { yyerrok; }
; ;
blist : /* lambda */ blist
| blist ID '=' INT { term($2, $4); } : /* nothing */
| blist ID { term($2, nextesn++); }
;
patterns
: /* nothing */
| patterns pattern ';'
| patterns ';'
| patterns error ';' { yyerrok; }
; ;
rules : /* lambda */ pattern
| rules lhs ':' tree '=' INT cost ';' '\n' { rule($2, $4, $6, $7); } : lhs '=' rhs when cost { rule($1, $3, nextern++, $4, $5); }
| rules '\n' ;
| rules error '\n' { yyerrok; }
lhs
: ID { $$ = $1; nonterm($$); }
; ;
lhs : ID { nonterm($$ = $1); } rhs
: ID { $$ = tree($1, NULL, NULL); }
| ID '(' rhs ')' { $$ = tree($1, $3, NULL); }
| ID '(' rhs ',' rhs ')' { $$ = tree($1, $3, $5); }
; ;
tree : ID { $$ = tree($1, NULL, NULL); } when
| ID '(' tree ')' { $$ = tree($1, $3, NULL); } : /* nothing */ { $$ = NULL; }
| ID '(' tree ',' tree ')' { $$ = tree($1, $3, $5); } | WHEN stringlist { $$ = $2; }
; ;
cost : /* lambda */ { $$ = 0; } stringlist
| '(' INT ')' { if ($2 > maxcost) { : /* nothing */ { $$ = NULL; }
yyerror("%d exceeds maximum cost of %d\n", $2, maxcost); | CFRAGMENT stringlist { $$ = pushstring($1, $2); }
$$ = maxcost; ;
} else
$$ = $2; } cost
: /* lambda */ { $$ = 0; }
| COST INT {
if ($2 > maxcost) {
yyerror("%d exceeds maximum cost of %d\n", $2, maxcost);
$$ = maxcost;
} else
$$ = $2;
}
; ;
%% %%
#include <stdarg.h> #include <stdarg.h>
@ -73,32 +113,6 @@ FILE *outfp = NULL;
static char buf[BUFSIZ], *bp = buf; static char buf[BUFSIZ], *bp = buf;
static int ppercent = 0; static int ppercent = 0;
static int get(void) {
if (*bp == 0) {
bp = buf;
*bp = 0;
if (fgets(buf, sizeof buf, infp) == NULL)
return EOF;
yylineno++;
while (buf[0] == '%' && buf[1] == '{' && (buf[2] == '\n' || buf[2] == '\r')) {
for (;;) {
if (fgets(buf, sizeof buf, infp) == NULL) {
yywarn("unterminated %{...%}\n");
return EOF;
}
yylineno++;
if (strcmp(buf, "%}\n") == 0 || strcmp(buf, "%}\r\n") == 0)
break;
fputs(buf, outfp);
}
if (fgets(buf, sizeof buf, infp) == NULL)
return EOF;
yylineno++;
}
}
return *bp++;
}
void yyerror(char *fmt, ...) { void yyerror(char *fmt, ...) {
va_list ap; va_list ap;
@ -111,58 +125,6 @@ void yyerror(char *fmt, ...) {
errcnt++; errcnt++;
} }
int yylex(void) {
int c;
while ((c = get()) != EOF) {
switch (c) {
case ' ': case '\f': case '\t': case '\r':
continue;
case '\n':
case '(': case ')': case ',':
case ';': case '=': case ':':
return c;
}
if (c == '%' && *bp == '%') {
bp++;
return ppercent++ ? 0 : PPERCENT;
} else if (c == '%' && strncmp(bp, "term", 4) == 0
&& isspace(bp[4])) {
bp += 4;
return TERMINAL;
} else if (c == '%' && strncmp(bp, "start", 5) == 0
&& isspace(bp[5])) {
bp += 5;
return START;
} else if (isdigit(c)) {
int n = 0;
do {
int d = c - '0';
if (n > (INT_MAX - d)/10)
yyerror("integer greater than %d\n", INT_MAX);
else
n = 10*n + d;
c = get();
} while (c != EOF && isdigit(c));
bp--;
yylval.n = n;
return INT;
} else if (isalpha(c)) {
char *p = bp - 1;
while (isalpha(*bp) || isdigit(*bp) || *bp == '_')
bp++;
yylval.string = alloc(bp - p + 1);
strncpy(yylval.string, p, bp - p);
yylval.string[bp - p] = 0;
return ID;
} else if (isprint(c))
yyerror("invalid character `%c'\n", c);
else
yyerror("invalid character `\\%03o'\n", (unsigned char)c);
}
return 0;
}
void yywarn(char *fmt, ...) { void yywarn(char *fmt, ...) {
va_list ap; va_list ap;
@ -172,3 +134,5 @@ void yywarn(char *fmt, ...) {
fprintf(stderr, "warning: "); fprintf(stderr, "warning: ");
vfprintf(stderr, fmt, ap); vfprintf(stderr, fmt, ap);
} }
/* vim: set sw=4 ts=4 expandtab : */

View file

@ -20,7 +20,6 @@ static Nonterm nts;
static Rule rules; static Rule rules;
static int nrules; static int nrules;
static char* stringf(char* fmt, ...);
static void print(char* fmt, ...); static void print(char* fmt, ...);
static void ckreach(Nonterm p); static void ckreach(Nonterm p);
static void emitclosure(Nonterm nts); static void emitclosure(Nonterm nts);
@ -34,6 +33,8 @@ static void emitleaf(Term p, int ntnumber);
static void emitnts(Rule rules, int nrules); static void emitnts(Rule rules, int nrules);
static void emitrecord(char* pre, Rule r, int cost); static void emitrecord(char* pre, Rule r, int cost);
static void emitrule(Nonterm nts); static void emitrule(Nonterm nts);
static void emitpredicatedefinitions(Rule rules);
static void emitpredicatecall(Rule rule);
static void emitstate(Term terms, Nonterm start, int ntnumber); static void emitstate(Term terms, Nonterm start, int ntnumber);
static void emitstring(Rule rules); static void emitstring(Rule rules);
static void emitstruct(Nonterm nts, int ntnumber); static void emitstruct(Nonterm nts, int ntnumber);
@ -45,6 +46,11 @@ int main(int argc, char* argv[])
int c, i; int c, i;
Nonterm p; Nonterm p;
#if 0
extern int yydebug;
yydebug = 1;
#endif
if (sizeof(short) == sizeof(int)) if (sizeof(short) == sizeof(int))
maxcost = SHRT_MAX / 2; maxcost = SHRT_MAX / 2;
for (i = 1; i < argc; i++) for (i = 1; i < argc; i++)
@ -88,7 +94,10 @@ int main(int argc, char* argv[])
infp = stdin; infp = stdin;
if (outfp == NULL) if (outfp == NULL)
outfp = stdout; outfp = stdout;
yyin = infp;
yyparse(); yyparse();
if (start) if (start)
ckreach(start); ckreach(start);
for (p = nts; p; p = p->link) for (p = nts; p; p = p->link)
@ -103,6 +112,7 @@ int main(int argc, char* argv[])
emitstring(rules); emitstring(rules);
emitrule(nts); emitrule(nts);
emitclosure(nts); emitclosure(nts);
emitpredicatedefinitions(rules);
if (start) if (start)
emitstate(terms, start, ntnumber); emitstate(terms, start, ntnumber);
print("#ifdef STATE_LABEL\n"); print("#ifdef STATE_LABEL\n");
@ -111,35 +121,30 @@ int main(int argc, char* argv[])
emitkids(rules, nrules); emitkids(rules, nrules);
emitfuncs(); emitfuncs();
print("#endif\n"); print("#endif\n");
if (!feof(infp)) print("#include \"mcgg_generated_footer.h\"\n");
while ((c = getc(infp)) != EOF)
putc(c, outfp);
return errcnt > 0; return errcnt > 0;
} }
/* alloc - allocate nbytes or issue fatal error */
void* alloc(int nbytes)
{
void* p = calloc(1, nbytes);
if (p == NULL)
{
yyerror("out of memory\n");
exit(1);
}
return p;
}
/* stringf - format and save a string */ /* stringf - format and save a string */
static char* stringf(char* fmt, ...) char* stringf(char* fmt, ...)
{ {
va_list ap; int n;
char* s, buf[512]; char* p;
va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
vsprintf(buf, fmt, ap); n = vsnprintf(NULL, 0, fmt, ap) + 1;
va_end(ap); va_end(ap);
return strcpy(alloc(strlen(buf) + 1), buf);
p = malloc(n);
if (!p)
return NULL;
va_start(ap, fmt);
vsnprintf(p, n, fmt, ap);
va_end(ap);
return p;
} }
struct entry struct entry
@ -178,7 +183,7 @@ static void* lookup(char* name)
/* install - install symbol name */ /* install - install symbol name */
static void* install(char* name) static void* install(char* name)
{ {
struct entry* p = alloc(sizeof *p); struct entry* p = calloc(1, sizeof *p);
int i = hash(name) % HASHSIZE; int i = hash(name) % HASHSIZE;
p->sym.name = name; p->sym.name = name;
@ -228,13 +233,16 @@ Term term(char* id, int esn)
p->name, p->esn); p->name, p->esn);
p->link = *q; p->link = *q;
*q = p; *q = p;
if (esn != -1)
print("enum { %s = %d };\n", id, esn);
return p; return p;
} }
/* 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(char* id, Tree left, Tree right)
{ {
Tree t = alloc(sizeof *t); Tree t = calloc(1, sizeof *t);
Term p = lookup(id); Term p = lookup(id);
int arity = 0; int arity = 0;
@ -268,12 +276,17 @@ Tree tree(char* id, Tree left, Tree right)
} }
/* rule - create & initialize a rule with the given fields */ /* rule - create & initialize a rule with the given fields */
Rule rule(char* id, Tree pattern, int ern, int cost) Rule rule(char* id, Tree pattern, int ern, Stringlist when, int cost)
{ {
Rule r = alloc(sizeof *r), *q; Rule r = calloc(1, sizeof *r);
Rule *q;
Term p = pattern->op; Term p = pattern->op;
if (when && (p->arity == 0))
yyerror("can't have a when clause on leaf nodes");
nrules++; nrules++;
r->when = when;
r->lhs = nonterm(id); r->lhs = nonterm(id);
r->packed = ++r->lhs->lhscount; r->packed = ++r->lhs->lhscount;
for (q = &r->lhs->rules; *q; q = &(*q)->decode) for (q = &r->lhs->rules; *q; q = &(*q)->decode)
@ -302,6 +315,14 @@ Rule rule(char* id, Tree pattern, int ern, int cost)
return r; return r;
} }
Stringlist pushstring(const char* data, Stringlist list)
{
Stringlist sl = calloc(1, sizeof *sl);
sl->payload = data;
sl->next = list;
return sl;
}
/* print - formatted output */ /* print - formatted output */
static void print(char* fmt, ...) static void print(char* fmt, ...)
{ {
@ -360,6 +381,11 @@ static void print(char* fmt, ...)
va_end(ap); va_end(ap);
} }
void printlineno(void)
{
print("#line %d\n", yylineno);
}
/* reach - mark all non-terminals in tree t as reachable */ /* reach - mark all non-terminals in tree t as reachable */
static void reach(Tree t) static void reach(Tree t)
{ {
@ -415,17 +441,26 @@ static void emitcase(Term p, int ntnumber)
{ {
case 0: case 0:
case -1: case -1:
print("%2{%1/* %R */\n%3c = ", r); print("%2if (");
emitpredicatecall(r);
print(")\n%2{%1/* %R */\n%3c = ", r);
break; break;
case 1: case 1:
if (r->pattern->nterms > 1) if (r->pattern->nterms > 1)
{ {
print("%2if (%1/* %R */\n", r); print("%2if (%1/* %R */\n", r);
emittest(r->pattern->left, "l", " "); emittest(r->pattern->left, "l", " ");
print("%3&& ");
emitpredicatecall(r);
print("\n");
print("%2) {\n%3c = "); print("%2) {\n%3c = ");
} }
else else
print("%2{%1/* %R */\n%3c = ", r); {
print("%2if (");
emitpredicatecall(r);
print(")\n%2{%1/* %R */\n%3c = ", r);
}
emitcost(r->pattern->left, "l"); emitcost(r->pattern->left, "l");
break; break;
case 2: case 2:
@ -435,10 +470,17 @@ static void emitcase(Term p, int ntnumber)
emittest(r->pattern->left, "l", emittest(r->pattern->left, "l",
r->pattern->right->nterms ? " && " : " "); r->pattern->right->nterms ? " && " : " ");
emittest(r->pattern->right, "r", " "); emittest(r->pattern->right, "r", " ");
print("%3&& ");
emitpredicatecall(r);
print("\n");
print("%2) {\n%3c = "); print("%2) {\n%3c = ");
} }
else else
print("%2{%1/* %R */\n%3c = ", r); {
print("%2if (");
emitpredicatecall(r);
print(")\n%2{%1/* %R */\n%3c = ", r);
}
emitcost(r->pattern->left, "l"); emitcost(r->pattern->left, "l");
emitcost(r->pattern->right, "r"); emitcost(r->pattern->right, "r");
break; break;
@ -555,8 +597,8 @@ static char* computekids(Tree t, char* v, char* bp, int* ip)
static void emitkids(Rule rules, int nrules) static void emitkids(Rule rules, int nrules)
{ {
int i; int i;
Rule r, * rc = alloc((nrules + 1) * sizeof *rc); Rule r, * rc = calloc(nrules+1, sizeof *rc);
char** str = alloc((nrules + 1) * sizeof *str); char** str = calloc(nrules+1, sizeof *str);
for (i = 0, r = rules; r; r = r->link) for (i = 0, r = rules; r; r = r->link)
{ {
@ -566,7 +608,7 @@ static void emitkids(Rule rules, int nrules)
for (j = 0; str[j] && strcmp(str[j], buf); j++) for (j = 0; str[j] && strcmp(str[j], buf); j++)
; ;
if (str[j] == NULL) if (str[j] == NULL)
str[j] = strcpy(alloc(strlen(buf) + 1), buf); str[j] = strdup(buf);
r->kids = rc[j]; r->kids = rc[j];
rc[j] = r; rc[j] = r;
} }
@ -592,16 +634,16 @@ static void emitlabel(Nonterm start)
"%1case 0:\n"); "%1case 0:\n");
if (Tflag) if (Tflag)
print("%2%Pnp = p;\n"); print("%2%Pnp = p;\n");
print("%2STATE_LABEL(p) = %Pstate(OP_LABEL(p), 0, 0);\n%2break;\n" print("%2STATE_LABEL(p) = %Pstate(p, 0, 0);\n%2break;\n"
"%1case 1:\n%2%Plabel1(LEFT_CHILD(p));\n"); "%1case 1:\n%2%Plabel1(LEFT_CHILD(p));\n");
if (Tflag) if (Tflag)
print("%2%Pnp = p;\n"); print("%2%Pnp = p;\n");
print("%2STATE_LABEL(p) = %Pstate(OP_LABEL(p),\n" print("%2STATE_LABEL(p) = %Pstate(p,\n"
"%3STATE_LABEL(LEFT_CHILD(p)), 0);\n%2break;\n" "%3STATE_LABEL(LEFT_CHILD(p)), 0);\n%2break;\n"
"%1case 2:\n%2%Plabel1(LEFT_CHILD(p));\n%2%Plabel1(RIGHT_CHILD(p));\n"); "%1case 2:\n%2%Plabel1(LEFT_CHILD(p));\n%2%Plabel1(RIGHT_CHILD(p));\n");
if (Tflag) if (Tflag)
print("%2%Pnp = p;\n"); print("%2%Pnp = p;\n");
print("%2STATE_LABEL(p) = %Pstate(OP_LABEL(p),\n" print("%2STATE_LABEL(p) = %Pstate(p,\n"
"%3STATE_LABEL(LEFT_CHILD(p)),\n%3STATE_LABEL(RIGHT_CHILD(p)));\n%2break;\n" "%3STATE_LABEL(LEFT_CHILD(p)),\n%3STATE_LABEL(RIGHT_CHILD(p)));\n%2break;\n"
"%1}\n}\n\n"); "%1}\n}\n\n");
print( print(
@ -635,8 +677,8 @@ static void emitleaf(Term p, int ntnumber)
if (cost == NULL) if (cost == NULL)
{ {
cost = alloc((ntnumber + 1) * sizeof *cost); cost = calloc(ntnumber+1, sizeof *cost);
rule = alloc((ntnumber + 1) * sizeof *rule); rule = calloc(ntnumber+1, sizeof *rule);
} }
for (i = 0; i <= ntnumber; i++) for (i = 0; i <= ntnumber; i++)
{ {
@ -686,8 +728,8 @@ static char* computents(Tree t, char* bp)
static void emitnts(Rule rules, int nrules) static void emitnts(Rule rules, int nrules)
{ {
Rule r; Rule r;
int i, j, * nts = alloc(nrules * sizeof *nts); int i, j, * nts = calloc(nrules, sizeof *nts);
char** str = alloc(nrules * sizeof *str); char** str = calloc(nrules, sizeof *str);
for (i = 0, r = rules; r; r = r->link) for (i = 0, r = rules; r; r = r->link)
{ {
@ -698,7 +740,7 @@ static void emitnts(Rule rules, int nrules)
if (str[j] == NULL) if (str[j] == NULL)
{ {
print("static short %Pnts_%d[] = { %s0 };\n", j, buf); print("static short %Pnts_%d[] = { %s0 };\n", j, buf);
str[j] = strcpy(alloc(strlen(buf) + 1), buf); str[j] = strdup(buf);
} }
nts[i++] = j; nts[i++] = j;
} }
@ -752,15 +794,48 @@ static void emitrule(Nonterm nts)
print("%1default:\n%2%Passert(0, PANIC(\"Bad goal nonterminal %%d in %Prule\\n\", goalnt));\n%1}\n%1return 0;\n}\n\n"); print("%1default:\n%2%Passert(0, PANIC(\"Bad goal nonterminal %%d in %Prule\\n\", goalnt));\n%1}\n%1return 0;\n}\n\n");
} }
/* emitpredicates - emit predicates for rules */
static void emitpredicatedefinitions(Rule r)
{
while (r)
{
Stringlist s = r->when;
if (s)
{
print("static int %Ppredicate_%d(NODEPTR_TYPE n) {\n", r->ern);
while (s)
{
print("%s", s->payload);
s = s->next;
}
print("\n}\n\n");
}
r = r->link;
}
}
/* emitpredicatecall - emit a call to a predicate */
static void emitpredicatecall(Rule r)
{
if (r->when)
print("%Ppredicate_%d(node)", r->ern);
else
print("1");
}
/* emitstate - emit state function */ /* emitstate - emit state function */
static void emitstate(Term terms, Nonterm start, int ntnumber) static void emitstate(Term terms, Nonterm start, int ntnumber)
{ {
int i; int i;
Term p; Term p;
print("STATE_TYPE %Pstate(int op, STATE_TYPE left, STATE_TYPE right) {\n%1int c;\n" print("STATE_TYPE %Pstate(NODEPTR_TYPE node, STATE_TYPE left, STATE_TYPE right) {\n%1int c;\n"
"%1struct %Pstate *p, *l = (struct %Pstate *)left,\n" "%1int op = OP_LABEL(node);\n"
"%2*r = (struct %Pstate *)right;\n\n%1assert(sizeof (STATE_TYPE) >= sizeof (void *));\n%1"); "%1struct %Pstate* p;\n"
"%1struct %Pstate* l = (struct %Pstate *)left;\n"
"%1struct %Pstate* r = (struct %Pstate *)right;\n"
"\n"
"%1assert(sizeof (STATE_TYPE) >= sizeof (void *));\n%1");
if (!Tflag) if (!Tflag)
print("if (%Parity[op] > 0) "); print("if (%Parity[op] > 0) ");
print("{\n%2p = ALLOC(sizeof *p);\n" print("{\n%2p = ALLOC(sizeof *p);\n"

View file

@ -3,7 +3,14 @@
/* $Id$ */ /* $Id$ */
/* iburg.c: */ /* iburg.c: */
extern void* alloc(int nbytes); extern char* stringf(char* fmt, ...);
typedef struct stringlist* Stringlist;
struct stringlist {
const char* payload;
Stringlist next;
};
extern Stringlist pushstring(const char* data, Stringlist list);
typedef enum typedef enum
{ {
@ -48,18 +55,19 @@ extern Tree tree(char* op, Tree left, Tree right);
struct rule struct rule
{ /* rules: */ { /* rules: */
Nonterm lhs; /* lefthand side non-terminal */ Nonterm lhs; /* lefthand side non-terminal */
Tree pattern; /* rule pattern */ Tree pattern; /* rule pattern */
int ern; /* external rule number */ int ern; /* external rule number */
int packed; /* packed external rule number */ int packed; /* packed external rule number */
int cost; /* associated cost */ int cost; /* associated cost */
Rule link; /* next rule in ern order */ Rule link; /* next rule in ern order */
Rule next; /* next rule with same pattern root */ Rule next; /* next rule with same pattern root */
Rule chain; /* next chain rule with same rhs */ Rule chain; /* next chain rule with same rhs */
Rule decode; /* next rule with same lhs */ Rule decode; /* next rule with same lhs */
Rule kids; /* next rule with same burm_kids pattern */ Rule kids; /* next rule with same burm_kids pattern */
Stringlist when; /* C predicate string */
}; };
extern Rule rule(char* id, Tree pattern, int ern, int cost); extern Rule rule(char* id, Tree pattern, int ern, Stringlist when, int cost);
extern int maxcost; /* maximum cost */ extern int maxcost; /* maximum cost */
/* gram.y: */ /* gram.y: */
@ -70,4 +78,11 @@ extern int errcnt;
extern FILE* infp; extern FILE* infp;
extern FILE* outfp; extern FILE* outfp;
/* Stupid flex imports --- why mo header file? */
extern FILE* yyin;
extern int yylineno;
extern void printlineno(void);
#endif #endif

View file

@ -0,0 +1,43 @@
static void dumpCover(NODEPTR_TYPE p, int goalnt, int indent) {
#ifdef TRACE
int eruleno = burm_rule(STATE_LABEL(p), goalnt);
short *nts = burm_nts[eruleno];
NODEPTR_TYPE kids[10];
int i;
for (i = 0; i < indent; i++)
fprintf(stderr, " ");
fprintf(stderr, "%s\n", burm_string[eruleno]);
burm_kids(p, eruleno, kids);
for (i = 0; nts[i]; i++)
dumpCover(kids[i], nts[i], indent + 1);
#endif
}
static NODEPTR_TYPE tree(int op, NODEPTR_TYPE l, NODEPTR_TYPE r) {
NODEPTR_TYPE p = malloc(sizeof *p);
assert(p);
p->op = op;
p->kids[0] = l; p->kids[1] = r;
return p;
}
int main(void) {
NODEPTR_TYPE p;
p = tree(STORE,
tree(LABEL, 0, 0),
tree(ADD,
tree(LOAD,
tree(LABEL, 0, 0),
0
),
tree(CONST, 0, 0)
)
);
burm_label(p);
dumpCover(p, 1, 0);
return 0;
}

69
util/mcgg/scan.l Normal file
View file

@ -0,0 +1,69 @@
%{
#include "iburg.h"
#include "y.tab.h"
static int braces = 0;
%}
%option warn
%option nodefault
%option noyywrap
%option yylineno
%x CSTRING
%x ECHO
%%
<INITIAL>"%{" { printlineno(); BEGIN(ECHO); }
<ECHO>"%}" BEGIN(INITIAL);
<ECHO>[%\n] fputc(yytext[0], outfp);
<ECHO>[^%\n]* fputs(yytext, outfp);
<INITIAL>"{" {
yylval.string = stringf("#line %d\n", yylineno);
braces = 1;
BEGIN(CSTRING);
return CFRAGMENT;
}
<CSTRING>"{" {
braces++;
yylval.string = strdup(yytext);
return CFRAGMENT;
}
<CSTRING>"}" {
braces--;
if (braces == 0)
BEGIN(INITIAL);
else
{
yylval.string = strdup(yytext);
return CFRAGMENT;
}
}
<CSTRING>[^{}]+ {
yylval.string = strdup(yytext);
return CFRAGMENT;
}
"%%" return PPERCENT;
"%term" return TERMINAL;
"%start" return START;
"PATTERNS" return PATTERNS;
"pat" return PAT;
"when" return WHEN;
"emit" return EMIT;
"cost" return COST;
[A-Za-z_][A-Za-z0-9_]* { yylval.string = strdup(yytext); return ID; }
[0-9]+ { yylval.n = atoi(yytext); return INT; }
[ \t\r\n]* ;
. return yytext[0];
%%
/* vim: set sw=4 ts=4 expandtab : */