Initial checkin of burg files

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3785 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2002-09-17 23:03:30 +00:00
parent 24b70926d5
commit 633a5b1aac
60 changed files with 11220 additions and 0 deletions

View File

@ -0,0 +1,13 @@
Copyright (C) 1991 Todd A. Proebsting
All Rights Reserved.
This software is in the public domain. You may use and copy this material
freely. This privilege extends to modifications, although any modified
version of this system given to a third party should clearly identify your
modifications as well as the original source.
The responsibility for the use of this material resides entirely with you.
We make no warranty of any kind concerning this material, nor do we make
any claim as to the suitability of BURG for any application. This software
is experimental in nature and there is no written or implied warranty. Use
it at your own risk.

View File

@ -0,0 +1,2 @@
8/20/02 -- Vikram Adve
be.c: Replaced "char*" with "const char*" to avoid compiler warnings.

View File

@ -0,0 +1,84 @@
# $Id$
#CFLAGS =
#CFLAGS = -O
#CFLAGS = -O -DNOLEX
CFLAGS = -g -DDEBUG
#CFLAGS = -g -DNOLEX -DDEBUG
SRCS = \
be.c \
burs.c \
closure.c \
delta.c \
fe.c \
item.c \
lex.c \
list.c \
main.c \
map.c \
nonterminal.c \
operator.c \
pattern.c \
plank.c \
queue.c \
rule.c \
string.c \
symtab.c \
table.c \
trim.c \
zalloc.c
BU_OBJS = \
burs.o \
closure.o \
delta.o \
item.o \
list.o \
map.o \
nonterminal.o \
operator.o \
pattern.o \
queue.o \
rule.o \
table.o \
trim.o \
zalloc.o
FE_OBJS = \
be.o \
fe.o \
lex.o \
main.o \
plank.o \
string.o \
symtab.o \
y.tab.o
all: test
burg: $(BU_OBJS) $(FE_OBJS)
$(CC) -o burg $(CFLAGS) $(BU_OBJS) $(FE_OBJS)
y.tab.c y.tab.h: gram.y
yacc -d gram.y
clean:
rm -f *.o y.tab.h y.tab.c core burg *.aux *.log *.dvi sample sample.c tmp
$(FE_OBJS): b.h
$(BU_OBJS): b.h
$(FE_OBJS): fe.h
lex.o: y.tab.h
doc.dvi: doc.tex
latex doc; latex doc
test: burg sample.gr
./burg -I <sample.gr >sample.c && cc $(CFLAGS) -o sample sample.c && ./sample
./burg -I sample.gr >tmp && cmp tmp sample.c
./burg -I <sample.gr -o tmp && cmp tmp sample.c
./burg -I sample.gr -o tmp && cmp tmp sample.c
./burg -I -O0 <sample.gr >tmp && cmp tmp sample.c
./burg -I -= <sample.gr >tmp && cmp tmp sample.c

14
support/tools/Burg/README Normal file
View File

@ -0,0 +1,14 @@
To format the documentation, type "make doc.dvi" and print the result.
The length of the cost vectors is fixed at 4 for reasons that are
primarily historical. To change it, edit the definition of DELTAWIDTH
in b.h.
Burg is compiled without optimization by default to avoid problems
with initial installation. To improve burg's performance, add '-O' to
CFLAGS in the Makefile and rebuild burg with a high quality optimizing
compiler.
To be added to the Burg mailing list, send your preferred electronic
mail address to cwf@research.att.com.

311
support/tools/Burg/b.h Normal file
View File

@ -0,0 +1,311 @@
/* $Id$ */
#define MAX_ARITY 2
typedef int ItemSetNum;
typedef int OperatorNum;
typedef int NonTerminalNum;
typedef int RuleNum;
typedef int ArityNum;
typedef int ERuleNum;
extern NonTerminalNum last_user_nonterminal;
extern NonTerminalNum max_nonterminal;
extern RuleNum max_rule;
extern ERuleNum max_erule_num;
extern int max_arity;
#ifdef __STDC__
#define ARGS(x) x
#else
#define ARGS(x) ()
#endif
#ifndef NOLEX
#define DELTAWIDTH 4
typedef short DeltaCost[DELTAWIDTH];
typedef short *DeltaPtr;
extern void ASSIGNCOST ARGS((DeltaPtr, DeltaPtr));
extern void ADDCOST ARGS((DeltaPtr, DeltaPtr));
extern void MINUSCOST ARGS((DeltaPtr, DeltaPtr));
extern void ZEROCOST ARGS((DeltaPtr));
extern int LESSCOST ARGS((DeltaPtr, DeltaPtr));
extern int EQUALCOST ARGS((DeltaPtr, DeltaPtr));
#define PRINCIPLECOST(x) (x[0])
#else
#define DELTAWIDTH 1
typedef int DeltaCost;
typedef int DeltaPtr;
#define ASSIGNCOST(l, r) ((l) = (r))
#define ADDCOST(l, r) ((l) += (r))
#define MINUSCOST(l, r) ((l) -= (r))
#define ZEROCOST(x) ((x) = 0)
#define LESSCOST(l, r) ((l) < (r))
#define EQUALCOST(l, r) ((l) == (r))
#define PRINCIPLECOST(x) (x)
#endif /* NOLEX */
#define NODIVERGE(c,state,nt,base) if (prevent_divergence > 0) CHECKDIVERGE(c,state,nt,base);
struct list {
void *x;
struct list *next;
};
typedef struct list *List;
struct intlist {
int x;
struct intlist *next;
};
typedef struct intlist *IntList;
struct operator {
char *name;
unsigned int ref:1;
OperatorNum num;
ItemSetNum baseNum;
ItemSetNum stateCount;
ArityNum arity;
struct table *table;
};
typedef struct operator *Operator;
struct nonterminal {
char *name;
NonTerminalNum num;
ItemSetNum baseNum;
ItemSetNum ruleCount;
struct plankMap *pmap;
struct rule *sampleRule; /* diagnostic---gives "a" rule that with this lhs */
};
typedef struct nonterminal *NonTerminal;
struct pattern {
NonTerminal normalizer;
Operator op; /* NULL if NonTerm -> NonTerm */
NonTerminal children[MAX_ARITY];
};
typedef struct pattern *Pattern;
struct rule {
DeltaCost delta;
ERuleNum erulenum;
RuleNum num;
RuleNum newNum;
NonTerminal lhs;
Pattern pat;
unsigned int used:1;
};
typedef struct rule *Rule;
struct item {
DeltaCost delta;
Rule rule;
};
typedef struct item Item;
typedef short *Relevant; /* relevant non-terminals */
typedef Item *ItemArray;
struct item_set { /* indexed by NonTerminal */
ItemSetNum num;
ItemSetNum newNum;
Operator op;
struct item_set *kids[2];
struct item_set *representative;
Relevant relevant;
ItemArray virgin;
ItemArray closed;
};
typedef struct item_set *Item_Set;
#define DIM_MAP_SIZE (1 << 8)
#define GLOBAL_MAP_SIZE (1 << 15)
struct mapping { /* should be a hash table for TS -> int */
List *hash;
int hash_size;
int max_size;
ItemSetNum count;
Item_Set *set; /* map: int <-> Item_Set */
};
typedef struct mapping *Mapping;
struct index_map {
ItemSetNum max_size;
Item_Set *class;
};
typedef struct index_map Index_Map;
struct dimension {
Relevant relevant;
Index_Map index_map;
Mapping map;
ItemSetNum max_size;
struct plankMap *pmap;
};
typedef struct dimension *Dimension;
struct table {
Operator op;
List rules;
Relevant relevant;
Dimension dimen[MAX_ARITY]; /* 1 for each dimension */
Item_Set *transition; /* maps local indices to global
itemsets */
};
typedef struct table *Table;
struct relation {
Rule rule;
DeltaCost chain;
NonTerminalNum nextchain;
DeltaCost sibling;
int sibFlag;
int sibComputed;
};
typedef struct relation *Relation;
struct queue {
List head;
List tail;
};
typedef struct queue *Queue;
struct plank {
char *name;
List fields;
int width;
};
typedef struct plank *Plank;
struct except {
short index;
short value;
};
typedef struct except *Exception;
struct plankMap {
List exceptions;
int offset;
struct stateMap *values;
};
typedef struct plankMap *PlankMap;
struct stateMap {
char *fieldname;
Plank plank;
int width;
short *value;
};
typedef struct stateMap *StateMap;
struct stateMapTable {
List maps;
};
extern void CHECKDIVERGE ARGS((DeltaPtr, Item_Set, int, int));
extern void zero ARGS((Item_Set));
extern ItemArray newItemArray ARGS((void));
extern ItemArray itemArrayCopy ARGS((ItemArray));
extern Item_Set newItem_Set ARGS((Relevant));
extern void freeItem_Set ARGS((Item_Set));
extern Mapping newMapping ARGS((int));
extern NonTerminal newNonTerminal ARGS((char *));
extern int nonTerminalName ARGS((char *, int));
extern Operator newOperator ARGS((char *, OperatorNum, ArityNum));
extern Pattern newPattern ARGS((Operator));
extern Rule newRule ARGS((DeltaPtr, ERuleNum, NonTerminal, Pattern));
extern List newList ARGS((void *, List));
extern IntList newIntList ARGS((int, IntList));
extern int length ARGS((List));
extern List appendList ARGS((void *, List));
extern Table newTable ARGS((Operator));
extern Queue newQ ARGS((void));
extern void addQ ARGS((Queue, Item_Set));
extern Item_Set popQ ARGS((Queue));
extern int equivSet ARGS((Item_Set, Item_Set));
extern Item_Set decode ARGS((Mapping, ItemSetNum));
extern Item_Set encode ARGS((Mapping, Item_Set, int *));
extern void build ARGS((void));
extern Item_Set *transLval ARGS((Table, int, int));
typedef void * (*ListFn) ARGS((void *));
extern void foreachList ARGS((ListFn, List));
extern void reveachList ARGS((ListFn, List));
extern void addToTable ARGS((Table, Item_Set));
extern void closure ARGS((Item_Set));
extern void trim ARGS((Item_Set));
extern void findChainRules ARGS((void));
extern void findAllPairs ARGS((void));
extern void addRelevant ARGS((Relevant, NonTerminalNum));
extern void *zalloc ARGS((unsigned int));
extern void zfree ARGS((void *));
extern NonTerminal start;
extern List rules;
extern List chainrules;
extern List operators;
extern List leaves;
extern List nonterminals;
extern List grammarNts;
extern Queue globalQ;
extern Mapping globalMap;
extern int exceptionTolerance;
extern int prevent_divergence;
extern int principleCost;
extern int lexical;
extern struct rule stub_rule;
extern Relation *allpairs;
extern Item_Set *sortedStates;
extern Item_Set errorState;
extern void dumpRelevant ARGS((Relevant));
extern void dumpOperator ARGS((Operator, int));
extern void dumpOperator_s ARGS((Operator));
extern void dumpOperator_l ARGS((Operator));
extern void dumpNonTerminal ARGS((NonTerminal));
extern void dumpRule ARGS((Rule));
extern void dumpRuleList ARGS((List));
extern void dumpItem ARGS((Item *));
extern void dumpItem_Set ARGS((Item_Set));
extern void dumpMapping ARGS((Mapping));
extern void dumpQ ARGS((Queue));
extern void dumpIndex_Map ARGS((Index_Map *));
extern void dumpDimension ARGS((Dimension));
extern void dumpPattern ARGS((Pattern));
extern void dumpTable ARGS((Table, int));
extern void dumpTransition ARGS((Table));
extern void dumpCost ARGS((DeltaCost));
extern void dumpAllPairs ARGS((void));
extern void dumpRelation ARGS((Relation));
extern void dumpSortedStates ARGS((void));
extern void dumpSortedRules ARGS((void));
extern int debugTrim;
#ifdef DEBUG
#define debug(a,b) if (a) b
#else
#define debug(a,b)
#endif
extern int debugTables;
#define TABLE_INCR 8
#define STATES_INCR 64
#ifdef NDEBUG
#define assert(c) ((void) 0)
#else
#define assert(c) ((void) ((c) || fatal(__FILE__,__LINE__)))
#endif
extern void doStart ARGS((char *));
extern void exit ARGS((int));
extern int fatal ARGS((char *, int));
extern void yyerror ARGS((char *));
extern void yyerror1 ARGS((char *));

1052
support/tools/Burg/be.c Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

71
support/tools/Burg/burs.c Normal file
View File

@ -0,0 +1,71 @@
char rcsid_burs[] = "$Id$";
#include "b.h"
Item_Set errorState;
static void doLeaf ARGS((Operator));
static void
doLeaf(leaf) Operator leaf;
{
int new;
List pl;
Item_Set ts;
Item_Set tmp;
assert(leaf->arity == 0);
ts = newItem_Set(leaf->table->relevant);
for (pl = rules; pl; pl = pl->next) {
Rule p = (Rule) pl->x;
if (p->pat->op == leaf) {
if (!ts->virgin[p->lhs->num].rule || p->delta < ts->virgin[p->lhs->num].delta) {
ts->virgin[p->lhs->num].rule = p;
ASSIGNCOST(ts->virgin[p->lhs->num].delta, p->delta);
ts->op = leaf;
}
}
}
trim(ts);
zero(ts);
tmp = encode(globalMap, ts, &new);
if (new) {
closure(ts);
leaf->table->transition[0] = ts;
addQ(globalQ, ts);
} else {
leaf->table->transition[0] = tmp;
freeItem_Set(ts);
}
}
void
build()
{
int new;
List ol;
Item_Set ts;
globalQ = newQ();
globalMap = newMapping(GLOBAL_MAP_SIZE);
ts = newItem_Set(0);
errorState = encode(globalMap, ts, &new);
ts->closed = ts->virgin;
addQ(globalQ, ts);
foreachList((ListFn) doLeaf, leaves);
debug(debugTables, printf("---initial set of states ---\n"));
debug(debugTables, dumpMapping(globalMap));
debug(debugTables, foreachList((ListFn) dumpItem_Set, globalQ->head));
for (ts = popQ(globalQ); ts; ts = popQ(globalQ)) {
for (ol = operators; ol; ol = ol->next) {
Operator op = (Operator) ol->x;
addToTable(op->table, ts);
}
}
}

View File

@ -0,0 +1,95 @@
char rcsid_closure[] = "$Id$";
#include <stdio.h>
#include "b.h"
int prevent_divergence = 0;
List chainrules;
void
findChainRules()
{
List pl;
assert(!chainrules);
for (pl = rules; pl; pl = pl->next) {
Rule p = (Rule) pl->x;
if (!p->pat->op) {
chainrules = newList(p, chainrules);
} else {
p->pat->op->table->rules = newList(p, p->pat->op->table->rules);
addRelevant(p->pat->op->table->relevant, p->lhs->num);
}
}
}
void
zero(t) Item_Set t;
{
int i;
DeltaCost base;
int exists;
int base_nt;
assert(!t->closed);
ZEROCOST(base);
exists = 0;
for (i = 0; i < max_nonterminal; i++) {
if (t->virgin[i].rule) {
if (exists) {
if (LESSCOST(t->virgin[i].delta, base)) {
ASSIGNCOST(base, t->virgin[i].delta);
base_nt = i;
}
} else {
ASSIGNCOST(base, t->virgin[i].delta);
exists = 1;
base_nt = i;
}
}
}
if (!exists) {
return;
}
for (i = 0; i < max_nonterminal; i++) {
if (t->virgin[i].rule) {
MINUSCOST(t->virgin[i].delta, base);
}
NODIVERGE(t->virgin[i].delta, t, i, base_nt);
}
}
void
closure(t) Item_Set t;
{
int changes;
List pl;
assert(!t->closed);
t->closed = itemArrayCopy(t->virgin);
changes = 1;
while (changes) {
changes = 0;
for (pl = chainrules; pl; pl = pl->next) {
Rule p = (Rule) pl->x;
register Item *rhs_item = &t->closed[p->pat->children[0]->num];
if (rhs_item->rule) { /* rhs is active */
DeltaCost dc;
register Item *lhs_item = &t->closed[p->lhs->num];
ASSIGNCOST(dc, rhs_item->delta);
ADDCOST(dc, p->delta);
if (LESSCOST(dc, lhs_item->delta) || !lhs_item->rule) {
ASSIGNCOST(lhs_item->delta, dc);
lhs_item->rule = p;
changes = 1;
}
}
}
}
}

143
support/tools/Burg/delta.c Normal file
View File

@ -0,0 +1,143 @@
char rcsid_delta[] = "$Id$";
#include <stdio.h>
#include "b.h"
#include "fe.h"
int principleCost = 0;
int lexical = 0;
#ifndef NOLEX
void
ASSIGNCOST(l, r) DeltaPtr l; DeltaPtr r;
{
int i;
if (lexical) {
for (i = 0; i < DELTAWIDTH; i++) {
l[i] = r[i];
}
} else {
l[0] = r[0];
}
}
void
ADDCOST(l, r) DeltaPtr l; DeltaPtr r;
{
int i;
if (lexical) {
for (i = 0; i < DELTAWIDTH; i++) {
l[i] += r[i];
}
} else {
l[0] += r[0];
}
}
void
MINUSCOST(l, r) DeltaPtr l; DeltaPtr r;
{
int i;
if (lexical) {
for (i = 0; i < DELTAWIDTH; i++) {
l[i] -= r[i];
}
} else {
l[0] -= r[0];
}
}
void
ZEROCOST(x) DeltaPtr x;
{
int i;
if (lexical) {
for (i = 0; i < DELTAWIDTH; i++) {
x[i] = 0;
}
} else {
x[0] = 0;
}
}
int
LESSCOST(l, r) DeltaPtr l; DeltaPtr r;
{
int i;
if (lexical) {
for (i = 0; i < DELTAWIDTH; i++) {
if (l[i] < r[i]) {
return 1;
} else if (l[i] > r[i]) {
return 0;
}
}
return 0;
} else {
return l[0] < r[0];
}
}
int
EQUALCOST(l, r) DeltaPtr l; DeltaPtr r;
{
int i;
if (lexical) {
for (i = 0; i < DELTAWIDTH; i++) {
if (l[i] != r[i]) {
return 0;
}
}
return 1;
} else {
return l[0] == r[0];
}
}
#endif /* NOLEX */
void
CHECKDIVERGE(c, its, nt, base) DeltaPtr c; Item_Set its; int nt; int base;
{
int i;
if (prevent_divergence <= 0) {
return;
}
if (lexical) {
#ifndef NOLEX
for (i = 0; i < DELTAWIDTH; i++) {
if (c[i] > prevent_divergence) {
char ntname[100];
char basename[100];
nonTerminalName(ntname, nt);
nonTerminalName(basename, base);
fprintf(stderr, "ERROR: The grammar appears to diverge\n");
fprintf(stderr, "\tRelative Costs: %s(0), %s(%d)\n", basename, ntname, c[i]);
fprintf(stderr, "\tOffending Operator: %s\n", its->op->name);
fprintf(stderr, "\tOffending Tree: ");
printRepresentative(stderr, its);
fprintf(stderr, "\n");
exit(1);
}
}
#endif /*NOLEX*/
} else if (PRINCIPLECOST(c) > prevent_divergence) {
char ntname[100];
char basename[100];
nonTerminalName(ntname, nt);
nonTerminalName(basename, base);
fprintf(stderr, "ERROR: The grammar appears to diverge\n");
fprintf(stderr, "\tRelative Costs: %s(0), %s(%d)\n", basename, ntname, PRINCIPLECOST(c));
fprintf(stderr, "\tOffending Operator: %s\n", its->op->name);
fprintf(stderr, "\tOffending Tree: ");
printRepresentative(stderr, its);
fprintf(stderr, "\n");
exit(1);
}
}

403
support/tools/Burg/fe.c Normal file
View File

@ -0,0 +1,403 @@
char rcsid_fe[] = "$Id$";
#include <stdio.h>
#include <string.h>
#include "b.h"
#include "fe.h"
int grammarflag;
static int arity;
List ruleASTs;
List grammarNts;
static void doBinding ARGS((Binding));
static void doDecl ARGS((Arity));
static NonTerminal lookup ARGS((Pattern));
static NonTerminal normalize ARGS((PatternAST, NonTerminal, Pattern *));
static void doEnterNonTerm ARGS((RuleAST));
static void doRule ARGS((RuleAST));
static void doTable ARGS((Operator));
static void
doBinding(b) Binding b;
{
int new;
Symbol s;
s = enter(b->name, &new);
if (!new) {
fprintf(stderr, "Non-unique name: %s\n", b->name);
exit(1);
}
s->tag = OPERATOR;
s->u.op = newOperator(b->name, b->opnum, arity);
if (arity == 0) {
leaves = newList(s->u.op, leaves);
}
}
static void
doDecl(a) Arity a;
{
if (!a) {
return;
}
arity = a->arity;
foreachList((ListFn) doBinding, a->bindings);
}
static List xpatterns;
static int tcount;
static NonTerminal
lookup(p) Pattern p;
{
char buf[10];
char *s;
List l;
NonTerminal n;
DeltaCost dummy;
for (l = xpatterns; l; l = l->next) {
Pattern x = (Pattern) l->x;
if (x->op == p->op
&& x->children[0] == p->children[0]
&& x->children[1] == p->children[1]) {
return x->normalizer;
}
}
sprintf(buf, "n%%%d", tcount++);
s = (char *) zalloc(strlen(buf)+1);
strcpy(s, buf);
n = newNonTerminal(s);
p->normalizer = n;
xpatterns = newList(p, xpatterns);
ZEROCOST(dummy);
(void) newRule(dummy, 0, n, p);
return n;
}
static NonTerminal
normalize(ast, nt, patt) PatternAST ast; NonTerminal nt; Pattern *patt;
{
Symbol s;
int new;
Pattern dummy;
s = enter(ast->op, &new);
ast->sym = s;
if (new) {
fprintf(stderr, "Illegal use of %s --- undefined symbol\n", s->name);
exit(1);
return 0; /* shut up compilers */
} else if (s->tag == NONTERMINAL) {
if (ast->children) {
fprintf(stderr, "Illegal use of %s, a non-terminal, as a terminal\n", s->name);
exit(1);
}
*patt = newPattern(0);
(*patt)->children[0] = s->u.nt;
return s->u.nt;
} else {
s->u.op->ref = 1;
*patt = newPattern(s->u.op);
if (s->u.op->arity == -1) {
if (!ast->children) {
s->u.op->arity = 0;
leaves = newList(s->u.op, leaves);
} else if (!ast->children->next) {
s->u.op->arity = 1;
} else if (!ast->children->next->next) {
s->u.op->arity = 2;
} else {
fprintf(stderr, "ERROR: Too many children (max = 2) for \"%s\"\n", s->name);
exit(1);
}
if (s->u.op->arity > max_arity) {
max_arity = s->u.op->arity;
}
}
switch (s->u.op->arity) {
default:
assert(0);
break;
case 0:
if (ast->children) {
fprintf(stderr, "ERROR: Incorrect number of children for leaf operator, \"%s\"\n", s->name);
exit(1);
}
break;
case 1:
if (!ast->children || ast->children->next) {
fprintf(stderr, "ERROR: Incorrect number of children for unary operator, \"%s\"\n", s->name);
exit(1);
}
(*patt)->children[0] = normalize((PatternAST) ast->children->x, 0, &dummy);
break;
case 2:
if (!ast->children || !ast->children->next) {
fprintf(stderr, "ERROR: Incorrect number of children for binary operator, \"%s\"\n", s->name);
exit(1);
}
(*patt)->children[0] = normalize((PatternAST) ast->children->x, 0, &dummy);
(*patt)->children[1] = normalize((PatternAST) ast->children->next->x, 0, &dummy);
break;
}
if (nt) {
(*patt)->normalizer = nt;
return nt;
} else {
return lookup(*patt);
}
}
}
static void
doEnterNonTerm(ast) RuleAST ast;
{
int new;
Symbol s;
DeltaCost delta;
int i;
IntList p;
s = enter(ast->lhs, &new);
if (new) {
s->u.nt = newNonTerminal(s->name);
s->tag = NONTERMINAL;
} else {
if (s->tag != NONTERMINAL) {
fprintf(stderr, "Illegal use of %s as a non-terminal\n", s->name);
exit(1);
}
}
ZEROCOST(delta);
for (p = ast->cost, i = 0; p; p = p->next, i++) {
int x = p->x;
#ifndef NOLEX
if (lexical) {
if (i < DELTAWIDTH) {
delta[i] = x;
}
} else
#endif /* NOLEX */
{
if (i == principleCost) {
PRINCIPLECOST(delta) = x;
}
}
}
ast->rule = newRule(delta, ast->erulenum, s->u.nt, 0);
}
static void
doRule(ast) RuleAST ast;
{
Pattern pat;
(void) normalize(ast->pat, ast->rule->lhs, &pat);
ast->rule->pat = pat;
}
static void
doTable(op) Operator op;
{
op->table = newTable(op);
}
void
doSpec(decls, rules) List decls; List rules;
{
foreachList((ListFn) doDecl, decls);
debug(debugTables, foreachList((ListFn) dumpOperator_l, operators));
ruleASTs = rules;
reveachList((ListFn) doEnterNonTerm, rules);
last_user_nonterminal = max_nonterminal;
reveachList((ListFn) doRule, rules);
debug(debugTables, foreachList((ListFn) dumpRule, rules));
foreachList((ListFn) doTable, operators);
}
void
doStart(name) char *name;
{
Symbol s;
int new;
if (start) {
yyerror1("Redeclaration of start symbol to be ");
fprintf(stderr, "\"%s\"\n", name);
exit(1);
}
s = enter(name, &new);
if (new) {
s->u.nt = newNonTerminal(s->name);
s->tag = NONTERMINAL;
} else {
if (s->tag != NONTERMINAL) {
fprintf(stderr, "Illegal use of %s as a non-terminal\n", s->name);
exit(1);
}
}
}
void
doGrammarNts()
{
List l;
int new;
for (l = grammarNts; l; l = l->next) {
char *n = (char*) l->x;
Symbol s;
s = enter(n, &new);
if (new) {
fprintf(stderr, "ERROR: %%gram, unused non-terminal: \"%s\"\n", n);
exit(1);
}
if (s->tag != NONTERMINAL) {
fprintf(stderr, "ERROR: %%gram, Not a non-terminal: \"%s\"\n", n);
exit(1);
}
l->x = s;
}
}
void
doGram(nts) List nts;
{
if (grammarNts) {
yyerror1("Redeclaration of %%gram\n");
exit(1);
}
grammarNts = nts;
}
Arity
newArity(ar, b) int ar; List b;
{
Arity a = (Arity) zalloc(sizeof(struct arity));
a->arity = ar;
a->bindings = b;
return a;
}
Binding
newBinding(name, opnum) char *name; int opnum;
{
Binding b = (Binding) zalloc(sizeof(struct binding));
if (opnum == 0) {
yyerror1("ERROR: Non-positive external symbol number, ");
fprintf(stderr, "%d", opnum);
exit(1);
}
b->name = name;
b->opnum = opnum;
return b;
}
PatternAST
newPatternAST(op, children) char *op; List children;
{
PatternAST p = (PatternAST) zalloc(sizeof(struct patternAST));
p->op = op;
p->children = children;
return p;
}
int max_ruleAST;
RuleAST
newRuleAST(lhs, pat, erulenum, cost) char *lhs; PatternAST pat; int erulenum; IntList cost;
{
RuleAST p = (RuleAST) zalloc(sizeof(struct ruleAST));
p->lhs = lhs;
p->pat = pat;
if (erulenum <= 0) {
yyerror1("External Rulenumber ");
fprintf(stderr, "(%d) <= 0\n", erulenum);
exit(1);
}
p->erulenum = erulenum;
p->cost = cost;
max_ruleAST++;
return p;
}
void
dumpBinding(b) Binding b;
{
printf("%s=%d ", b->name, b->opnum);
}
void
dumpArity(a) Arity a;
{
List l;
printf("Arity(%d) ", a->arity);
for (l = a->bindings; l; l = l->next) {
Binding b = (Binding) l->x;
dumpBinding(b);
}
printf("\n");
}
void
dumpPatternAST(p) PatternAST p;
{
List l;
printf("%s", p->op);
if (p->children) {
printf("(");
for (l = p->children; l; l = l->next) {
PatternAST past = (PatternAST) l->x;
dumpPatternAST(past);
if (l->next) {
printf(", ");
}
}
printf(")");
}
}
void
dumpRuleAST(p) RuleAST p;
{
printf("%s : ", p->lhs);
dumpPatternAST(p->pat);
printf(" = %d (%ld)\n", p->erulenum, (long) p->cost);
}
void
dumpDecls(decls) List decls;
{
List l;
for (l = decls; l; l = l->next) {
Arity a = (Arity) l->x;
dumpArity(a);
}
}
void
dumpRules(rules) List rules;
{
List l;
for (l = rules; l; l = l->next) {
RuleAST p = (RuleAST) l->x;
dumpRuleAST(p);
}
}

127
support/tools/Burg/fe.h Normal file
View File

@ -0,0 +1,127 @@
/* $Id$ */
struct binding {
char *name;
int opnum;
};
typedef struct binding *Binding;
struct arity {
int arity;
List bindings;
};
typedef struct arity *Arity;
struct patternAST {
struct symbol *sym;
char *op;
List children;
};
typedef struct patternAST *PatternAST;
struct ruleAST {
char *lhs;
PatternAST pat;
int erulenum;
IntList cost;
struct rule *rule;
struct strTableElement *kids;
struct strTableElement *nts;
};
typedef struct ruleAST *RuleAST;
typedef enum {
UNKNOWN,
OPERATOR,
NONTERMINAL
} TagType;
struct symbol {
char *name;
TagType tag;
union {
NonTerminal nt;
Operator op;
} u;
};
typedef struct symbol *Symbol;
struct strTableElement {
char *str;
IntList erulenos;
char *ename;
};
typedef struct strTableElement *StrTableElement;
struct strTable {
List elems;
};
typedef struct strTable *StrTable;
extern StrTable newStrTable ARGS((void));
extern StrTableElement addString ARGS((StrTable, char *, int, int *));
extern void doSpec ARGS((List, List));
extern Arity newArity ARGS((int, List));
extern Binding newBinding ARGS((char *, int));
extern PatternAST newPatternAST ARGS((char *, List));
extern RuleAST newRuleAST ARGS((char *, PatternAST, int, IntList));
extern Symbol enter ARGS((char *, int *));
extern Symbol newSymbol ARGS((char *));
extern void makeDebug ARGS((void));
extern void makeSimple ARGS((void));
extern void makePlanks ARGS((void));
extern void makeOpLabel ARGS((void));
extern void makeChild ARGS((void));
extern void makeOperators ARGS((void));
extern void makeLabel ARGS((void));
extern void makeString ARGS((void));
extern void makeString ARGS((void));
extern void makeReduce ARGS((void));
extern void makeRuleTable ARGS((void));
extern void makeTables ARGS((void));
extern void makeTreecost ARGS((void));
extern void makePrint ARGS((void));
extern void makeRule ARGS((void));
extern void makeNts ARGS((void));
extern void makeKids ARGS((void));
extern void startBurm ARGS((void));
extern void startOptional ARGS((void));
extern void makePlankLabel ARGS((void));
extern void makeStateLabel ARGS((void));
extern void makeStringArray ARGS((void));
extern void makeNonterminalArray ARGS((void));
extern void makeCostArray ARGS((void));
extern void makeLHSmap ARGS((void));
extern void makeClosureArray ARGS((void));
extern void makeOperatorVector ARGS((void));
extern void endOptional ARGS((void));
extern void reportDiagnostics ARGS((void));
extern void makeNonterminals ARGS((void));
extern int opsOfArity ARGS((int));
extern void yypurge ARGS((void));
extern void yyfinished ARGS((void));
extern void printRepresentative ARGS((FILE *, Item_Set));
extern void dumpRules ARGS((List));
extern void dumpDecls ARGS((List));
extern void dumpRuleAST ARGS((RuleAST));
extern void dumpPatternAST ARGS((PatternAST));
extern void dumpArity ARGS((Arity));
extern void dumpBinding ARGS((Binding));
extern void dumpStrTable ARGS((StrTable));
extern int yylex ARGS((void));
extern int yyparse ARGS((void));
extern int max_ruleAST;
extern List ruleASTs;
extern FILE *outfile;
extern char *prefix;
extern int trimflag;
extern int speedflag;
extern int grammarflag;

90
support/tools/Burg/gram.y Normal file
View File

@ -0,0 +1,90 @@
%{
char rcsid_gram[] = "$Id$";
#include <stdio.h>
#include "b.h"
#include "fe.h"
%}
%union {
int y_int;
char *y_string;
Arity y_arity;
Binding y_binding;
PatternAST y_patternAST;
RuleAST y_ruleAST;
List y_list;
IntList y_intlist;
}
%start full
%term ERROR
%term K_TERM
%term K_GRAM
%term K_START
%term K_PPERCENT
%term INT
%term ID
%token <y_string> ID
%token <y_int> INT
%type <y_arity> decl
%type <y_binding> binding
%type <y_intlist> cost costtail
%type <y_ruleAST> rule
%type <y_patternAST> pattern
%type <y_list> decls rules bindinglist grammarlist
%%
full : spec
| spec K_PPERCENT
{ yyfinished(); }
;
spec : decls K_PPERCENT rules
= { doSpec($1, $3); }
;
decls : /* lambda */ = { $$ = 0; }
| decls decl = { $$ = newList($2, $1); }
;
decl : K_TERM bindinglist = { $$ = newArity(-1, $2); }
| K_GRAM grammarlist = { $$ = 0; doGram($2); }
| K_START ID = { $$ = 0; doStart($2); } /* kludge */
;
grammarlist : /* lambda */ = { $$ = 0; }
| grammarlist ID = { $$ = newList($2, $1); }
;
bindinglist : /* lambda */ = { $$ = 0; }
| bindinglist binding = { $$ = newList($2, $1); }
;
binding : ID '=' INT = { $$ = newBinding($1, $3); }
;
rules : /* lambda */ = { $$ = 0; }
| rules rule = { $$ = newList($2, $1); }
;
rule : ID ':' pattern '=' INT cost ';' = { $$ = newRuleAST($1, $3, $5, $6); }
;
pattern : ID = { $$ = newPatternAST($1, 0); }
| ID '(' pattern ')' = { $$ = newPatternAST($1, newList($3,0)); }
| ID '(' pattern ',' pattern ')' = { $$ = newPatternAST($1, newList($3, newList($5, 0))); }
;
cost : /* lambda */ = { $$ = 0; }
| '(' INT costtail ')' = { $$ = newIntList($2, $3); }
;
costtail : /* lambda */ = { $$ = 0; }
| ',' INT costtail = { $$ = newIntList($2, $3); }
| INT costtail = { $$ = newIntList($1, $2); }
;

133
support/tools/Burg/item.c Normal file
View File

@ -0,0 +1,133 @@
char rcsid_item[] = "$Id$";
#include "b.h"
#include <stdio.h>
#include <string.h>
#include "fe.h"
static Item_Set fptr;
ItemArray
newItemArray()
{
ItemArray ia;
ia = (ItemArray) zalloc(max_nonterminal *sizeof(*ia));
return ia;
}
ItemArray
itemArrayCopy(src) ItemArray src;
{
ItemArray dst;
dst = newItemArray();
memcpy(dst, src, max_nonterminal * sizeof(*dst));
return dst;
}
Item_Set
newItem_Set(relevant) Relevant relevant;
{
Item_Set ts;
if (fptr) {
ts = fptr;
fptr = 0;
memset(ts->virgin, 0, max_nonterminal * sizeof(struct item));
if (ts->closed) {
zfree(ts->closed);
ts->closed = 0;
}
ts->num = 0;
ts->op = 0;
} else {
ts = (Item_Set) zalloc(sizeof(struct item_set));
ts->virgin = newItemArray();
}
ts->relevant = relevant;
return ts;
}
void
freeItem_Set(ts) Item_Set ts;
{
assert(!fptr);
fptr = ts;
}
int
equivSet(a, b) Item_Set a; Item_Set b;
{
register Relevant r;
register int nt;
register Item *aa = a->virgin;
register Item *ba = b->virgin;
/*
return !bcmp(a->virgin, b->virgin, max_nonterminal * sizeof(Item));
*/
r = a->relevant ? a->relevant : b->relevant;
assert(r);
if (a->op && b->op && a->op != b->op) {
return 0;
}
for (; (nt = *r) != 0; r++) {
if (aa[nt].rule != ba[nt].rule || !EQUALCOST(aa[nt].delta, ba[nt].delta)) {
return 0;
}
}
return 1;
}
void
printRepresentative(f, s) FILE *f; Item_Set s;
{
if (!s) {
return;
}
fprintf(f, "%s", s->op->name);
switch (s->op->arity) {
case 1:
fprintf(f, "(");
printRepresentative(f, s->kids[0]);
fprintf(f, ")");
break;
case 2:
fprintf(f, "(");
printRepresentative(f, s->kids[0]);
fprintf(f, ", ");
printRepresentative(f, s->kids[1]);
fprintf(f, ")");
break;
}
}
void
dumpItem(t) Item *t;
{
printf("[%s #%d]", t->rule->lhs->name, t->rule->num);
dumpCost(t->delta);
}
void
dumpItem_Set(ts) Item_Set ts;
{
int i;
printf("Item_Set #%d: [", ts->num);
for (i = 1; i < max_nonterminal; i++) {
if (ts->virgin[i].rule) {
printf(" %d", i);
dumpCost(ts->virgin[i].delta);
}
}
printf(" ]\n");
}
void
dumpCost(dc) DeltaCost dc;
{
printf("(%ld)", (long) dc);
}

260
support/tools/Burg/lex.c Normal file
View File

@ -0,0 +1,260 @@
char rcsid_lex[] = "$Id$";
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include "b.h"
#include "fe.h"
#include "y.tab.h"
static char buf[BUFSIZ];
static int yyline = 1;
typedef int (*ReadFn) ARGS((void));
static char *StrCopy ARGS((char *));
static int code_get ARGS((void));
static int simple_get ARGS((void));
static void ReadCharString ARGS((ReadFn, int));
static void ReadCodeBlock ARGS((void));
static void ReadOldComment ARGS((ReadFn));
static char *
StrCopy(s) char *s;
{
char *t = (char *)zalloc(strlen(s) + 1);
strcpy(t,s);
return t;
}
static int
simple_get()
{
int ch;
if ((ch = getchar()) == '\n') {
yyline++;
}
return ch;
}
static int
code_get()
{
int ch;
if ((ch = getchar()) == '\n') {
yyline++;
}
if (ch != EOF) {
fputc(ch, outfile);
}
return ch;
}
void
yypurge()
{
while (code_get() != EOF) ;
}
static void
ReadCharString(rdfn, which) ReadFn rdfn; int which;
{
int ch;
int backslash = 0;
int firstline = yyline;
while ((ch = rdfn()) != EOF) {
if (ch == which && !backslash) {
return;
}
if (ch == '\\' && !backslash) {
backslash = 1;
} else {
backslash = 0;
}
}
yyerror1("Unexpected EOF in string on line ");
fprintf(stderr, "%d\n", firstline);
exit(1);
}
static void
ReadOldComment(rdfn) ReadFn rdfn;
{
/* will not work for comments delimiter in string */
int ch;
int starred = 0;
int firstline = yyline;
while ((ch = rdfn()) != EOF) {
if (ch == '*') {
starred = 1;
} else if (ch == '/' && starred) {
return;
} else {
starred = 0;
}
}
yyerror1("Unexpected EOF in comment on line ");
fprintf(stderr, "%d\n", firstline);
exit(1);
}
static void
ReadCodeBlock()
{
int ch;
int firstline = yyline;
while ((ch = getchar()) != EOF) {
if (ch == '%') {
ch = getchar();
if (ch != '}') {
yyerror("bad %%");
}
return;
}
fputc(ch, outfile);
if (ch == '\n') {
yyline++;
}
if (ch == '"' || ch == '\'') {
ReadCharString(code_get, ch);
} else if (ch == '/') {
ch = getchar();
if (ch == '*') {
fputc(ch, outfile);
ReadOldComment(code_get);
continue;
} else {
ungetc(ch, stdin);
}
}
}
yyerror1("Unclosed block of C code started on line ");
fprintf(stderr, "%d\n", firstline);
exit(1);
}
static int done;
void
yyfinished()
{
done = 1;
}
int
yylex()
{
int ch;
char *ptr = buf;
if (done) return 0;
while ((ch = getchar()) != EOF) {
switch (ch) {
case ' ':
case '\f':
case '\t':
continue;
case '\n':
yyline++;
continue;
case '(':
case ')':
case ',':
case ':':
case ';':
case '=':
return(ch);
case '/':
ch = getchar();
if (ch == '*') {
ReadOldComment(simple_get);
continue;
} else {
ungetc(ch, stdin);
yyerror("illegal char /");
continue;
}
case '%':
ch = getchar();
switch (ch) {
case '%':
return (K_PPERCENT);
case '{':
ReadCodeBlock();
continue;
case 's':
case 'g':
case 't':
do {
if (ptr >= &buf[BUFSIZ]) {
yyerror("ID too long");
return(ERROR);
} else {
*ptr++ = ch;
}
ch = getchar();
} while (isalpha(ch) || isdigit(ch) || ch == '_');
ungetc(ch, stdin);
*ptr = '\0';
if (!strcmp(buf, "term")) return K_TERM;
if (!strcmp(buf, "start")) return K_START;
if (!strcmp(buf, "gram")) return K_GRAM;
yyerror("illegal character after %%");
continue;
default:
yyerror("illegal character after %%");
continue;
}
default:
if (isalpha(ch) ) {
do {
if (ptr >= &buf[BUFSIZ]) {
yyerror("ID too long");
return(ERROR);
} else {
*ptr++ = ch;
}
ch = getchar();
} while (isalpha(ch) || isdigit(ch) || ch == '_');
ungetc(ch, stdin);
*ptr = '\0';
yylval.y_string = StrCopy(buf);
return(ID);
}
if (isdigit(ch)) {
int val=0;
do {
val *= 10;
val += (ch - '0');
ch = getchar();
} while (isdigit(ch));
ungetc(ch, stdin);
yylval.y_int = val;
return(INT);
}
yyerror1("illegal char ");
fprintf(stderr, "(\\%03o)\n", ch);
exit(1);
}
}
return(0);
}
void
yyerror1(str) char *str;
{
fprintf(stderr, "line %d: %s", yyline, str);
}
void
yyerror(str) char *str;
{
yyerror1(str);
fprintf(stderr, "\n");
exit(1);
}

75
support/tools/Burg/list.c Normal file
View File

@ -0,0 +1,75 @@
char rcsid_list[] = "$Id$";
#include "b.h"
IntList
newIntList(x, next) int x; IntList next;
{
IntList l;
l = (IntList) zalloc(sizeof(*l));
assert(l);
l->x = x;
l->next = next;
return l;
}
List
newList(x, next) void *x; List next;
{
List l;
l = (List) zalloc(sizeof(*l));
assert(l);
l->x = x;
l->next = next;
return l;
}
List
appendList(x, l) void *x; List l;
{
List last;
List p;
last = 0;
for (p = l; p; p = p->next) {
last = p;
}
if (last) {
last->next = newList(x, 0);
return l;
} else {
return newList(x, 0);
}
}
void
foreachList(f, l) ListFn f; List l;
{
for (; l; l = l->next) {
(*f)(l->x);
}
}
void
reveachList(f, l) ListFn f; List l;
{
if (l) {
reveachList(f, l->next);
(*f)(l->x);
}
}
int
length(l) List l;
{
int c = 0;
for(; l; l = l->next) {
c++;
}
return c;
}

182
support/tools/Burg/main.c Normal file
View File

@ -0,0 +1,182 @@
char rcsid_main[] = "$Id$";
#include <math.h>
#include <stdio.h>
#include "b.h"
#include "fe.h"
int debugTables = 0;
static int simpleTables = 0;
static int internals = 0;
static int diagnostics = 0;
static char *inFileName;
static char *outFileName;
static char version[] = "BURG, Version 1.0";
extern void main ARGS((int argc, char **argv));
void
main(argc, argv) int argc; char **argv;
{
int i;
extern int atoi ARGS((char *));
for (i = 1; argv[i]; i++) {
char **needStr = 0;
int *needInt = 0;
if (argv[i][0] == '-') {
switch (argv[i][1]) {
case 'V':
fprintf(stderr, "%s\n", version);
break;
case 'p':
needStr = &prefix;
break;
case 'o':
needStr = &outFileName;
break;
case 'I':
internals = 1;
break;
case 'T':
simpleTables = 1;
break;
case '=':
#ifdef NOLEX
fprintf(stderr, "'%s' was not compiled to support lexicographic ordering\n", argv[0]);
#else
lexical = 1;
#endif /* NOLEX */
break;
case 'O':
needInt = &principleCost;
break;
case 'c':
needInt = &prevent_divergence;
break;
case 'e':
needInt = &exceptionTolerance;
break;
case 'd':
diagnostics = 1;
break;
case 'S':
speedflag = 1;
break;
case 't':
trimflag = 1;
break;
case 'G':
grammarflag = 1;
break;
default:
fprintf(stderr, "Bad option (%s)\n", argv[i]);
exit(1);
}
} else {
if (inFileName) {
fprintf(stderr, "Unexpected Filename (%s) after (%s)\n", argv[i], inFileName);
exit(1);
}
inFileName = argv[i];
}
if (needInt || needStr) {
char *v;
char *opt = argv[i];
if (argv[i][2]) {
v = &argv[i][2];
} else {
v = argv[++i];
if (!v) {
fprintf(stderr, "Expection argument after %s\n", opt);
exit(1);
}
}
if (needInt) {
*needInt = atoi(v);
} else if (needStr) {
*needStr = v;
}
}
}
if (inFileName) {
if(freopen(inFileName, "r", stdin)==NULL) {
fprintf(stderr, "Failed opening (%s)", inFileName);
exit(1);
}
}
if (outFileName) {
if ((outfile = fopen(outFileName, "w")) == NULL) {
fprintf(stderr, "Failed opening (%s)", outFileName);
exit(1);
}
} else {
outfile = stdout;
}
yyparse();
if (!rules) {
fprintf(stderr, "ERROR: No rules present\n");
exit(1);
}
findChainRules();
findAllPairs();
doGrammarNts();
build();
debug(debugTables, foreachList((ListFn) dumpOperator_l, operators));
debug(debugTables, printf("---final set of states ---\n"));
debug(debugTables, dumpMapping(globalMap));
startBurm();
makeNts();
if (simpleTables) {
makeSimple();
} else {
makePlanks();
}
startOptional();
makeLabel();
makeKids();
if (internals) {
makeChild();
makeOpLabel();
makeStateLabel();
}
endOptional();
makeOperatorVector();
makeNonterminals();
if (internals) {
makeOperators();
makeStringArray();
makeRuleDescArray();
makeCostArray();
makeDeltaCostArray();
makeStateStringArray();
makeNonterminalArray();
/*
makeLHSmap();
*/
}
makeClosureArray();
if (diagnostics) {
reportDiagnostics();
}
yypurge();
exit(0);
}

135
support/tools/Burg/map.c Normal file
View File

@ -0,0 +1,135 @@
char rcsid_map[] = "$Id$";
#include <stdio.h>
#include <string.h>
#include "b.h"
#include "fe.h"
Mapping globalMap;
static void growMapping ARGS((Mapping));
static int hash ARGS((Item_Set, int));
Mapping
newMapping(size) int size;
{
Mapping m;
m = (Mapping) zalloc(sizeof(struct mapping));
assert(m);
m->count = 0;
m->hash = (List*) zalloc(size * sizeof(List));
m->hash_size = size;
m->max_size = STATES_INCR;
m->set = (Item_Set*) zalloc(m->max_size * sizeof(Item_Set));
assert(m->set);
return m;
}
static void
growMapping(m) Mapping m;
{
Item_Set *tmp;
m->max_size += STATES_INCR;
tmp = (Item_Set*) zalloc(m->max_size * sizeof(Item_Set));
memcpy(tmp, m->set, m->count * sizeof(Item_Set));
zfree(m->set);
m->set = tmp;
}
static int
hash(ts, mod) Item_Set ts; int mod;
{
register Item *p = ts->virgin;
register int v;
register Relevant r = ts->relevant;
register int nt;
if (!ts->op) {
return 0;
}
v = 0;
for (; (nt = *r) != 0; r++) {
v ^= ((int)p[nt].rule) + (PRINCIPLECOST(p[nt].delta)<<4);
}
v >>= 4;
v &= (mod-1);
return v;
}
Item_Set
encode(m, ts, new) Mapping m; Item_Set ts; int *new;
{
int h;
List l;
assert(m);
assert(ts);
assert(m->count <= m->max_size);
if (grammarNts && errorState && m == globalMap) {
List l;
int found;
found = 0;
for (l = grammarNts; l; l = l->next) {
Symbol s;
s = (Symbol) l->x;
if (ts->virgin[s->u.nt->num].rule) {
found = 1;
break;
}
}
if (!found) {
*new = 0;
return errorState;
}
}
*new = 0;
h = hash(ts, m->hash_size);
for (l = m->hash[h]; l; l = l->next) {
Item_Set s = (Item_Set) l->x;
if (ts->op == s->op && equivSet(ts, s)) {
ts->num = s->num;
return s;
}
}
if (m->count >= m->max_size) {
growMapping(m);
}
assert(m->count < m->max_size);
m->set[m->count] = ts;
ts->num = m->count++;
*new = 1;
m->hash[h] = newList(ts, m->hash[h]);
return ts;
}
Item_Set
decode(m, t) Mapping m; ItemSetNum t;
{
assert(m);
assert(t);
assert(m->count < m->max_size);
assert(t < m->count);
return m->set[t];
}
void
dumpMapping(m) Mapping m;
{
int i;
printf("BEGIN Mapping: Size=%d\n", m->count);
for (i = 0; i < m->count; i++) {
dumpItem_Set(m->set[i]);
}
printf("END Mapping\n");
}

View File

@ -0,0 +1,49 @@
char rcsid_nonterminal[] = "$Id$";
#include "b.h"
#include <stdio.h>
NonTerminal start;
NonTerminalNum max_nonterminal = 1;
NonTerminalNum last_user_nonterminal;
List nonterminals;
NonTerminal
newNonTerminal(name) char *name;
{
NonTerminal nt;
nt = (NonTerminal) zalloc(sizeof(struct nonterminal));
assert(nt);
if (max_nonterminal == 1) {
start = nt;
}
nt->name = name;
nt->num = max_nonterminal++;
nonterminals = newList(nt, nonterminals);
return nt;
}
int
nonTerminalName(buf, i) char *buf; int i;
{
List l;
extern char *strcpy ARGS((char *, char *));
for (l = nonterminals; l; l = l->next) {
NonTerminal nt = (NonTerminal) l->x;
if (nt->num == i) {
strcpy(buf, nt->name);
return 1;
}
}
strcpy(buf, "(Unknown NonTerminal)");
return 0;
}
void
dumpNonTerminal(n) NonTerminal n;
{
printf("%s(%d)", n->name, n->num);
}

View File

@ -0,0 +1,48 @@
char rcsid_operator[] = "$Id$";
#include "b.h"
#include <stdio.h>
int max_arity = -1;
List operators;
List leaves;
Operator
newOperator(name, num, arity) char *name; OperatorNum num; ArityNum arity;
{
Operator op;
assert(arity <= MAX_ARITY);
op = (Operator) zalloc(sizeof(struct operator));
assert(op);
op->name = name;
op->num = num;
op->arity = arity;
operators = newList(op, operators);
return op;
}
void
dumpOperator_s(op) Operator op;
{
printf("Op: %s(%d)=%d\n", op->name, op->arity, op->num);
}
void
dumpOperator(op, full) Operator op; int full;
{
dumpOperator_s(op);
if (full) {
dumpTable(op->table, 0);
}
}
void
dumpOperator_l(op) Operator op;
{
dumpOperator(op, 1);
}

View File

@ -0,0 +1,38 @@
char rcsid_pattern[] = "$Id$";
#include <stdio.h>
#include "b.h"
Pattern
newPattern(op) Operator op;
{
Pattern p;
p = (Pattern) zalloc(sizeof(struct pattern));
p->op = op;
return p;
}
void
dumpPattern(p) Pattern p;
{
int i;
if (!p) {
printf("[no-pattern]");
return;
}
if (p->op) {
printf("%s", p->op->name);
if (p->op->arity > 0) {
printf("(");
for (i = 0; i < p->op->arity; i++) {
printf("%s ", p->children[i]->name);
}
printf(")");
}
} else {
printf("%s", p->children[0]->name);
}
}

920
support/tools/Burg/plank.c Normal file
View File

@ -0,0 +1,920 @@
char rcsid_plank[] = "$Id$";
#include <stdio.h>
#include <string.h>
#include "b.h"
#include "fe.h"
#define ERROR_VAL 0
int speedflag = 0;
Item_Set *sortedStates;
static struct stateMapTable smt;
int exceptionTolerance = 0;
static int plankSize = 32;
static Plank newPlank ARGS((void));
static PlankMap newPlankMap ARGS((int));
static StateMap newStateMap ARGS((void));
static Exception newException ARGS((int, int));
static void enterStateMap ARGS((PlankMap, short *, int, int *));
static List assemblePlanks ARGS((void));
static void assignRules ARGS((RuleAST));
static int stateCompare ARGS((Item_Set *, Item_Set *));
static int ruleCompare ARGS((RuleAST *, RuleAST *));
static void renumber ARGS((void));
static short * newVector ARGS((void));
static int width ARGS((int));
static PlankMap mapToPmap ARGS((Dimension));
static void doDimPmaps ARGS((Operator));
static void doNonTermPmaps ARGS((NonTerminal));
static void makePmaps ARGS((void));
static void outPlank ARGS((Plank));
static void purgePlanks ARGS((List));
static void inToEx ARGS((void));
static void makePlankRuleMacros ARGS((void));
static void makePlankRule ARGS((void));
static void exceptionSwitch ARGS((List, char *, char *, char *, int, char *));
static void doPlankLabel ARGS((Operator));
static void doPlankLabelSafely ARGS((Operator));
static void doPlankLabelMacrosSafely ARGS((Operator));
static void makePlankState ARGS((void));
static Plank
newPlank()
{
Plank p;
char buf[50];
static int num = 0;
p = (Plank) zalloc(sizeof(struct plank));
sprintf(buf, "%s_plank_%d", prefix, num++);
p->name = (char *) zalloc(strlen(buf)+1);
strcpy(p->name, buf);
return p;
}
static PlankMap
newPlankMap(offset) int offset;
{
PlankMap im;
im = (PlankMap) zalloc(sizeof(struct plankMap));
im->offset = offset;
return im;
}
static StateMap
newStateMap()
{
char buf[50];
static int num = 0;
StateMap sm;
sm = (StateMap) zalloc(sizeof(struct stateMap));
sprintf(buf, "f%d", num++);
sm->fieldname = (char *) zalloc(strlen(buf)+1);
strcpy(sm->fieldname, buf);
return sm;
}
static Exception
newException(index, value) int index; int value;
{
Exception e;
e = (Exception) zalloc(sizeof(struct except));
e->index = index;
e->value = value;
return e;
}
static void
enterStateMap(im, v, width, new) PlankMap im; short * v; int width; int *new;
{
int i;
StateMap sm;
List l;
int size;
assert(im);
assert(v);
assert(width > 0);
size = globalMap->count;
for (l = smt.maps; l; l = l->next) {
int ecount;
sm = (StateMap) l->x;
ecount = 0;
for (i = 0; i < size; i++) {
if (v[i] != -1 && sm->value[i] != -1 && v[i] != sm->value[i]) {
if (++ecount > exceptionTolerance) {
goto again;
}
}
}
for (i = 0; i < size; i++) {
assert(v[i] >= 0);
assert(sm->value[i] >= 0);
if (v[i] == -1) {
continue;
}
if (sm->value[i] == -1) {
sm->value[i] = v[i];
} else if (v[i] != sm->value[i]) {
im->exceptions = newList(newException(i,v[i]), im->exceptions);
}
}
im->values = sm;
if (width > sm->width) {
sm->width = width;
}
*new = 0;
return;
again: ;
}
sm = newStateMap();
im->values = sm;
sm->value = v;
sm->width = width;
*new = 1;
smt.maps = newList(sm, smt.maps);
}
static List
assemblePlanks()
{
List planks = 0;
Plank pl;
List p;
List s;
for (s = smt.maps; s; s = s->next) {
StateMap sm = (StateMap) s->x;
for (p = planks; p; p = p->next) {
pl = (Plank) p->x;
if (sm->width <= plankSize - pl->width) {
pl->width += sm->width;
pl->fields = newList(sm, pl->fields);
sm->plank = pl;
goto next;
}
}
pl = newPlank();
pl->width = sm->width;
pl->fields = newList(sm, 0);
sm->plank = pl;
planks = appendList(pl, planks);
next: ;
}
return planks;
}
RuleAST *sortedRules;
static int count;
static void
assignRules(ast) RuleAST ast;
{
sortedRules[count++] = ast;
}
static int
stateCompare(s, t) Item_Set *s; Item_Set *t;
{
return strcmp((*s)->op->name, (*t)->op->name);
}
static int
ruleCompare(s, t) RuleAST *s; RuleAST *t;
{
return strcmp((*s)->lhs, (*t)->lhs);
}
void
dumpSortedStates()
{
int i;
printf("dump Sorted States: ");
for (i = 0; i < globalMap->count; i++) {
printf("%d ", sortedStates[i]->num);
}
printf("\n");
}
void
dumpSortedRules()
{
int i;
printf("dump Sorted Rules: ");
for (i = 0; i < max_ruleAST; i++) {
printf("%d ", sortedRules[i]->rule->erulenum);
}
printf("\n");
}
static void
renumber()
{
int i;
Operator previousOp;
NonTerminal previousLHS;
int base_counter;
sortedStates = (Item_Set*) zalloc(globalMap->count * sizeof(Item_Set));
for (i = 1; i < globalMap->count; i++) {
sortedStates[i-1] = globalMap->set[i];
}
qsort(sortedStates, globalMap->count-1, sizeof(Item_Set), stateCompare);
previousOp = 0;
for (i = 0; i < globalMap->count-1; i++) {
sortedStates[i]->newNum = i;
sortedStates[i]->op->stateCount++;
if (previousOp != sortedStates[i]->op) {
sortedStates[i]->op->baseNum = i;
previousOp = sortedStates[i]->op;
}
}
sortedRules = (RuleAST*) zalloc(max_ruleAST * sizeof(RuleAST));
count = 0;
foreachList((ListFn) assignRules, ruleASTs);
qsort(sortedRules, max_ruleAST, sizeof(RuleAST), ruleCompare);
previousLHS = 0;
base_counter = 0;
for (i = 0; i < max_ruleAST; i++) {
if (previousLHS != sortedRules[i]->rule->lhs) {
sortedRules[i]->rule->lhs->baseNum = base_counter;
previousLHS = sortedRules[i]->rule->lhs;
base_counter++; /* make space for 0 */
}
sortedRules[i]->rule->newNum = base_counter;
sortedRules[i]->rule->lhs->ruleCount++;
sortedRules[i]->rule->lhs->sampleRule = sortedRules[i]->rule; /* kludge for diagnostics */
base_counter++;
}
}
static short *
newVector()
{
short *p;
p = (short *) zalloc(globalMap->count* sizeof(short));
return p;
}
static int
width(v) int v;
{
int c;
for (c = 0; v; v >>= 1) {
c++;
}
return c;
}
static PlankMap
mapToPmap(d) Dimension d;
{
PlankMap im;
short *v;
int i;
int new;
if (d->map->count == 1) {
return 0;
}
assert(d->map->count > 1);
im = newPlankMap(0);
v = newVector();
for (i = 0; i < globalMap->count-1; i++) {
int index = d->map->set[d->index_map.class[sortedStates[i]->num]->num]->num;
assert(index >= 0);
v[i+1] = index;
}
v[0] = 0;
enterStateMap(im, v, width(d->map->count), &new);
if (!new) {
zfree(v);
}
return im;
}
static void
doDimPmaps(op) Operator op;
{
int i, j;
Dimension d;
short *v;
PlankMap im;
int new;
if (!op->table->rules) {
return;
}
switch (op->arity) {
case 0:
break;
case 1:
d = op->table->dimen[0];
if (d->map->count > 1) {
v = newVector();
im = newPlankMap(op->baseNum);
for (i = 0; i < globalMap->count-1; i++) {
int index = d->map->set[d->index_map.class[sortedStates[i]->num]->num]->num;
if (index) {
Item_Set *ts = transLval(op->table, index, 0);
v[i+1] = (*ts)->newNum - op->baseNum+1;
assert(v[i+1] >= 0);
}
}
enterStateMap(im, v, width(d->map->count-1), &new);
if (!new) {
zfree(v);
}
d->pmap = im;
}
break;
case 2:
if (op->table->dimen[0]->map->count == 1 && op->table->dimen[1]->map->count == 1) {
op->table->dimen[0]->pmap = 0;
op->table->dimen[1]->pmap = 0;
} else if (op->table->dimen[0]->map->count == 1) {
v = newVector();
im = newPlankMap(op->baseNum);
d = op->table->dimen[1];
for (i = 0; i < globalMap->count-1; i++) {
int index = d->map->set[d->index_map.class[sortedStates[i]->num]->num]->num;
if (index) {
Item_Set *ts = transLval(op->table, 1, index);
v[i+1] = (*ts)->newNum - op->baseNum+1;
assert(v[i+1] >= 0);
}
}
enterStateMap(im, v, width(d->map->count-1), &new);
if (!new) {
zfree(v);
}
d->pmap = im;
} else if (op->table->dimen[1]->map->count == 1) {
v = newVector();
im = newPlankMap(op->baseNum);
d = op->table->dimen[0];
for (i = 0; i < globalMap->count-1; i++) {
int index = d->map->set[d->index_map.class[sortedStates[i]->num]->num]->num;
if (index) {
Item_Set *ts = transLval(op->table, index, 1);
v[i +1] = (*ts)->newNum - op->baseNum +1;
assert(v[i +1] >= 0);
}
}
enterStateMap(im, v, width(d->map->count-1), &new);
if (!new) {
zfree(v);
}
d->pmap = im;
} else {
op->table->dimen[0]->pmap = mapToPmap(op->table->dimen[0]);
op->table->dimen[1]->pmap = mapToPmap(op->table->dimen[1]);
/* output table */
fprintf(outfile, "static unsigned %s %s_%s_transition[%d][%d] = {",
op->stateCount <= 255 ? "char" : "short",
prefix,
op->name,
op->table->dimen[0]->map->count,
op->table->dimen[1]->map->count);
for (i = 0; i < op->table->dimen[0]->map->count; i++) {
if (i > 0) {
fprintf(outfile, ",");
}
fprintf(outfile, "\n{");
for (j = 0; j < op->table->dimen[1]->map->count; j++) {
Item_Set *ts = transLval(op->table, i, j);
short diff;
if (j > 0) {
fprintf(outfile, ",");
if (j % 10 == 0) {
fprintf(outfile, "\t/* row %d, cols %d-%d*/\n",
i,
j-10,
j-1);
}
}
if ((*ts)->num > 0) {
diff = (*ts)->newNum - op->baseNum +1;
} else {
diff = 0;
}
fprintf(outfile, "%5d", diff);
}
fprintf(outfile, "}\t/* row %d */", i);
}
fprintf(outfile, "\n};\n");
}
break;
default:
assert(0);
}
}
static NonTerminal *ntVector;
static void
doNonTermPmaps(n) NonTerminal n;
{
short *v;
PlankMap im;
int new;
int i;
ntVector[n->num] = n;
if (n->num >= last_user_nonterminal) {
return;
}
if (n->ruleCount <= 0) {
return;
}
im = newPlankMap(n->baseNum);
v = newVector();
for (i = 0; i < globalMap->count-1; i++) {
Rule r = globalMap->set[sortedStates[i]->num]->closed[n->num].rule;
if (r) {
r->used = 1;
v[i+1] = r->newNum - n->baseNum /*safely*/;
assert(v[i+1] >= 0);
}
}
enterStateMap(im, v, width(n->ruleCount+1), &new);
if (!new) {
zfree(v);
}
n->pmap = im;
}
static void
makePmaps()
{
foreachList((ListFn) doDimPmaps, operators);
ntVector = (NonTerminal*) zalloc((max_nonterminal) * sizeof(NonTerminal));
foreachList((ListFn) doNonTermPmaps, nonterminals);
}
static void
outPlank(p) Plank p;
{
List f;
int i;
fprintf(outfile, "static struct {\n");
for (f = p->fields; f; f = f->next) {
StateMap sm = (StateMap) f->x;
fprintf(outfile, "\tunsigned int %s:%d;\n", sm->fieldname, sm->width);
}
fprintf(outfile, "} %s[] = {\n", p->name);
for (i = 0; i < globalMap->count; i++) {
fprintf(outfile, "\t{");
for (f = p->fields; f; f = f->next) {
StateMap sm = (StateMap) f->x;
fprintf(outfile, "%4d,", sm->value[i] == -1 ? ERROR_VAL : sm->value[i]);
}
fprintf(outfile, "},\t/* row %d */\n", i);
}
fprintf(outfile, "};\n");
}
static void
purgePlanks(planks) List planks;
{
List p;
for (p = planks; p; p = p->next) {
Plank x = (Plank) p->x;
outPlank(x);
}
}
static void
inToEx()
{
int i;
int counter;
fprintf(outfile, "static short %s_eruleMap[] = {\n", prefix);
counter = 0;
for (i = 0; i < max_ruleAST; i++) {
if (counter > 0) {
fprintf(outfile, ",");
if (counter % 10 == 0) {
fprintf(outfile, "\t/* %d-%d */\n", counter-10, counter-1);
}
}
if (counter < sortedRules[i]->rule->newNum) {
assert(counter == sortedRules[i]->rule->newNum-1);
fprintf(outfile, "%5d", 0);
counter++;
if (counter > 0) {
fprintf(outfile, ",");
if (counter % 10 == 0) {
fprintf(outfile, "\t/* %d-%d */\n", counter-10, counter-1);
}
}
}
fprintf(outfile, "%5d", sortedRules[i]->rule->erulenum);
counter++;
}
fprintf(outfile, "\n};\n");
}
static void
makePlankRuleMacros()
{
int i;
for (i = 1; i < last_user_nonterminal; i++) {
List es;
PlankMap im = ntVector[i]->pmap;
fprintf(outfile, "#define %s_%s_rule(state)\t", prefix, ntVector[i]->name);
if (im) {
fprintf(outfile, "%s_eruleMap[", prefix);
for (es = im->exceptions; es; es = es->next) {
Exception e = (Exception) es->x;
fprintf(outfile, "((state) == %d ? %d :",
e->index, e->value);
}
fprintf(outfile, "%s[state].%s",
im->values->plank->name,
im->values->fieldname);
for (es = im->exceptions; es; es = es->next) {
fprintf(outfile, ")");
}
fprintf(outfile, " +%d]", im->offset);
} else {
/* nonterminal never appears on LHS. */
assert(ntVector[i] == start);
fprintf(outfile, "0");
}
fprintf(outfile, "\n");
}
fprintf(outfile, "\n");
}
static void
makePlankRule()
{
int i;
makePlankRuleMacros();
fprintf(outfile, "#ifdef __STDC__\n");
fprintf(outfile, "int %s_rule(int state, int goalnt) {\n", prefix);
fprintf(outfile, "#else\n");
fprintf(outfile, "int %s_rule(state, goalnt) int state; int goalnt; {\n", prefix);
fprintf(outfile, "#endif\n");
fprintf(outfile,
"\t%s_assert(state >= 0 && state < %d, %s_PANIC(\"Bad state %%d passed to %s_rule\\n\", state));\n",
prefix, globalMap->count, prefix, prefix);
fprintf(outfile, "\tswitch(goalnt) {\n");
for (i = 1; i < last_user_nonterminal; i++) {
fprintf(outfile, "\tcase %d:\n", i);
fprintf(outfile, "\t\treturn %s_%s_rule(state);\n", prefix, ntVector[i]->name);
}
fprintf(outfile, "\tdefault:\n");
fprintf(outfile, "\t\t%s_PANIC(\"Unknown nonterminal %%d in %s_rule;\\n\", goalnt);\n", prefix, prefix);
fprintf(outfile, "\t\tabort();\n");
fprintf(outfile, "\t\treturn 0;\n");
fprintf(outfile, "\t}\n");
fprintf(outfile, "}\n");
}
static void
exceptionSwitch(es, sw, pre, post, offset, def) List es; char *sw; char *pre; char *post; int offset; char *def;
{
if (es) {
fprintf(outfile, "\t\tswitch (%s) {\n", sw);
for (; es; es = es->next) {
Exception e = (Exception) es->x;
fprintf(outfile, "\t\tcase %d: %s %d; %s\n", e->index, pre, e->value+offset, post);
}
if (def) {
fprintf(outfile, "\t\tdefault: %s;\n", def);
}
fprintf(outfile, "\t\t}\n");
} else {
if (def) {
fprintf(outfile, "\t\t%s;\n", def);
}
}
}
static void
doPlankLabel(op) Operator op;
{
PlankMap im0;
PlankMap im1;
char buf[100];
fprintf(outfile, "\tcase %d:\n", op->num);
switch (op->arity) {
case 0:
fprintf(outfile, "\t\treturn %d;\n", op->table->transition[0]->newNum);
break;
case 1:
im0 = op->table->dimen[0]->pmap;
if (im0) {
exceptionSwitch(im0->exceptions, "l", "return ", "", im0->offset, 0);
fprintf(outfile, "\t\treturn %s[l].%s + %d;\n",
im0->values->plank->name, im0->values->fieldname, im0->offset);
} else {
Item_Set *ts = transLval(op->table, 1, 0);
if (*ts) {
fprintf(outfile, "\t\treturn %d;\n", (*ts)->newNum);
} else {
fprintf(outfile, "\t\treturn %d;\n", ERROR_VAL);
}
}
break;
case 2:
im0 = op->table->dimen[0]->pmap;
im1 = op->table->dimen[1]->pmap;
if (!im0 && !im1) {
Item_Set *ts = transLval(op->table, 1, 1);
if (*ts) {
fprintf(outfile, "\t\treturn %d;\n", (*ts)->newNum);
} else {
fprintf(outfile, "\t\treturn %d;\n", ERROR_VAL);
}
} else if (!im0) {
exceptionSwitch(im1->exceptions, "r", "return ", "", im1->offset, 0);
fprintf(outfile, "\t\treturn %s[r].%s + %d;\n",
im1->values->plank->name, im1->values->fieldname, im1->offset);
} else if (!im1) {
exceptionSwitch(im0->exceptions, "l", "return ", "", im0->offset, 0);
fprintf(outfile, "\t\treturn %s[l].%s + %d;\n",
im0->values->plank->name, im0->values->fieldname, im0->offset);
} else {
assert(im0->offset == 0);
assert(im1->offset == 0);
sprintf(buf, "l = %s[l].%s",
im0->values->plank->name, im0->values->fieldname);
exceptionSwitch(im0->exceptions, "l", "l =", "break;", 0, buf);
sprintf(buf, "r = %s[r].%s",
im1->values->plank->name, im1->values->fieldname);
exceptionSwitch(im1->exceptions, "r", "r =", "break;", 0, buf);
fprintf(outfile, "\t\treturn %s_%s_transition[l][r] + %d;\n",
prefix,
op->name,
op->baseNum);
}
break;
default:
assert(0);
}
}
static void
doPlankLabelMacrosSafely(op) Operator op;
{
PlankMap im0;
PlankMap im1;
switch (op->arity) {
case -1:
fprintf(outfile, "#define %s_%s_state\t0\n", prefix, op->name);
break;
case 0:
fprintf(outfile, "#define %s_%s_state", prefix, op->name);
fprintf(outfile, "\t%d\n", op->table->transition[0]->newNum+1);
break;
case 1:
fprintf(outfile, "#define %s_%s_state(l)", prefix, op->name);
im0 = op->table->dimen[0]->pmap;
if (im0) {
if (im0->exceptions) {
List es = im0->exceptions;
assert(0);
fprintf(outfile, "\t\tswitch (l) {\n");
for (; es; es = es->next) {
Exception e = (Exception) es->x;
fprintf(outfile, "\t\tcase %d: return %d;\n", e->index, e->value ? e->value+im0->offset : 0);
}
fprintf(outfile, "\t\t}\n");
}
if (speedflag) {
fprintf(outfile, "\t( %s[l].%s + %d )\n",
im0->values->plank->name, im0->values->fieldname,
im0->offset);
} else {
fprintf(outfile, "\t( (%s_TEMP = %s[l].%s) ? %s_TEMP + %d : 0 )\n",
prefix,
im0->values->plank->name, im0->values->fieldname,
prefix,
im0->offset);
}
} else {
Item_Set *ts = transLval(op->table, 1, 0);
if (*ts) {
fprintf(outfile, "\t%d\n", (*ts)->newNum+1);
} else {
fprintf(outfile, "\t%d\n", 0);
}
}
break;
case 2:
fprintf(outfile, "#define %s_%s_state(l,r)", prefix, op->name);
im0 = op->table->dimen[0]->pmap;
im1 = op->table->dimen[1]->pmap;
if (!im0 && !im1) {
Item_Set *ts = transLval(op->table, 1, 1);
assert(0);
if (*ts) {
fprintf(outfile, "\t\treturn %d;\n", (*ts)->newNum+1);
} else {
fprintf(outfile, "\t\treturn %d;\n", 0);
}
} else if (!im0) {
assert(0);
if (im1->exceptions) {
List es = im1->exceptions;
fprintf(outfile, "\t\tswitch (r) {\n");
for (; es; es = es->next) {
Exception e = (Exception) es->x;
fprintf(outfile, "\t\tcase %d: return %d;\n", e->index, e->value ? e->value+im1->offset : 0);
}
fprintf(outfile, "\t\t}\n");
}
fprintf(outfile, "\t\tstate = %s[r].%s; offset = %d;\n",
im1->values->plank->name, im1->values->fieldname, im1->offset);
fprintf(outfile, "\t\tbreak;\n");
} else if (!im1) {
assert(0);
if (im0->exceptions) {
List es = im0->exceptions;
fprintf(outfile, "\t\tswitch (l) {\n");
for (; es; es = es->next) {
Exception e = (Exception) es->x;
fprintf(outfile, "\t\tcase %d: return %d;\n", e->index, e->value ? e->value+im0->offset : 0);
}
fprintf(outfile, "\t\t}\n");
}
fprintf(outfile, "\t\tstate = %s[l].%s; offset = %d;\n",
im0->values->plank->name, im0->values->fieldname, im0->offset);
fprintf(outfile, "\t\tbreak;\n");
} else {
assert(im0->offset == 0);
assert(im1->offset == 0);
/*
sprintf(buf, "l = %s[l].%s",
im0->values->plank->name, im0->values->fieldname);
exceptionSwitch(im0->exceptions, "l", "l =", "break;", 0, buf);
sprintf(buf, "r = %s[r].%s",
im1->values->plank->name, im1->values->fieldname);
exceptionSwitch(im1->exceptions, "r", "r =", "break;", 0, buf);
fprintf(outfile, "\t\tstate = %s_%s_transition[l][r]; offset = %d;\n",
prefix,
op->name,
op->baseNum);
fprintf(outfile, "\t\tbreak;\n");
*/
if (speedflag) {
fprintf(outfile, "\t( %s_%s_transition[%s[l].%s][%s[r].%s] + %d)\n",
prefix,
op->name,
im0->values->plank->name, im0->values->fieldname,
im1->values->plank->name, im1->values->fieldname,
op->baseNum);
} else {
fprintf(outfile, "\t( (%s_TEMP = %s_%s_transition[%s[l].%s][%s[r].%s]) ? ",
prefix,
prefix,
op->name,
im0->values->plank->name, im0->values->fieldname,
im1->values->plank->name, im1->values->fieldname);
fprintf(outfile, "%s_TEMP + %d : 0 )\n",
prefix,
op->baseNum);
}
}
break;
default:
assert(0);
}
}
static void
doPlankLabelSafely(op) Operator op;
{
fprintf(outfile, "\tcase %d:\n", op->num);
switch (op->arity) {
case -1:
fprintf(outfile, "\t\treturn 0;\n");
break;
case 0:
fprintf(outfile, "\t\treturn %s_%s_state;\n", prefix, op->name);
break;
case 1:
fprintf(outfile, "\t\treturn %s_%s_state(l);\n", prefix, op->name);
break;
case 2:
fprintf(outfile, "\t\treturn %s_%s_state(l,r);\n", prefix, op->name);
break;
default:
assert(0);
}
}
static void
makePlankState()
{
fprintf(outfile, "\n");
fprintf(outfile, "int %s_TEMP;\n", prefix);
foreachList((ListFn) doPlankLabelMacrosSafely, operators);
fprintf(outfile, "\n");
fprintf(outfile, "#ifdef __STDC__\n");
switch (max_arity) {
case -1:
fprintf(stderr, "ERROR: no terminals in grammar.\n");
exit(1);
case 0:
fprintf(outfile, "int %s_state(int op) {\n", prefix);
fprintf(outfile, "#else\n");
fprintf(outfile, "int %s_state(op) int op; {\n", prefix);
break;
case 1:
fprintf(outfile, "int %s_state(int op, int l) {\n", prefix);
fprintf(outfile, "#else\n");
fprintf(outfile, "int %s_state(op, l) int op; int l; {\n", prefix);
break;
case 2:
fprintf(outfile, "int %s_state(int op, int l, int r) {\n", prefix);
fprintf(outfile, "#else\n");
fprintf(outfile, "int %s_state(op, l, r) int op; int l; int r; {\n", prefix);
break;
default:
assert(0);
}
fprintf(outfile, "#endif\n");
fprintf(outfile, "\tregister int %s_TEMP;\n", prefix);
fprintf(outfile, "#ifndef NDEBUG\n");
fprintf(outfile, "\tswitch (op) {\n");
opsOfArity(2);
if (max_arity >= 2) {
fprintf(outfile,
"\t\t%s_assert(r >= 0 && r < %d, %s_PANIC(\"Bad state %%d passed to %s_state\\n\", r));\n",
prefix, globalMap->count, prefix, prefix);
fprintf(outfile, "\t\t/*FALLTHROUGH*/\n");
}
opsOfArity(1);
if (max_arity > 1) {
fprintf(outfile,
"\t\t%s_assert(l >= 0 && l < %d, %s_PANIC(\"Bad state %%d passed to %s_state\\n\", l));\n",
prefix, globalMap->count, prefix, prefix);
fprintf(outfile, "\t\t/*FALLTHROUGH*/\n");
}
opsOfArity(0);
fprintf(outfile, "\t\tbreak;\n");
fprintf(outfile, "\t}\n");
fprintf(outfile, "#endif\n");
fprintf(outfile, "\tswitch (op) {\n");
fprintf(outfile,"\tdefault: %s_PANIC(\"Unknown op %%d in %s_state\\n\", op); abort(); return 0;\n",
prefix, prefix);
foreachList((ListFn) doPlankLabelSafely, operators);
fprintf(outfile, "\t}\n");
fprintf(outfile, "}\n");
}
void
makePlanks()
{
List planks;
renumber();
makePmaps();
planks = assemblePlanks();
purgePlanks(planks);
inToEx();
makePlankRule();
makePlankState();
}

View File

@ -0,0 +1,64 @@
char rcsid_queue[] = "$Id$";
#include "b.h"
#include <stdio.h>
Queue globalQ;
Queue
newQ()
{
Queue q;
q = (Queue) zalloc(sizeof(struct queue));
assert(q);
q->head = 0;
q->tail = 0;
return q;
}
void
addQ(q, ts) Queue q; Item_Set ts;
{
List qe;
assert(q);
assert(ts);
qe = newList(ts, 0);
if (q->head) {
assert(q->tail);
q->tail->next = qe;
q->tail = qe;
} else {
q->head = q->tail = qe;
}
}
Item_Set
popQ(q) Queue q;
{
List qe;
Item_Set ts;
assert(q);
if (q->head) {
qe = q->head;
q->head = q->head->next;
ts = (Item_Set) qe->x;
zfree(qe);
return ts;
} else {
return 0;
}
}
void
dumpQ(q) Queue q;
{
printf("Begin Queue\n");
foreachList((ListFn)dumpItem_Set, q->head);
printf("End Queue\n");
}

49
support/tools/Burg/rule.c Normal file
View File

@ -0,0 +1,49 @@
char rcsid_rule[] = "$Id$";
#include "b.h"
#include <stdio.h>
RuleNum max_rule;
int max_erule_num;
struct rule stub_rule;
List rules;
Rule
newRule(delta, erulenum, lhs, pat) DeltaPtr delta; ERuleNum erulenum; NonTerminal lhs; Pattern pat;
{
Rule p;
p = (Rule) zalloc(sizeof(struct rule));
assert(p);
ASSIGNCOST(p->delta, delta);
p->erulenum = erulenum;
if (erulenum > max_erule_num) {
max_erule_num = erulenum;
}
p->num = max_rule++;
p->lhs = lhs;
p->pat = pat;
rules = newList(p, rules);
return p;
}
void
dumpRule(p) Rule p;
{
dumpNonTerminal(p->lhs);
printf(" : ");
dumpPattern(p->pat);
printf(" ");
dumpCost(p->delta);
printf("\n");
}
void
dumpRuleList(l) List l;
{
foreachList((ListFn)dumpRule, l);
}

View File

@ -0,0 +1,150 @@
%{
#include <stdio.h>
typedef struct node *NODEPTR_TYPE;
struct node {
int op, state_label;
NODEPTR_TYPE left, right;
};
#define OP_LABEL(p) ((p)->op)
#define STATE_LABEL(p) ((p)->state_label)
#define LEFT_CHILD(p) ((p)->left)
#define RIGHT_CHILD(p) ((p)->right)
#define PANIC printf
%}
%start reg
%term Assign=1 Constant=2 Fetch=3 Four=4 Mul=5 Plus=6
%%
con: Constant = 1 (0);
con: Four = 2 (0);
addr: con = 3 (0);
addr: Plus(con,reg) = 4 (0);
addr: Plus(con,Mul(Four,reg)) = 5 (0);
reg: Fetch(addr) = 6 (1);
reg: Assign(addr,reg) = 7 (1);
%%
#define Assign 1
#define Constant 2
#define Fetch 3
#define Four 4
#define Mul 5
#define Plus 6
#ifdef __STDC__
#define ARGS(x) x
#else
#define ARGS(x) ()
#endif
NODEPTR_TYPE buildtree ARGS((int, NODEPTR_TYPE, NODEPTR_TYPE));
void printcover ARGS((NODEPTR_TYPE, int, int));
void printtree ARGS((NODEPTR_TYPE));
int treecost ARGS((NODEPTR_TYPE, int, int));
void printMatches ARGS((NODEPTR_TYPE));
int main ARGS((void));
NODEPTR_TYPE buildtree(op, left, right) int op; NODEPTR_TYPE left; NODEPTR_TYPE right; {
NODEPTR_TYPE p;
extern void *malloc ARGS((unsigned));
p = (NODEPTR_TYPE) malloc(sizeof *p);
p->op = op;
p->left = left;
p->right = right;
return p;
}
void printcover(p, goalnt, indent) NODEPTR_TYPE p; int goalnt; int indent; {
int eruleno = burm_rule(STATE_LABEL(p), goalnt);
short *nts = burm_nts[eruleno];
NODEPTR_TYPE kids[10];
int i;
if (eruleno == 0) {
printf("no cover\n");
return;
}
for (i = 0; i < indent; i++)
printf(".");
printf("%s\n", burm_string[eruleno]);
burm_kids(p, eruleno, kids);
for (i = 0; nts[i]; i++)
printcover(kids[i], nts[i], indent+1);
}
void printtree(p) NODEPTR_TYPE p; {
int op = burm_op_label(p);
printf("%s", burm_opname[op]);
switch (burm_arity[op]) {
case 0:
break;
case 1:
printf("(");
printtree(burm_child(p, 0));
printf(")");
break;
case 2:
printf("(");
printtree(burm_child(p, 0));
printf(", ");
printtree(burm_child(p, 1));
printf(")");
break;
}
}
int treecost(p, goalnt, costindex) NODEPTR_TYPE p; int goalnt; int costindex; {
int eruleno = burm_rule(STATE_LABEL(p), goalnt);
int cost = burm_cost[eruleno][costindex], i;
short *nts = burm_nts[eruleno];
NODEPTR_TYPE kids[10];
burm_kids(p, eruleno, kids);
for (i = 0; nts[i]; i++)
cost += treecost(kids[i], nts[i], costindex);
return cost;
}
void printMatches(p) NODEPTR_TYPE p; {
int nt;
int eruleno;
printf("Node 0x%lx= ", (unsigned long)p);
printtree(p);
printf(" matched rules:\n");
for (nt = 1; burm_ntname[nt] != (char*)NULL; nt++)
if ((eruleno = burm_rule(STATE_LABEL(p), nt)) != 0)
printf("\t%s\n", burm_string[eruleno]);
}
main() {
NODEPTR_TYPE p;
p = buildtree(Assign,
buildtree(Constant, 0, 0),
buildtree(Fetch,
buildtree(Plus,
buildtree(Constant, 0, 0),
buildtree(Mul,
buildtree(Four, 0, 0),
buildtree(Fetch, buildtree(Constant, 0, 0), 0)
)
),
0
)
);
printtree(p);
printf("\n\n");
burm_label(p);
printcover(p, 1, 0);
printf("\nCover cost == %d\n\n", treecost(p, 1, 0));
printMatches(p);
return 0;
}

View File

@ -0,0 +1,65 @@
char rcsid_string[] = "$Id$";
#include <stdio.h>
#include <string.h>
#include "b.h"
#include "fe.h"
static StrTableElement newStrTableElement ARGS((void));
StrTable
newStrTable()
{
return (StrTable) zalloc(sizeof(struct strTable));
}
static StrTableElement
newStrTableElement()
{
return (StrTableElement) zalloc(sizeof(struct strTableElement));
}
void
dumpStrTable(t) StrTable t;
{
List e;
IntList r;
printf("Begin StrTable\n");
for (e = t->elems; e; e = e->next) {
StrTableElement el = (StrTableElement) e->x;
printf("%s: ", el->str);
for (r = el->erulenos; r; r = r->next) {
int i = r->x;
printf("(%d)", i);
}
printf("\n");
}
printf("End StrTable\n");
}
StrTableElement
addString(t, s, eruleno, new) StrTable t; char *s; int eruleno; int *new;
{
List l;
StrTableElement ste;
assert(t);
for (l = t->elems; l; l = l->next) {
StrTableElement e = (StrTableElement) l->x;
assert(e);
if (!strcmp(s, e->str)) {
e->erulenos = newIntList(eruleno, e->erulenos);
*new = 0;
return e;
}
}
ste = newStrTableElement();
ste->erulenos = newIntList(eruleno, 0);
ste->str = (char *) zalloc(strlen(s) + 1);
strcpy(ste->str, s);
t->elems = newList(ste, t->elems);
*new = 1;
return ste;
}

View File

@ -0,0 +1,38 @@
char rcsid_symtab[] = "$Id$";
#include <stdio.h>
#include <string.h>
#include "b.h"
#include "fe.h"
static List symtab;
Symbol
newSymbol(name) char *name;
{
Symbol s;
s = (Symbol) zalloc(sizeof(struct symbol));
assert(s);
s->name = name;
return s;
}
Symbol
enter(name, new) char *name; int *new;
{
List l;
Symbol s;
*new = 0;
for (l = symtab; l; l = l->next) {
s = (Symbol) l->x;
if (!strcmp(name, s->name)) {
return s;
}
}
*new = 1;
s = newSymbol(name);
symtab = newList(s, symtab);
return s;
}

552
support/tools/Burg/table.c Normal file
View File

@ -0,0 +1,552 @@
char rcsid_table[] = "$Id$";
#include "b.h"
#include <string.h>
#include <stdio.h>
static void growIndex_Map ARGS((Index_Map *));
static Relevant newRelevant ARGS((void));
static Dimension newDimension ARGS((Operator, int));
static void GT_1 ARGS((Table));
static void GT_2_0 ARGS((Table));
static void GT_2_1 ARGS((Table));
static void growTransition ARGS((Table, int));
static Item_Set restrict ARGS((Dimension, Item_Set));
static void addHP_1 ARGS((Table, Item_Set));
static void addHP_2_0 ARGS((Table, Item_Set));
static void addHP_2_1 ARGS((Table, Item_Set));
static void addHyperPlane ARGS((Table, int, Item_Set));
static void
growIndex_Map(r) Index_Map *r;
{
Index_Map new;
new.max_size = r->max_size + STATES_INCR;
new.class = (Item_Set*) zalloc(new.max_size * sizeof(Item_Set));
assert(new.class);
memcpy(new.class, r->class, r->max_size * sizeof(Item_Set));
zfree(r->class);
*r = new;
}
static Relevant
newRelevant()
{
Relevant r = (Relevant) zalloc(max_nonterminal * sizeof(*r));
return r;
}
void
addRelevant(r, nt) Relevant r; NonTerminalNum nt;
{
int i;
for (i = 0; r[i]; i++) {
if (r[i] == nt) {
break;
}
}
if (!r[i]) {
r[i] = nt;
}
}
static Dimension
newDimension(op, index) Operator op; ArityNum index;
{
Dimension d;
List pl;
Relevant r;
assert(op);
assert(index >= 0 && index < op->arity);
d = (Dimension) zalloc(sizeof(struct dimension));
assert(d);
r = d->relevant = newRelevant();
for (pl = rules; pl; pl = pl->next) {
Rule pr = (Rule) pl->x;
if (pr->pat->op == op) {
addRelevant(r, pr->pat->children[index]->num);
}
}
d->index_map.max_size = STATES_INCR;
d->index_map.class = (Item_Set*)
zalloc(d->index_map.max_size * sizeof(Item_Set));
d->map = newMapping(DIM_MAP_SIZE);
d->max_size = TABLE_INCR;
return d;
}
Table
newTable(op) Operator op;
{
Table t;
int i, size;
assert(op);
t = (Table) zalloc(sizeof(struct table));
assert(t);
t->op = op;
for (i = 0; i < op->arity; i++) {
t->dimen[i] = newDimension(op, i);
}
size = 1;
for (i = 0; i < op->arity; i++) {
size *= t->dimen[i]->max_size;
}
t->transition = (Item_Set*) zalloc(size * sizeof(Item_Set));
t->relevant = newRelevant();
assert(t->transition);
return t;
}
static void
GT_1(t) Table t;
{
Item_Set *ts;
ItemSetNum oldsize = t->dimen[0]->max_size;
ItemSetNum newsize = t->dimen[0]->max_size + TABLE_INCR;
t->dimen[0]->max_size = newsize;
ts = (Item_Set*) zalloc(newsize * sizeof(Item_Set));
assert(ts);
memcpy(ts, t->transition, oldsize * sizeof(Item_Set));
zfree(t->transition);
t->transition = ts;
}
static void
GT_2_0(t) Table t;
{
Item_Set *ts;
ItemSetNum oldsize = t->dimen[0]->max_size;
ItemSetNum newsize = t->dimen[0]->max_size + TABLE_INCR;
int size;
t->dimen[0]->max_size = newsize;
size = newsize * t->dimen[1]->max_size;
ts = (Item_Set*) zalloc(size * sizeof(Item_Set));
assert(ts);
memcpy(ts, t->transition, oldsize*t->dimen[1]->max_size * sizeof(Item_Set));
zfree(t->transition);
t->transition = ts;
}
static void
GT_2_1(t) Table t;
{
Item_Set *ts;
ItemSetNum oldsize = t->dimen[1]->max_size;
ItemSetNum newsize = t->dimen[1]->max_size + TABLE_INCR;
int size;
Item_Set *from;
Item_Set *to;
int i1, i2;
t->dimen[1]->max_size = newsize;
size = newsize * t->dimen[0]->max_size;
ts = (Item_Set*) zalloc(size * sizeof(Item_Set));
assert(ts);
from = t->transition;
to = ts;
for (i1 = 0; i1 < t->dimen[0]->max_size; i1++) {
for (i2 = 0; i2 < oldsize; i2++) {
to[i2] = from[i2];
}
to += newsize;
from += oldsize;
}
zfree(t->transition);
t->transition = ts;
}
static void
growTransition(t, dim) Table t; ArityNum dim;
{
assert(t);
assert(t->op);
assert(dim < t->op->arity);
switch (t->op->arity) {
default:
assert(0);
break;
case 1:
GT_1(t);
return;
case 2:
switch (dim) {
default:
assert(0);
break;
case 0:
GT_2_0(t);
return;
case 1:
GT_2_1(t);
return;
}
}
}
static Item_Set
restrict(d, ts) Dimension d; Item_Set ts;
{
DeltaCost base;
Item_Set r;
int found;
register Relevant r_ptr = d->relevant;
register Item *ts_current = ts->closed;
register Item *r_current;
register int i;
register int nt;
ZEROCOST(base);
found = 0;
r = newItem_Set(d->relevant);
r_current = r->virgin;
for (i = 0; (nt = r_ptr[i]) != 0; i++) {
if (ts_current[nt].rule) {
r_current[nt].rule = &stub_rule;
if (!found) {
found = 1;
ASSIGNCOST(base, ts_current[nt].delta);
} else {
if (LESSCOST(ts_current[nt].delta, base)) {
ASSIGNCOST(base, ts_current[nt].delta);
}
}
}
}
/* zero align */
for (i = 0; (nt = r_ptr[i]) != 0; i++) {
if (r_current[nt].rule) {
ASSIGNCOST(r_current[nt].delta, ts_current[nt].delta);
MINUSCOST(r_current[nt].delta, base);
}
}
assert(!r->closed);
r->representative = ts;
return r;
}
static void
addHP_1(t, ts) Table t; Item_Set ts;
{
List pl;
Item_Set e;
Item_Set tmp;
int new;
e = newItem_Set(t->relevant);
assert(e);
e->kids[0] = ts->representative;
for (pl = t->rules; pl; pl = pl->next) {
Rule p = (Rule) pl->x;
if (t->op == p->pat->op && ts->virgin[p->pat->children[0]->num].rule) {
DeltaCost dc;
ASSIGNCOST(dc, ts->virgin[p->pat->children[0]->num].delta);
ADDCOST(dc, p->delta);
if (!e->virgin[p->lhs->num].rule || LESSCOST(dc, e->virgin[p->lhs->num].delta)) {
e->virgin[p->lhs->num].rule = p;
ASSIGNCOST(e->virgin[p->lhs->num].delta, dc);
e->op = t->op;
}
}
}
trim(e);
zero(e);
tmp = encode(globalMap, e, &new);
assert(ts->num < t->dimen[0]->map->max_size);
t->transition[ts->num] = tmp;
if (new) {
closure(e);
addQ(globalQ, tmp);
} else {
freeItem_Set(e);
}
}
static void
addHP_2_0(t, ts) Table t; Item_Set ts;
{
List pl;
register Item_Set e;
Item_Set tmp;
int new;
int i2;
assert(t->dimen[1]->map->count <= t->dimen[1]->map->max_size);
for (i2 = 0; i2 < t->dimen[1]->map->count; i2++) {
e = newItem_Set(t->relevant);
assert(e);
e->kids[0] = ts->representative;
e->kids[1] = t->dimen[1]->map->set[i2]->representative;
for (pl = t->rules; pl; pl = pl->next) {
register Rule p = (Rule) pl->x;
if (t->op == p->pat->op
&& ts->virgin[p->pat->children[0]->num].rule
&& t->dimen[1]->map->set[i2]->virgin[p->pat->children[1]->num].rule){
DeltaCost dc;
ASSIGNCOST(dc, p->delta);
ADDCOST(dc, ts->virgin[p->pat->children[0]->num].delta);
ADDCOST(dc, t->dimen[1]->map->set[i2]->virgin[p->pat->children[1]->num].delta);
if (!e->virgin[p->lhs->num].rule || LESSCOST(dc, e->virgin[p->lhs->num].delta)) {
e->virgin[p->lhs->num].rule = p;
ASSIGNCOST(e->virgin[p->lhs->num].delta, dc);
e->op = t->op;
}
}
}
trim(e);
zero(e);
tmp = encode(globalMap, e, &new);
assert(ts->num < t->dimen[0]->map->max_size);
t->transition[ts->num * t->dimen[1]->max_size + i2] = tmp;
if (new) {
closure(e);
addQ(globalQ, tmp);
} else {
freeItem_Set(e);
}
}
}
static void
addHP_2_1(t, ts) Table t; Item_Set ts;
{
List pl;
register Item_Set e;
Item_Set tmp;
int new;
int i1;
assert(t->dimen[0]->map->count <= t->dimen[0]->map->max_size);
for (i1 = 0; i1 < t->dimen[0]->map->count; i1++) {
e = newItem_Set(t->relevant);
assert(e);
e->kids[0] = t->dimen[0]->map->set[i1]->representative;
e->kids[1] = ts->representative;
for (pl = t->rules; pl; pl = pl->next) {
register Rule p = (Rule) pl->x;
if (t->op == p->pat->op
&& ts->virgin[p->pat->children[1]->num].rule
&& t->dimen[0]->map->set[i1]->virgin[p->pat->children[0]->num].rule){
DeltaCost dc;
ASSIGNCOST(dc, p->delta );
ADDCOST(dc, ts->virgin[p->pat->children[1]->num].delta);
ADDCOST(dc, t->dimen[0]->map->set[i1]->virgin[p->pat->children[0]->num].delta);
if (!e->virgin[p->lhs->num].rule || LESSCOST(dc, e->virgin[p->lhs->num].delta)) {
e->virgin[p->lhs->num].rule = p;
ASSIGNCOST(e->virgin[p->lhs->num].delta, dc);
e->op = t->op;
}
}
}
trim(e);
zero(e);
tmp = encode(globalMap, e, &new);
assert(ts->num < t->dimen[1]->map->max_size);
t->transition[i1 * t->dimen[1]->max_size + ts->num] = tmp;
if (new) {
closure(e);
addQ(globalQ, tmp);
} else {
freeItem_Set(e);
}
}
}
static void
addHyperPlane(t, i, ts) Table t; ArityNum i; Item_Set ts;
{
switch (t->op->arity) {
default:
assert(0);
break;
case 1:
addHP_1(t, ts);
return;
case 2:
switch (i) {
default:
assert(0);
break;
case 0:
addHP_2_0(t, ts);
return;
case 1:
addHP_2_1(t, ts);
return;
}
}
}
void
addToTable(t, ts) Table t; Item_Set ts;
{
ArityNum i;
assert(t);
assert(ts);
assert(t->op);
for (i = 0; i < t->op->arity; i++) {
Item_Set r;
Item_Set tmp;
int new;
r = restrict(t->dimen[i], ts);
tmp = encode(t->dimen[i]->map, r, &new);
if (t->dimen[i]->index_map.max_size <= ts->num) {
growIndex_Map(&t->dimen[i]->index_map);
}
assert(ts->num < t->dimen[i]->index_map.max_size);
t->dimen[i]->index_map.class[ts->num] = tmp;
if (new) {
if (t->dimen[i]->max_size <= r->num) {
growTransition(t, i);
}
addHyperPlane(t, i, r);
} else {
freeItem_Set(r);
}
}
}
Item_Set *
transLval(t, row, col) Table t; int row; int col;
{
switch (t->op->arity) {
case 0:
assert(row == 0);
assert(col == 0);
return t->transition;
case 1:
assert(col == 0);
return t->transition + row;
case 2:
return t->transition + row * t->dimen[1]->max_size + col;
default:
assert(0);
}
return 0;
}
void
dumpRelevant(r) Relevant r;
{
for (; *r; r++) {
printf("%4d", *r);
}
}
void
dumpIndex_Map(r) Index_Map *r;
{
int i;
printf("BEGIN Index_Map: MaxSize (%d)\n", r->max_size);
for (i = 0; i < globalMap->count; i++) {
printf("\t#%d: -> %d\n", i, r->class[i]->num);
}
printf("END Index_Map:\n");
}
void
dumpDimension(d) Dimension d;
{
printf("BEGIN Dimension:\n");
printf("Relevant: ");
dumpRelevant(d->relevant);
printf("\n");
dumpIndex_Map(&d->index_map);
dumpMapping(d->map);
printf("MaxSize of dimension = %d\n", d->max_size);
printf("END Dimension\n");
}
void
dumpTable(t, full) Table t; int full;
{
int i;
if (!t) {
printf("NO Table yet.\n");
return;
}
printf("BEGIN Table:\n");
if (full) {
dumpOperator(t->op, 0);
}
for (i = 0; i < t->op->arity; i++) {
printf("BEGIN dimension(%d)\n", i);
dumpDimension(t->dimen[i]);
printf("END dimension(%d)\n", i);
}
dumpTransition(t);
printf("END Table:\n");
}
void
dumpTransition(t) Table t;
{
int i,j;
switch (t->op->arity) {
case 0:
printf("{ %d }", t->transition[0]->num);
break;
case 1:
printf("{");
for (i = 0; i < t->dimen[0]->map->count; i++) {
if (i > 0) {
printf(",");
}
printf("%5d", t->transition[i]->num);
}
printf("}");
break;
case 2:
printf("{");
for (i = 0; i < t->dimen[0]->map->count; i++) {
if (i > 0) {
printf(",");
}
printf("\n");
printf("{");
for (j = 0; j < t->dimen[1]->map->count; j++) {
Item_Set *ts = transLval(t, i, j);
if (j > 0) {
printf(",");
}
printf("%5d", (*ts)->num);
}
printf("}");
}
printf("\n}\n");
break;
default:
assert(0);
}
}

412
support/tools/Burg/trim.c Normal file
View File

@ -0,0 +1,412 @@
char rcsid_trim[] = "$Id$";
#include <stdio.h>
#include "b.h"
#include "fe.h"
Relation *allpairs;
int trimflag = 0;
int debugTrim = 0;
static void siblings ARGS((int, int));
static void findAllNexts ARGS((void));
static Relation *newAllPairs ARGS((void));
static void
siblings(i, j) int i; int j;
{
int k;
List pl;
DeltaCost Max;
int foundmax;
allpairs[i][j].sibComputed = 1;
if (i == 1) {
return; /* never trim start symbol */
}
if (i==j) {
return;
}
ZEROCOST(Max);
foundmax = 0;
for (k = 1; k < max_nonterminal; k++) {
DeltaCost tmp;
if (k==i || k==j) {
continue;
}
if (!allpairs[k][i].rule) {
continue;
}
if (!allpairs[k][j].rule) {
return;
}
ASSIGNCOST(tmp, allpairs[k][j].chain);
MINUSCOST(tmp, allpairs[k][i].chain);
if (foundmax) {
if (LESSCOST(Max, tmp)) {
ASSIGNCOST(Max, tmp);
}
} else {
foundmax = 1;
ASSIGNCOST(Max, tmp);
}
}
for (pl = rules; pl; pl = pl->next) {
Rule p = (Rule) pl->x;
Operator op = p->pat->op;
List oprule;
DeltaCost Min;
int foundmin;
if (!op) {
continue;
}
switch (op->arity) {
case 0:
continue;
case 1:
if (!allpairs[p->pat->children[0]->num ][ i].rule) {
continue;
}
foundmin = 0;
for (oprule = op->table->rules; oprule; oprule = oprule->next) {
Rule s = (Rule) oprule->x;
DeltaPtr Cx;
DeltaPtr Csj;
DeltaPtr Cpi;
DeltaCost tmp;
if (!allpairs[p->lhs->num ][ s->lhs->num].rule
|| !allpairs[s->pat->children[0]->num ][ j].rule) {
continue;
}
Cx = allpairs[p->lhs->num ][ s->lhs->num].chain;
Csj= allpairs[s->pat->children[0]->num ][ j].chain;
Cpi= allpairs[p->pat->children[0]->num ][ i].chain;
ASSIGNCOST(tmp, Cx);
ADDCOST(tmp, s->delta);
ADDCOST(tmp, Csj);
MINUSCOST(tmp, Cpi);
MINUSCOST(tmp, p->delta);
if (foundmin) {
if (LESSCOST(tmp, Min)) {
ASSIGNCOST(Min, tmp);
}
} else {
foundmin = 1;
ASSIGNCOST(Min, tmp);
}
}
if (!foundmin) {
return;
}
if (foundmax) {
if (LESSCOST(Max, Min)) {
ASSIGNCOST(Max, Min);
}
} else {
foundmax = 1;
ASSIGNCOST(Max, Min);
}
break;
case 2:
/* do first dimension */
if (allpairs[p->pat->children[0]->num ][ i].rule) {
foundmin = 0;
for (oprule = op->table->rules; oprule; oprule = oprule->next) {
Rule s = (Rule) oprule->x;
DeltaPtr Cx;
DeltaPtr Cb;
DeltaPtr Csj;
DeltaPtr Cpi;
DeltaCost tmp;
if (allpairs[p->lhs->num ][ s->lhs->num].rule
&& allpairs[s->pat->children[0]->num ][ j].rule
&& allpairs[s->pat->children[1]->num ][ p->pat->children[1]->num].rule) {
Cx = allpairs[p->lhs->num ][ s->lhs->num].chain;
Csj= allpairs[s->pat->children[0]->num ][ j].chain;
Cpi= allpairs[p->pat->children[0]->num ][ i].chain;
Cb = allpairs[s->pat->children[1]->num ][ p->pat->children[1]->num].chain;
ASSIGNCOST(tmp, Cx);
ADDCOST(tmp, s->delta);
ADDCOST(tmp, Csj);
ADDCOST(tmp, Cb);
MINUSCOST(tmp, Cpi);
MINUSCOST(tmp, p->delta);
if (foundmin) {
if (LESSCOST(tmp, Min)) {
ASSIGNCOST(Min, tmp);
}
} else {
foundmin = 1;
ASSIGNCOST(Min, tmp);
}
}
}
if (!foundmin) {
return;
}
if (foundmax) {
if (LESSCOST(Max, Min)) {
ASSIGNCOST(Max, Min);
}
} else {
foundmax = 1;
ASSIGNCOST(Max, Min);
}
}
/* do second dimension */
if (allpairs[p->pat->children[1]->num ][ i].rule) {
foundmin = 0;
for (oprule = op->table->rules; oprule; oprule = oprule->next) {
Rule s = (Rule) oprule->x;
DeltaPtr Cx;
DeltaPtr Cb;
DeltaPtr Csj;
DeltaPtr Cpi;
DeltaCost tmp;
if (allpairs[p->lhs->num ][ s->lhs->num].rule
&& allpairs[s->pat->children[1]->num ][ j].rule
&& allpairs[s->pat->children[0]->num ][ p->pat->children[0]->num].rule) {
Cx = allpairs[p->lhs->num ][ s->lhs->num].chain;
Csj= allpairs[s->pat->children[1]->num ][ j].chain;
Cpi= allpairs[p->pat->children[1]->num ][ i].chain;
Cb = allpairs[s->pat->children[0]->num ][ p->pat->children[0]->num].chain;
ASSIGNCOST(tmp, Cx);
ADDCOST(tmp, s->delta);
ADDCOST(tmp, Csj);
ADDCOST(tmp, Cb);
MINUSCOST(tmp, Cpi);
MINUSCOST(tmp, p->delta);
if (foundmin) {
if (LESSCOST(tmp, Min)) {
ASSIGNCOST(Min, tmp);
}
} else {
foundmin = 1;
ASSIGNCOST(Min, tmp);
}
}
}
if (!foundmin) {
return;
}
if (foundmax) {
if (LESSCOST(Max, Min)) {
ASSIGNCOST(Max, Min);
}
} else {
foundmax = 1;
ASSIGNCOST(Max, Min);
}
}
break;
default:
assert(0);
}
}
allpairs[i ][ j].sibFlag = foundmax;
ASSIGNCOST(allpairs[i ][ j].sibling, Max);
}
static void
findAllNexts()
{
int i,j;
int last;
for (i = 1; i < max_nonterminal; i++) {
last = 0;
for (j = 1; j < max_nonterminal; j++) {
if (allpairs[i ][j].rule) {
allpairs[i ][ last].nextchain = j;
last = j;
}
}
}
/*
for (i = 1; i < max_nonterminal; i++) {
last = 0;
for (j = 1; j < max_nonterminal; j++) {
if (allpairs[i ][j].sibFlag) {
allpairs[i ][ last].nextsibling = j;
last = j;
}
}
}
*/
}
static Relation *
newAllPairs()
{
int i;
Relation *rv;
rv = (Relation*) zalloc(max_nonterminal * sizeof(Relation));
for (i = 0; i < max_nonterminal; i++) {
rv[i] = (Relation) zalloc(max_nonterminal * sizeof(struct relation));
}
return rv;
}
void
findAllPairs()
{
List pl;
int changes;
int j;
allpairs = newAllPairs();
for (pl = chainrules; pl; pl = pl->next) {
Rule p = (Rule) pl->x;
NonTerminalNum rhs = p->pat->children[0]->num;
NonTerminalNum lhs = p->lhs->num;
Relation r = &allpairs[lhs ][ rhs];
if (LESSCOST(p->delta, r->chain)) {
ASSIGNCOST(r->chain, p->delta);
r->rule = p;
}
}
for (j = 1; j < max_nonterminal; j++) {
Relation r = &allpairs[j ][ j];
ZEROCOST(r->chain);
r->rule = &stub_rule;
}
changes = 1;
while (changes) {
changes = 0;
for (pl = chainrules; pl; pl = pl->next) {
Rule p = (Rule) pl->x;
NonTerminalNum rhs = p->pat->children[0]->num;
NonTerminalNum lhs = p->lhs->num;
int i;
for (i = 1; i < max_nonterminal; i++) {
Relation r = &allpairs[rhs ][ i];
Relation s = &allpairs[lhs ][ i];
DeltaCost dc;
if (!r->rule) {
continue;
}
ASSIGNCOST(dc, p->delta);
ADDCOST(dc, r->chain);
if (!s->rule || LESSCOST(dc, s->chain)) {
s->rule = p;
ASSIGNCOST(s->chain, dc);
changes = 1;
}
}
}
}
findAllNexts();
}
void
trim(t) Item_Set t;
{
int m,n;
static short *vec = 0;
int last;
assert(!t->closed);
debug(debugTrim, printf("Begin Trim\n"));
debug(debugTrim, dumpItem_Set(t));
last = 0;
if (!vec) {
vec = (short*) zalloc(max_nonterminal * sizeof(*vec));
}
for (m = 1; m < max_nonterminal; m++) {
if (t->virgin[m].rule) {
vec[last++] = m;
}
}
for (m = 0; m < last; m++) {
DeltaCost tmp;
int j;
int i;
i = vec[m];
for (j = allpairs[i ][ 0].nextchain; j; j = allpairs[i ][ j].nextchain) {
if (i == j) {
continue;
}
if (!t->virgin[j].rule) {
continue;
}
ASSIGNCOST(tmp, t->virgin[j].delta);
ADDCOST(tmp, allpairs[i ][ j].chain);
if (!LESSCOST(t->virgin[i].delta, tmp)) {
t->virgin[i].rule = 0;
ZEROCOST(t->virgin[i].delta);
debug(debugTrim, printf("Trimmed Chain (%d,%d)\n", i,j));
goto outer;
}
}
if (!trimflag) {
continue;
}
for (n = 0; n < last; n++) {
j = vec[n];
if (i == j) {
continue;
}
if (!t->virgin[j].rule) {
continue;
}
if (!allpairs[i][j].sibComputed) {
siblings(i,j);
}
if (!allpairs[i][j].sibFlag) {
continue;
}
ASSIGNCOST(tmp, t->virgin[j].delta);
ADDCOST(tmp, allpairs[i ][ j].sibling);
if (!LESSCOST(t->virgin[i].delta, tmp)) {
t->virgin[i].rule = 0;
ZEROCOST(t->virgin[i].delta);
goto outer;
}
}
outer: ;
}
debug(debugTrim, dumpItem_Set(t));
debug(debugTrim, printf("End Trim\n"));
}
void
dumpRelation(r) Relation r;
{
printf("{ %d %ld %d %ld }", r->rule->erulenum, (long) r->chain, r->sibFlag, (long) r->sibling);
}
void
dumpAllPairs()
{
int i,j;
printf("Dumping AllPairs\n");
for (i = 1; i < max_nonterminal; i++) {
for (j = 1; j < max_nonterminal; j++) {
dumpRelation(&allpairs[i ][j]);
}
printf("\n");
}
}

View File

@ -0,0 +1,35 @@
char rcsid_zalloc[] = "$Id$";
#include <stdio.h>
#include <string.h>
#include "b.h"
extern void exit ARGS((int));
extern void free ARGS((void *));
extern void *malloc ARGS((unsigned));
int
fatal(name, line) char *name; int line;
{
fprintf(stderr, "assertion failed: file %s, line %d\n", name, line);
exit(1);
return 0;
}
void *
zalloc(size) unsigned int size;
{
void *t = (void *) malloc(size);
if (!t) {
fprintf(stderr, "Malloc failed---PROGRAM ABORTED\n");
exit(1);
}
memset(t, 0, size);
return t;
}
void
zfree(p) void *p;
{
free(p);
}

13
utils/Burg/COPYRIGHT Normal file
View File

@ -0,0 +1,13 @@
Copyright (C) 1991 Todd A. Proebsting
All Rights Reserved.
This software is in the public domain. You may use and copy this material
freely. This privilege extends to modifications, although any modified
version of this system given to a third party should clearly identify your
modifications as well as the original source.
The responsibility for the use of this material resides entirely with you.
We make no warranty of any kind concerning this material, nor do we make
any claim as to the suitability of BURG for any application. This software
is experimental in nature and there is no written or implied warranty. Use
it at your own risk.

2
utils/Burg/LOG_CHANGES Normal file
View File

@ -0,0 +1,2 @@
8/20/02 -- Vikram Adve
be.c: Replaced "char*" with "const char*" to avoid compiler warnings.

84
utils/Burg/Makefile Normal file
View File

@ -0,0 +1,84 @@
# $Id$
#CFLAGS =
#CFLAGS = -O
#CFLAGS = -O -DNOLEX
CFLAGS = -g -DDEBUG
#CFLAGS = -g -DNOLEX -DDEBUG
SRCS = \
be.c \
burs.c \
closure.c \
delta.c \
fe.c \
item.c \
lex.c \
list.c \
main.c \
map.c \
nonterminal.c \
operator.c \
pattern.c \
plank.c \
queue.c \
rule.c \
string.c \
symtab.c \
table.c \
trim.c \
zalloc.c
BU_OBJS = \
burs.o \
closure.o \
delta.o \
item.o \
list.o \
map.o \
nonterminal.o \
operator.o \
pattern.o \
queue.o \
rule.o \
table.o \
trim.o \
zalloc.o
FE_OBJS = \
be.o \
fe.o \
lex.o \
main.o \
plank.o \
string.o \
symtab.o \
y.tab.o
all: test
burg: $(BU_OBJS) $(FE_OBJS)
$(CC) -o burg $(CFLAGS) $(BU_OBJS) $(FE_OBJS)
y.tab.c y.tab.h: gram.y
yacc -d gram.y
clean:
rm -f *.o y.tab.h y.tab.c core burg *.aux *.log *.dvi sample sample.c tmp
$(FE_OBJS): b.h
$(BU_OBJS): b.h
$(FE_OBJS): fe.h
lex.o: y.tab.h
doc.dvi: doc.tex
latex doc; latex doc
test: burg sample.gr
./burg -I <sample.gr >sample.c && cc $(CFLAGS) -o sample sample.c && ./sample
./burg -I sample.gr >tmp && cmp tmp sample.c
./burg -I <sample.gr -o tmp && cmp tmp sample.c
./burg -I sample.gr -o tmp && cmp tmp sample.c
./burg -I -O0 <sample.gr >tmp && cmp tmp sample.c
./burg -I -= <sample.gr >tmp && cmp tmp sample.c

14
utils/Burg/README Normal file
View File

@ -0,0 +1,14 @@
To format the documentation, type "make doc.dvi" and print the result.
The length of the cost vectors is fixed at 4 for reasons that are
primarily historical. To change it, edit the definition of DELTAWIDTH
in b.h.
Burg is compiled without optimization by default to avoid problems
with initial installation. To improve burg's performance, add '-O' to
CFLAGS in the Makefile and rebuild burg with a high quality optimizing
compiler.
To be added to the Burg mailing list, send your preferred electronic
mail address to cwf@research.att.com.

311
utils/Burg/b.h Normal file
View File

@ -0,0 +1,311 @@
/* $Id$ */
#define MAX_ARITY 2
typedef int ItemSetNum;
typedef int OperatorNum;
typedef int NonTerminalNum;
typedef int RuleNum;
typedef int ArityNum;
typedef int ERuleNum;
extern NonTerminalNum last_user_nonterminal;
extern NonTerminalNum max_nonterminal;
extern RuleNum max_rule;
extern ERuleNum max_erule_num;
extern int max_arity;
#ifdef __STDC__
#define ARGS(x) x
#else
#define ARGS(x) ()
#endif
#ifndef NOLEX
#define DELTAWIDTH 4
typedef short DeltaCost[DELTAWIDTH];
typedef short *DeltaPtr;
extern void ASSIGNCOST ARGS((DeltaPtr, DeltaPtr));
extern void ADDCOST ARGS((DeltaPtr, DeltaPtr));
extern void MINUSCOST ARGS((DeltaPtr, DeltaPtr));
extern void ZEROCOST ARGS((DeltaPtr));
extern int LESSCOST ARGS((DeltaPtr, DeltaPtr));
extern int EQUALCOST ARGS((DeltaPtr, DeltaPtr));
#define PRINCIPLECOST(x) (x[0])
#else
#define DELTAWIDTH 1
typedef int DeltaCost;
typedef int DeltaPtr;
#define ASSIGNCOST(l, r) ((l) = (r))
#define ADDCOST(l, r) ((l) += (r))
#define MINUSCOST(l, r) ((l) -= (r))
#define ZEROCOST(x) ((x) = 0)
#define LESSCOST(l, r) ((l) < (r))
#define EQUALCOST(l, r) ((l) == (r))
#define PRINCIPLECOST(x) (x)
#endif /* NOLEX */
#define NODIVERGE(c,state,nt,base) if (prevent_divergence > 0) CHECKDIVERGE(c,state,nt,base);
struct list {
void *x;
struct list *next;
};
typedef struct list *List;
struct intlist {
int x;
struct intlist *next;
};
typedef struct intlist *IntList;
struct operator {
char *name;
unsigned int ref:1;
OperatorNum num;
ItemSetNum baseNum;
ItemSetNum stateCount;
ArityNum arity;
struct table *table;
};
typedef struct operator *Operator;
struct nonterminal {
char *name;
NonTerminalNum num;
ItemSetNum baseNum;
ItemSetNum ruleCount;
struct plankMap *pmap;
struct rule *sampleRule; /* diagnostic---gives "a" rule that with this lhs */
};
typedef struct nonterminal *NonTerminal;
struct pattern {
NonTerminal normalizer;
Operator op; /* NULL if NonTerm -> NonTerm */
NonTerminal children[MAX_ARITY];
};
typedef struct pattern *Pattern;
struct rule {
DeltaCost delta;
ERuleNum erulenum;
RuleNum num;
RuleNum newNum;
NonTerminal lhs;
Pattern pat;
unsigned int used:1;
};
typedef struct rule *Rule;
struct item {
DeltaCost delta;
Rule rule;
};
typedef struct item Item;
typedef short *Relevant; /* relevant non-terminals */
typedef Item *ItemArray;
struct item_set { /* indexed by NonTerminal */
ItemSetNum num;
ItemSetNum newNum;
Operator op;
struct item_set *kids[2];
struct item_set *representative;
Relevant relevant;
ItemArray virgin;
ItemArray closed;
};
typedef struct item_set *Item_Set;
#define DIM_MAP_SIZE (1 << 8)
#define GLOBAL_MAP_SIZE (1 << 15)
struct mapping { /* should be a hash table for TS -> int */
List *hash;
int hash_size;
int max_size;
ItemSetNum count;
Item_Set *set; /* map: int <-> Item_Set */
};
typedef struct mapping *Mapping;
struct index_map {
ItemSetNum max_size;
Item_Set *class;
};
typedef struct index_map Index_Map;
struct dimension {
Relevant relevant;
Index_Map index_map;
Mapping map;
ItemSetNum max_size;
struct plankMap *pmap;
};
typedef struct dimension *Dimension;
struct table {
Operator op;
List rules;
Relevant relevant;
Dimension dimen[MAX_ARITY]; /* 1 for each dimension */
Item_Set *transition; /* maps local indices to global
itemsets */
};
typedef struct table *Table;
struct relation {
Rule rule;
DeltaCost chain;
NonTerminalNum nextchain;
DeltaCost sibling;
int sibFlag;
int sibComputed;
};
typedef struct relation *Relation;
struct queue {
List head;
List tail;
};
typedef struct queue *Queue;
struct plank {
char *name;
List fields;
int width;
};
typedef struct plank *Plank;
struct except {
short index;
short value;
};
typedef struct except *Exception;
struct plankMap {
List exceptions;
int offset;
struct stateMap *values;
};
typedef struct plankMap *PlankMap;
struct stateMap {
char *fieldname;
Plank plank;
int width;
short *value;
};
typedef struct stateMap *StateMap;
struct stateMapTable {
List maps;
};
extern void CHECKDIVERGE ARGS((DeltaPtr, Item_Set, int, int));
extern void zero ARGS((Item_Set));
extern ItemArray newItemArray ARGS((void));
extern ItemArray itemArrayCopy ARGS((ItemArray));
extern Item_Set newItem_Set ARGS((Relevant));
extern void freeItem_Set ARGS((Item_Set));
extern Mapping newMapping ARGS((int));
extern NonTerminal newNonTerminal ARGS((char *));
extern int nonTerminalName ARGS((char *, int));
extern Operator newOperator ARGS((char *, OperatorNum, ArityNum));
extern Pattern newPattern ARGS((Operator));
extern Rule newRule ARGS((DeltaPtr, ERuleNum, NonTerminal, Pattern));
extern List newList ARGS((void *, List));
extern IntList newIntList ARGS((int, IntList));
extern int length ARGS((List));
extern List appendList ARGS((void *, List));
extern Table newTable ARGS((Operator));
extern Queue newQ ARGS((void));
extern void addQ ARGS((Queue, Item_Set));
extern Item_Set popQ ARGS((Queue));
extern int equivSet ARGS((Item_Set, Item_Set));
extern Item_Set decode ARGS((Mapping, ItemSetNum));
extern Item_Set encode ARGS((Mapping, Item_Set, int *));
extern void build ARGS((void));
extern Item_Set *transLval ARGS((Table, int, int));
typedef void * (*ListFn) ARGS((void *));
extern void foreachList ARGS((ListFn, List));
extern void reveachList ARGS((ListFn, List));
extern void addToTable ARGS((Table, Item_Set));
extern void closure ARGS((Item_Set));
extern void trim ARGS((Item_Set));
extern void findChainRules ARGS((void));
extern void findAllPairs ARGS((void));
extern void addRelevant ARGS((Relevant, NonTerminalNum));
extern void *zalloc ARGS((unsigned int));
extern void zfree ARGS((void *));
extern NonTerminal start;
extern List rules;
extern List chainrules;
extern List operators;
extern List leaves;
extern List nonterminals;
extern List grammarNts;
extern Queue globalQ;
extern Mapping globalMap;
extern int exceptionTolerance;
extern int prevent_divergence;
extern int principleCost;
extern int lexical;
extern struct rule stub_rule;
extern Relation *allpairs;
extern Item_Set *sortedStates;
extern Item_Set errorState;
extern void dumpRelevant ARGS((Relevant));
extern void dumpOperator ARGS((Operator, int));
extern void dumpOperator_s ARGS((Operator));
extern void dumpOperator_l ARGS((Operator));
extern void dumpNonTerminal ARGS((NonTerminal));
extern void dumpRule ARGS((Rule));
extern void dumpRuleList ARGS((List));
extern void dumpItem ARGS((Item *));
extern void dumpItem_Set ARGS((Item_Set));
extern void dumpMapping ARGS((Mapping));
extern void dumpQ ARGS((Queue));
extern void dumpIndex_Map ARGS((Index_Map *));
extern void dumpDimension ARGS((Dimension));
extern void dumpPattern ARGS((Pattern));
extern void dumpTable ARGS((Table, int));
extern void dumpTransition ARGS((Table));
extern void dumpCost ARGS((DeltaCost));
extern void dumpAllPairs ARGS((void));
extern void dumpRelation ARGS((Relation));
extern void dumpSortedStates ARGS((void));
extern void dumpSortedRules ARGS((void));
extern int debugTrim;
#ifdef DEBUG
#define debug(a,b) if (a) b
#else
#define debug(a,b)
#endif
extern int debugTables;
#define TABLE_INCR 8
#define STATES_INCR 64
#ifdef NDEBUG
#define assert(c) ((void) 0)
#else
#define assert(c) ((void) ((c) || fatal(__FILE__,__LINE__)))
#endif
extern void doStart ARGS((char *));
extern void exit ARGS((int));
extern int fatal ARGS((char *, int));
extern void yyerror ARGS((char *));
extern void yyerror1 ARGS((char *));

1052
utils/Burg/be.c Normal file

File diff suppressed because it is too large Load Diff

BIN
utils/Burg/burg.shar.gz Normal file

Binary file not shown.

71
utils/Burg/burs.c Normal file
View File

@ -0,0 +1,71 @@
char rcsid_burs[] = "$Id$";
#include "b.h"
Item_Set errorState;
static void doLeaf ARGS((Operator));
static void
doLeaf(leaf) Operator leaf;
{
int new;
List pl;
Item_Set ts;
Item_Set tmp;
assert(leaf->arity == 0);
ts = newItem_Set(leaf->table->relevant);
for (pl = rules; pl; pl = pl->next) {
Rule p = (Rule) pl->x;
if (p->pat->op == leaf) {
if (!ts->virgin[p->lhs->num].rule || p->delta < ts->virgin[p->lhs->num].delta) {
ts->virgin[p->lhs->num].rule = p;
ASSIGNCOST(ts->virgin[p->lhs->num].delta, p->delta);
ts->op = leaf;
}
}
}
trim(ts);
zero(ts);
tmp = encode(globalMap, ts, &new);
if (new) {
closure(ts);
leaf->table->transition[0] = ts;
addQ(globalQ, ts);
} else {
leaf->table->transition[0] = tmp;
freeItem_Set(ts);
}
}
void
build()
{
int new;
List ol;
Item_Set ts;
globalQ = newQ();
globalMap = newMapping(GLOBAL_MAP_SIZE);
ts = newItem_Set(0);
errorState = encode(globalMap, ts, &new);
ts->closed = ts->virgin;
addQ(globalQ, ts);
foreachList((ListFn) doLeaf, leaves);
debug(debugTables, printf("---initial set of states ---\n"));
debug(debugTables, dumpMapping(globalMap));
debug(debugTables, foreachList((ListFn) dumpItem_Set, globalQ->head));
for (ts = popQ(globalQ); ts; ts = popQ(globalQ)) {
for (ol = operators; ol; ol = ol->next) {
Operator op = (Operator) ol->x;
addToTable(op->table, ts);
}
}
}

95
utils/Burg/closure.c Normal file
View File

@ -0,0 +1,95 @@
char rcsid_closure[] = "$Id$";
#include <stdio.h>
#include "b.h"
int prevent_divergence = 0;
List chainrules;
void
findChainRules()
{
List pl;
assert(!chainrules);
for (pl = rules; pl; pl = pl->next) {
Rule p = (Rule) pl->x;
if (!p->pat->op) {
chainrules = newList(p, chainrules);
} else {
p->pat->op->table->rules = newList(p, p->pat->op->table->rules);
addRelevant(p->pat->op->table->relevant, p->lhs->num);
}
}
}
void
zero(t) Item_Set t;
{
int i;
DeltaCost base;
int exists;
int base_nt;
assert(!t->closed);
ZEROCOST(base);
exists = 0;
for (i = 0; i < max_nonterminal; i++) {
if (t->virgin[i].rule) {
if (exists) {
if (LESSCOST(t->virgin[i].delta, base)) {
ASSIGNCOST(base, t->virgin[i].delta);
base_nt = i;
}
} else {
ASSIGNCOST(base, t->virgin[i].delta);
exists = 1;
base_nt = i;
}
}
}
if (!exists) {
return;
}
for (i = 0; i < max_nonterminal; i++) {
if (t->virgin[i].rule) {
MINUSCOST(t->virgin[i].delta, base);
}
NODIVERGE(t->virgin[i].delta, t, i, base_nt);
}
}
void
closure(t) Item_Set t;
{
int changes;
List pl;
assert(!t->closed);
t->closed = itemArrayCopy(t->virgin);
changes = 1;
while (changes) {
changes = 0;
for (pl = chainrules; pl; pl = pl->next) {
Rule p = (Rule) pl->x;
register Item *rhs_item = &t->closed[p->pat->children[0]->num];
if (rhs_item->rule) { /* rhs is active */
DeltaCost dc;
register Item *lhs_item = &t->closed[p->lhs->num];
ASSIGNCOST(dc, rhs_item->delta);
ADDCOST(dc, p->delta);
if (LESSCOST(dc, lhs_item->delta) || !lhs_item->rule) {
ASSIGNCOST(lhs_item->delta, dc);
lhs_item->rule = p;
changes = 1;
}
}
}
}
}

143
utils/Burg/delta.c Normal file
View File

@ -0,0 +1,143 @@
char rcsid_delta[] = "$Id$";
#include <stdio.h>
#include "b.h"
#include "fe.h"
int principleCost = 0;
int lexical = 0;
#ifndef NOLEX
void
ASSIGNCOST(l, r) DeltaPtr l; DeltaPtr r;
{
int i;
if (lexical) {
for (i = 0; i < DELTAWIDTH; i++) {
l[i] = r[i];
}
} else {
l[0] = r[0];
}
}
void
ADDCOST(l, r) DeltaPtr l; DeltaPtr r;
{
int i;
if (lexical) {
for (i = 0; i < DELTAWIDTH; i++) {
l[i] += r[i];
}
} else {
l[0] += r[0];
}
}
void
MINUSCOST(l, r) DeltaPtr l; DeltaPtr r;
{
int i;
if (lexical) {
for (i = 0; i < DELTAWIDTH; i++) {
l[i] -= r[i];
}
} else {
l[0] -= r[0];
}
}
void
ZEROCOST(x) DeltaPtr x;
{
int i;
if (lexical) {
for (i = 0; i < DELTAWIDTH; i++) {
x[i] = 0;
}
} else {
x[0] = 0;
}
}
int
LESSCOST(l, r) DeltaPtr l; DeltaPtr r;
{
int i;
if (lexical) {
for (i = 0; i < DELTAWIDTH; i++) {
if (l[i] < r[i]) {
return 1;
} else if (l[i] > r[i]) {
return 0;
}
}
return 0;
} else {
return l[0] < r[0];
}
}
int
EQUALCOST(l, r) DeltaPtr l; DeltaPtr r;
{
int i;
if (lexical) {
for (i = 0; i < DELTAWIDTH; i++) {
if (l[i] != r[i]) {
return 0;
}
}
return 1;
} else {
return l[0] == r[0];
}
}
#endif /* NOLEX */
void
CHECKDIVERGE(c, its, nt, base) DeltaPtr c; Item_Set its; int nt; int base;
{
int i;
if (prevent_divergence <= 0) {
return;
}
if (lexical) {
#ifndef NOLEX
for (i = 0; i < DELTAWIDTH; i++) {
if (c[i] > prevent_divergence) {
char ntname[100];
char basename[100];
nonTerminalName(ntname, nt);
nonTerminalName(basename, base);
fprintf(stderr, "ERROR: The grammar appears to diverge\n");
fprintf(stderr, "\tRelative Costs: %s(0), %s(%d)\n", basename, ntname, c[i]);
fprintf(stderr, "\tOffending Operator: %s\n", its->op->name);
fprintf(stderr, "\tOffending Tree: ");
printRepresentative(stderr, its);
fprintf(stderr, "\n");
exit(1);
}
}
#endif /*NOLEX*/
} else if (PRINCIPLECOST(c) > prevent_divergence) {
char ntname[100];
char basename[100];
nonTerminalName(ntname, nt);
nonTerminalName(basename, base);
fprintf(stderr, "ERROR: The grammar appears to diverge\n");
fprintf(stderr, "\tRelative Costs: %s(0), %s(%d)\n", basename, ntname, PRINCIPLECOST(c));
fprintf(stderr, "\tOffending Operator: %s\n", its->op->name);
fprintf(stderr, "\tOffending Tree: ");
printRepresentative(stderr, its);
fprintf(stderr, "\n");
exit(1);
}
}

403
utils/Burg/fe.c Normal file
View File

@ -0,0 +1,403 @@
char rcsid_fe[] = "$Id$";
#include <stdio.h>
#include <string.h>
#include "b.h"
#include "fe.h"
int grammarflag;
static int arity;
List ruleASTs;
List grammarNts;
static void doBinding ARGS((Binding));
static void doDecl ARGS((Arity));
static NonTerminal lookup ARGS((Pattern));
static NonTerminal normalize ARGS((PatternAST, NonTerminal, Pattern *));
static void doEnterNonTerm ARGS((RuleAST));
static void doRule ARGS((RuleAST));
static void doTable ARGS((Operator));
static void
doBinding(b) Binding b;
{
int new;
Symbol s;
s = enter(b->name, &new);
if (!new) {
fprintf(stderr, "Non-unique name: %s\n", b->name);
exit(1);
}
s->tag = OPERATOR;
s->u.op = newOperator(b->name, b->opnum, arity);
if (arity == 0) {
leaves = newList(s->u.op, leaves);
}
}
static void
doDecl(a) Arity a;
{
if (!a) {
return;
}
arity = a->arity;
foreachList((ListFn) doBinding, a->bindings);
}
static List xpatterns;
static int tcount;
static NonTerminal
lookup(p) Pattern p;
{
char buf[10];
char *s;
List l;
NonTerminal n;
DeltaCost dummy;
for (l = xpatterns; l; l = l->next) {
Pattern x = (Pattern) l->x;
if (x->op == p->op
&& x->children[0] == p->children[0]
&& x->children[1] == p->children[1]) {
return x->normalizer;
}
}
sprintf(buf, "n%%%d", tcount++);
s = (char *) zalloc(strlen(buf)+1);
strcpy(s, buf);
n = newNonTerminal(s);
p->normalizer = n;
xpatterns = newList(p, xpatterns);
ZEROCOST(dummy);
(void) newRule(dummy, 0, n, p);
return n;
}
static NonTerminal
normalize(ast, nt, patt) PatternAST ast; NonTerminal nt; Pattern *patt;
{
Symbol s;
int new;
Pattern dummy;
s = enter(ast->op, &new);
ast->sym = s;
if (new) {
fprintf(stderr, "Illegal use of %s --- undefined symbol\n", s->name);
exit(1);
return 0; /* shut up compilers */
} else if (s->tag == NONTERMINAL) {
if (ast->children) {
fprintf(stderr, "Illegal use of %s, a non-terminal, as a terminal\n", s->name);
exit(1);
}
*patt = newPattern(0);
(*patt)->children[0] = s->u.nt;
return s->u.nt;
} else {
s->u.op->ref = 1;
*patt = newPattern(s->u.op);
if (s->u.op->arity == -1) {
if (!ast->children) {
s->u.op->arity = 0;
leaves = newList(s->u.op, leaves);
} else if (!ast->children->next) {
s->u.op->arity = 1;
} else if (!ast->children->next->next) {
s->u.op->arity = 2;
} else {
fprintf(stderr, "ERROR: Too many children (max = 2) for \"%s\"\n", s->name);
exit(1);
}
if (s->u.op->arity > max_arity) {
max_arity = s->u.op->arity;
}
}
switch (s->u.op->arity) {
default:
assert(0);
break;
case 0:
if (ast->children) {
fprintf(stderr, "ERROR: Incorrect number of children for leaf operator, \"%s\"\n", s->name);
exit(1);
}
break;
case 1:
if (!ast->children || ast->children->next) {
fprintf(stderr, "ERROR: Incorrect number of children for unary operator, \"%s\"\n", s->name);
exit(1);
}
(*patt)->children[0] = normalize((PatternAST) ast->children->x, 0, &dummy);
break;
case 2:
if (!ast->children || !ast->children->next) {
fprintf(stderr, "ERROR: Incorrect number of children for binary operator, \"%s\"\n", s->name);
exit(1);
}
(*patt)->children[0] = normalize((PatternAST) ast->children->x, 0, &dummy);
(*patt)->children[1] = normalize((PatternAST) ast->children->next->x, 0, &dummy);
break;
}
if (nt) {
(*patt)->normalizer = nt;
return nt;
} else {
return lookup(*patt);
}
}
}
static void
doEnterNonTerm(ast) RuleAST ast;
{
int new;
Symbol s;
DeltaCost delta;
int i;
IntList p;
s = enter(ast->lhs, &new);
if (new) {
s->u.nt = newNonTerminal(s->name);
s->tag = NONTERMINAL;
} else {
if (s->tag != NONTERMINAL) {
fprintf(stderr, "Illegal use of %s as a non-terminal\n", s->name);
exit(1);
}
}
ZEROCOST(delta);
for (p = ast->cost, i = 0; p; p = p->next, i++) {
int x = p->x;
#ifndef NOLEX
if (lexical) {
if (i < DELTAWIDTH) {
delta[i] = x;
}
} else
#endif /* NOLEX */
{
if (i == principleCost) {
PRINCIPLECOST(delta) = x;
}
}
}
ast->rule = newRule(delta, ast->erulenum, s->u.nt, 0);
}
static void
doRule(ast) RuleAST ast;
{
Pattern pat;
(void) normalize(ast->pat, ast->rule->lhs, &pat);
ast->rule->pat = pat;
}
static void
doTable(op) Operator op;
{
op->table = newTable(op);
}
void
doSpec(decls, rules) List decls; List rules;
{
foreachList((ListFn) doDecl, decls);
debug(debugTables, foreachList((ListFn) dumpOperator_l, operators));
ruleASTs = rules;
reveachList((ListFn) doEnterNonTerm, rules);
last_user_nonterminal = max_nonterminal;
reveachList((ListFn) doRule, rules);
debug(debugTables, foreachList((ListFn) dumpRule, rules));
foreachList((ListFn) doTable, operators);
}
void
doStart(name) char *name;
{
Symbol s;
int new;
if (start) {
yyerror1("Redeclaration of start symbol to be ");
fprintf(stderr, "\"%s\"\n", name);
exit(1);
}
s = enter(name, &new);
if (new) {
s->u.nt = newNonTerminal(s->name);
s->tag = NONTERMINAL;
} else {
if (s->tag != NONTERMINAL) {
fprintf(stderr, "Illegal use of %s as a non-terminal\n", s->name);
exit(1);
}
}
}
void
doGrammarNts()
{
List l;
int new;
for (l = grammarNts; l; l = l->next) {
char *n = (char*) l->x;
Symbol s;
s = enter(n, &new);
if (new) {
fprintf(stderr, "ERROR: %%gram, unused non-terminal: \"%s\"\n", n);
exit(1);
}
if (s->tag != NONTERMINAL) {
fprintf(stderr, "ERROR: %%gram, Not a non-terminal: \"%s\"\n", n);
exit(1);
}
l->x = s;
}
}
void
doGram(nts) List nts;
{
if (grammarNts) {
yyerror1("Redeclaration of %%gram\n");
exit(1);
}
grammarNts = nts;
}
Arity
newArity(ar, b) int ar; List b;
{
Arity a = (Arity) zalloc(sizeof(struct arity));
a->arity = ar;
a->bindings = b;
return a;
}
Binding
newBinding(name, opnum) char *name; int opnum;
{
Binding b = (Binding) zalloc(sizeof(struct binding));
if (opnum == 0) {
yyerror1("ERROR: Non-positive external symbol number, ");
fprintf(stderr, "%d", opnum);
exit(1);
}
b->name = name;
b->opnum = opnum;
return b;
}
PatternAST
newPatternAST(op, children) char *op; List children;
{
PatternAST p = (PatternAST) zalloc(sizeof(struct patternAST));
p->op = op;
p->children = children;
return p;
}
int max_ruleAST;
RuleAST
newRuleAST(lhs, pat, erulenum, cost) char *lhs; PatternAST pat; int erulenum; IntList cost;
{
RuleAST p = (RuleAST) zalloc(sizeof(struct ruleAST));
p->lhs = lhs;
p->pat = pat;
if (erulenum <= 0) {
yyerror1("External Rulenumber ");
fprintf(stderr, "(%d) <= 0\n", erulenum);
exit(1);
}
p->erulenum = erulenum;
p->cost = cost;
max_ruleAST++;
return p;
}
void
dumpBinding(b) Binding b;
{
printf("%s=%d ", b->name, b->opnum);
}
void
dumpArity(a) Arity a;
{
List l;
printf("Arity(%d) ", a->arity);
for (l = a->bindings; l; l = l->next) {
Binding b = (Binding) l->x;
dumpBinding(b);
}
printf("\n");
}
void
dumpPatternAST(p) PatternAST p;
{
List l;
printf("%s", p->op);
if (p->children) {
printf("(");
for (l = p->children; l; l = l->next) {
PatternAST past = (PatternAST) l->x;
dumpPatternAST(past);
if (l->next) {
printf(", ");
}
}
printf(")");
}
}
void
dumpRuleAST(p) RuleAST p;
{
printf("%s : ", p->lhs);
dumpPatternAST(p->pat);
printf(" = %d (%ld)\n", p->erulenum, (long) p->cost);
}
void
dumpDecls(decls) List decls;
{
List l;
for (l = decls; l; l = l->next) {
Arity a = (Arity) l->x;
dumpArity(a);
}
}
void
dumpRules(rules) List rules;
{
List l;
for (l = rules; l; l = l->next) {
RuleAST p = (RuleAST) l->x;
dumpRuleAST(p);
}
}

127
utils/Burg/fe.h Normal file
View File

@ -0,0 +1,127 @@
/* $Id$ */
struct binding {
char *name;
int opnum;
};
typedef struct binding *Binding;
struct arity {
int arity;
List bindings;
};
typedef struct arity *Arity;
struct patternAST {
struct symbol *sym;
char *op;
List children;
};
typedef struct patternAST *PatternAST;
struct ruleAST {
char *lhs;
PatternAST pat;
int erulenum;
IntList cost;
struct rule *rule;
struct strTableElement *kids;
struct strTableElement *nts;
};
typedef struct ruleAST *RuleAST;
typedef enum {
UNKNOWN,
OPERATOR,
NONTERMINAL
} TagType;
struct symbol {
char *name;
TagType tag;
union {
NonTerminal nt;
Operator op;
} u;
};
typedef struct symbol *Symbol;
struct strTableElement {
char *str;
IntList erulenos;
char *ename;
};
typedef struct strTableElement *StrTableElement;
struct strTable {
List elems;
};
typedef struct strTable *StrTable;
extern StrTable newStrTable ARGS((void));
extern StrTableElement addString ARGS((StrTable, char *, int, int *));
extern void doSpec ARGS((List, List));
extern Arity newArity ARGS((int, List));
extern Binding newBinding ARGS((char *, int));
extern PatternAST newPatternAST ARGS((char *, List));
extern RuleAST newRuleAST ARGS((char *, PatternAST, int, IntList));
extern Symbol enter ARGS((char *, int *));
extern Symbol newSymbol ARGS((char *));
extern void makeDebug ARGS((void));
extern void makeSimple ARGS((void));
extern void makePlanks ARGS((void));
extern void makeOpLabel ARGS((void));
extern void makeChild ARGS((void));
extern void makeOperators ARGS((void));
extern void makeLabel ARGS((void));
extern void makeString ARGS((void));
extern void makeString ARGS((void));
extern void makeReduce ARGS((void));
extern void makeRuleTable ARGS((void));
extern void makeTables ARGS((void));
extern void makeTreecost ARGS((void));
extern void makePrint ARGS((void));
extern void makeRule ARGS((void));
extern void makeNts ARGS((void));
extern void makeKids ARGS((void));
extern void startBurm ARGS((void));
extern void startOptional ARGS((void));
extern void makePlankLabel ARGS((void));
extern void makeStateLabel ARGS((void));
extern void makeStringArray ARGS((void));
extern void makeNonterminalArray ARGS((void));
extern void makeCostArray ARGS((void));
extern void makeLHSmap ARGS((void));
extern void makeClosureArray ARGS((void));
extern void makeOperatorVector ARGS((void));
extern void endOptional ARGS((void));
extern void reportDiagnostics ARGS((void));
extern void makeNonterminals ARGS((void));
extern int opsOfArity ARGS((int));
extern void yypurge ARGS((void));
extern void yyfinished ARGS((void));
extern void printRepresentative ARGS((FILE *, Item_Set));
extern void dumpRules ARGS((List));
extern void dumpDecls ARGS((List));
extern void dumpRuleAST ARGS((RuleAST));
extern void dumpPatternAST ARGS((PatternAST));
extern void dumpArity ARGS((Arity));
extern void dumpBinding ARGS((Binding));
extern void dumpStrTable ARGS((StrTable));
extern int yylex ARGS((void));
extern int yyparse ARGS((void));
extern int max_ruleAST;
extern List ruleASTs;
extern FILE *outfile;
extern char *prefix;
extern int trimflag;
extern int speedflag;
extern int grammarflag;

90
utils/Burg/gram.y Normal file
View File

@ -0,0 +1,90 @@
%{
char rcsid_gram[] = "$Id$";
#include <stdio.h>
#include "b.h"
#include "fe.h"
%}
%union {
int y_int;
char *y_string;
Arity y_arity;
Binding y_binding;
PatternAST y_patternAST;
RuleAST y_ruleAST;
List y_list;
IntList y_intlist;
}
%start full
%term ERROR
%term K_TERM
%term K_GRAM
%term K_START
%term K_PPERCENT
%term INT
%term ID
%token <y_string> ID
%token <y_int> INT
%type <y_arity> decl
%type <y_binding> binding
%type <y_intlist> cost costtail
%type <y_ruleAST> rule
%type <y_patternAST> pattern
%type <y_list> decls rules bindinglist grammarlist
%%
full : spec
| spec K_PPERCENT
{ yyfinished(); }
;
spec : decls K_PPERCENT rules
= { doSpec($1, $3); }
;
decls : /* lambda */ = { $$ = 0; }
| decls decl = { $$ = newList($2, $1); }
;
decl : K_TERM bindinglist = { $$ = newArity(-1, $2); }
| K_GRAM grammarlist = { $$ = 0; doGram($2); }
| K_START ID = { $$ = 0; doStart($2); } /* kludge */
;
grammarlist : /* lambda */ = { $$ = 0; }
| grammarlist ID = { $$ = newList($2, $1); }
;
bindinglist : /* lambda */ = { $$ = 0; }
| bindinglist binding = { $$ = newList($2, $1); }
;
binding : ID '=' INT = { $$ = newBinding($1, $3); }
;
rules : /* lambda */ = { $$ = 0; }
| rules rule = { $$ = newList($2, $1); }
;
rule : ID ':' pattern '=' INT cost ';' = { $$ = newRuleAST($1, $3, $5, $6); }
;
pattern : ID = { $$ = newPatternAST($1, 0); }
| ID '(' pattern ')' = { $$ = newPatternAST($1, newList($3,0)); }
| ID '(' pattern ',' pattern ')' = { $$ = newPatternAST($1, newList($3, newList($5, 0))); }
;
cost : /* lambda */ = { $$ = 0; }
| '(' INT costtail ')' = { $$ = newIntList($2, $3); }
;
costtail : /* lambda */ = { $$ = 0; }
| ',' INT costtail = { $$ = newIntList($2, $3); }
| INT costtail = { $$ = newIntList($1, $2); }
;

133
utils/Burg/item.c Normal file
View File

@ -0,0 +1,133 @@
char rcsid_item[] = "$Id$";
#include "b.h"
#include <stdio.h>
#include <string.h>
#include "fe.h"
static Item_Set fptr;
ItemArray
newItemArray()
{
ItemArray ia;
ia = (ItemArray) zalloc(max_nonterminal *sizeof(*ia));
return ia;
}
ItemArray
itemArrayCopy(src) ItemArray src;
{
ItemArray dst;
dst = newItemArray();
memcpy(dst, src, max_nonterminal * sizeof(*dst));
return dst;
}
Item_Set
newItem_Set(relevant) Relevant relevant;
{
Item_Set ts;
if (fptr) {
ts = fptr;
fptr = 0;
memset(ts->virgin, 0, max_nonterminal * sizeof(struct item));
if (ts->closed) {
zfree(ts->closed);
ts->closed = 0;
}
ts->num = 0;
ts->op = 0;
} else {
ts = (Item_Set) zalloc(sizeof(struct item_set));
ts->virgin = newItemArray();
}
ts->relevant = relevant;
return ts;
}
void
freeItem_Set(ts) Item_Set ts;
{
assert(!fptr);
fptr = ts;
}
int
equivSet(a, b) Item_Set a; Item_Set b;
{
register Relevant r;
register int nt;
register Item *aa = a->virgin;
register Item *ba = b->virgin;
/*
return !bcmp(a->virgin, b->virgin, max_nonterminal * sizeof(Item));
*/
r = a->relevant ? a->relevant : b->relevant;
assert(r);
if (a->op && b->op && a->op != b->op) {
return 0;
}
for (; (nt = *r) != 0; r++) {
if (aa[nt].rule != ba[nt].rule || !EQUALCOST(aa[nt].delta, ba[nt].delta)) {
return 0;
}
}
return 1;
}
void
printRepresentative(f, s) FILE *f; Item_Set s;
{
if (!s) {
return;
}
fprintf(f, "%s", s->op->name);
switch (s->op->arity) {
case 1:
fprintf(f, "(");
printRepresentative(f, s->kids[0]);
fprintf(f, ")");
break;
case 2:
fprintf(f, "(");
printRepresentative(f, s->kids[0]);
fprintf(f, ", ");
printRepresentative(f, s->kids[1]);
fprintf(f, ")");
break;
}
}
void
dumpItem(t) Item *t;
{
printf("[%s #%d]", t->rule->lhs->name, t->rule->num);
dumpCost(t->delta);
}
void
dumpItem_Set(ts) Item_Set ts;
{
int i;
printf("Item_Set #%d: [", ts->num);
for (i = 1; i < max_nonterminal; i++) {
if (ts->virgin[i].rule) {
printf(" %d", i);
dumpCost(ts->virgin[i].delta);
}
}
printf(" ]\n");
}
void
dumpCost(dc) DeltaCost dc;
{
printf("(%ld)", (long) dc);
}

260
utils/Burg/lex.c Normal file
View File

@ -0,0 +1,260 @@
char rcsid_lex[] = "$Id$";
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include "b.h"
#include "fe.h"
#include "y.tab.h"
static char buf[BUFSIZ];
static int yyline = 1;
typedef int (*ReadFn) ARGS((void));
static char *StrCopy ARGS((char *));
static int code_get ARGS((void));
static int simple_get ARGS((void));
static void ReadCharString ARGS((ReadFn, int));
static void ReadCodeBlock ARGS((void));
static void ReadOldComment ARGS((ReadFn));
static char *
StrCopy(s) char *s;
{
char *t = (char *)zalloc(strlen(s) + 1);
strcpy(t,s);
return t;
}
static int
simple_get()
{
int ch;
if ((ch = getchar()) == '\n') {
yyline++;
}
return ch;
}
static int
code_get()
{
int ch;
if ((ch = getchar()) == '\n') {
yyline++;
}
if (ch != EOF) {
fputc(ch, outfile);
}
return ch;
}
void
yypurge()
{
while (code_get() != EOF) ;
}
static void
ReadCharString(rdfn, which) ReadFn rdfn; int which;
{
int ch;
int backslash = 0;
int firstline = yyline;
while ((ch = rdfn()) != EOF) {
if (ch == which && !backslash) {
return;
}
if (ch == '\\' && !backslash) {
backslash = 1;
} else {
backslash = 0;
}
}
yyerror1("Unexpected EOF in string on line ");
fprintf(stderr, "%d\n", firstline);
exit(1);
}
static void
ReadOldComment(rdfn) ReadFn rdfn;
{
/* will not work for comments delimiter in string */
int ch;
int starred = 0;
int firstline = yyline;
while ((ch = rdfn()) != EOF) {
if (ch == '*') {
starred = 1;
} else if (ch == '/' && starred) {
return;
} else {
starred = 0;
}
}
yyerror1("Unexpected EOF in comment on line ");
fprintf(stderr, "%d\n", firstline);
exit(1);
}
static void
ReadCodeBlock()
{
int ch;
int firstline = yyline;
while ((ch = getchar()) != EOF) {
if (ch == '%') {
ch = getchar();
if (ch != '}') {
yyerror("bad %%");
}
return;
}
fputc(ch, outfile);
if (ch == '\n') {
yyline++;
}
if (ch == '"' || ch == '\'') {
ReadCharString(code_get, ch);
} else if (ch == '/') {
ch = getchar();
if (ch == '*') {
fputc(ch, outfile);
ReadOldComment(code_get);
continue;
} else {
ungetc(ch, stdin);
}
}
}
yyerror1("Unclosed block of C code started on line ");
fprintf(stderr, "%d\n", firstline);
exit(1);
}
static int done;
void
yyfinished()
{
done = 1;
}
int
yylex()
{
int ch;
char *ptr = buf;
if (done) return 0;
while ((ch = getchar()) != EOF) {
switch (ch) {
case ' ':
case '\f':
case '\t':
continue;
case '\n':
yyline++;
continue;
case '(':
case ')':
case ',':
case ':':
case ';':
case '=':
return(ch);
case '/':
ch = getchar();
if (ch == '*') {
ReadOldComment(simple_get);
continue;
} else {
ungetc(ch, stdin);
yyerror("illegal char /");
continue;
}
case '%':
ch = getchar();
switch (ch) {
case '%':
return (K_PPERCENT);
case '{':
ReadCodeBlock();
continue;
case 's':
case 'g':
case 't':
do {
if (ptr >= &buf[BUFSIZ]) {
yyerror("ID too long");
return(ERROR);
} else {
*ptr++ = ch;
}
ch = getchar();
} while (isalpha(ch) || isdigit(ch) || ch == '_');
ungetc(ch, stdin);
*ptr = '\0';
if (!strcmp(buf, "term")) return K_TERM;
if (!strcmp(buf, "start")) return K_START;
if (!strcmp(buf, "gram")) return K_GRAM;
yyerror("illegal character after %%");
continue;
default:
yyerror("illegal character after %%");
continue;
}
default:
if (isalpha(ch) ) {
do {
if (ptr >= &buf[BUFSIZ]) {
yyerror("ID too long");
return(ERROR);
} else {
*ptr++ = ch;
}
ch = getchar();
} while (isalpha(ch) || isdigit(ch) || ch == '_');
ungetc(ch, stdin);
*ptr = '\0';
yylval.y_string = StrCopy(buf);
return(ID);
}
if (isdigit(ch)) {
int val=0;
do {
val *= 10;
val += (ch - '0');
ch = getchar();
} while (isdigit(ch));
ungetc(ch, stdin);
yylval.y_int = val;
return(INT);
}
yyerror1("illegal char ");
fprintf(stderr, "(\\%03o)\n", ch);
exit(1);
}
}
return(0);
}
void
yyerror1(str) char *str;
{
fprintf(stderr, "line %d: %s", yyline, str);
}
void
yyerror(str) char *str;
{
yyerror1(str);
fprintf(stderr, "\n");
exit(1);
}

75
utils/Burg/list.c Normal file
View File

@ -0,0 +1,75 @@
char rcsid_list[] = "$Id$";
#include "b.h"
IntList
newIntList(x, next) int x; IntList next;
{
IntList l;
l = (IntList) zalloc(sizeof(*l));
assert(l);
l->x = x;
l->next = next;
return l;
}
List
newList(x, next) void *x; List next;
{
List l;
l = (List) zalloc(sizeof(*l));
assert(l);
l->x = x;
l->next = next;
return l;
}
List
appendList(x, l) void *x; List l;
{
List last;
List p;
last = 0;
for (p = l; p; p = p->next) {
last = p;
}
if (last) {
last->next = newList(x, 0);
return l;
} else {
return newList(x, 0);
}
}
void
foreachList(f, l) ListFn f; List l;
{
for (; l; l = l->next) {
(*f)(l->x);
}
}
void
reveachList(f, l) ListFn f; List l;
{
if (l) {
reveachList(f, l->next);
(*f)(l->x);
}
}
int
length(l) List l;
{
int c = 0;
for(; l; l = l->next) {
c++;
}
return c;
}

182
utils/Burg/main.c Normal file
View File

@ -0,0 +1,182 @@
char rcsid_main[] = "$Id$";
#include <math.h>
#include <stdio.h>
#include "b.h"
#include "fe.h"
int debugTables = 0;
static int simpleTables = 0;
static int internals = 0;
static int diagnostics = 0;
static char *inFileName;
static char *outFileName;
static char version[] = "BURG, Version 1.0";
extern void main ARGS((int argc, char **argv));
void
main(argc, argv) int argc; char **argv;
{
int i;
extern int atoi ARGS((char *));
for (i = 1; argv[i]; i++) {
char **needStr = 0;
int *needInt = 0;
if (argv[i][0] == '-') {
switch (argv[i][1]) {
case 'V':
fprintf(stderr, "%s\n", version);
break;
case 'p':
needStr = &prefix;
break;
case 'o':
needStr = &outFileName;
break;
case 'I':
internals = 1;
break;
case 'T':
simpleTables = 1;
break;
case '=':
#ifdef NOLEX
fprintf(stderr, "'%s' was not compiled to support lexicographic ordering\n", argv[0]);
#else
lexical = 1;
#endif /* NOLEX */
break;
case 'O':
needInt = &principleCost;
break;
case 'c':
needInt = &prevent_divergence;
break;
case 'e':
needInt = &exceptionTolerance;
break;
case 'd':
diagnostics = 1;
break;
case 'S':
speedflag = 1;
break;
case 't':
trimflag = 1;
break;
case 'G':
grammarflag = 1;
break;
default:
fprintf(stderr, "Bad option (%s)\n", argv[i]);
exit(1);
}
} else {
if (inFileName) {
fprintf(stderr, "Unexpected Filename (%s) after (%s)\n", argv[i], inFileName);
exit(1);
}
inFileName = argv[i];
}
if (needInt || needStr) {
char *v;
char *opt = argv[i];
if (argv[i][2]) {
v = &argv[i][2];
} else {
v = argv[++i];
if (!v) {
fprintf(stderr, "Expection argument after %s\n", opt);
exit(1);
}
}
if (needInt) {
*needInt = atoi(v);
} else if (needStr) {
*needStr = v;
}
}
}
if (inFileName) {
if(freopen(inFileName, "r", stdin)==NULL) {
fprintf(stderr, "Failed opening (%s)", inFileName);
exit(1);
}
}
if (outFileName) {
if ((outfile = fopen(outFileName, "w")) == NULL) {
fprintf(stderr, "Failed opening (%s)", outFileName);
exit(1);
}
} else {
outfile = stdout;
}
yyparse();
if (!rules) {
fprintf(stderr, "ERROR: No rules present\n");
exit(1);
}
findChainRules();
findAllPairs();
doGrammarNts();
build();
debug(debugTables, foreachList((ListFn) dumpOperator_l, operators));
debug(debugTables, printf("---final set of states ---\n"));
debug(debugTables, dumpMapping(globalMap));
startBurm();
makeNts();
if (simpleTables) {
makeSimple();
} else {
makePlanks();
}
startOptional();
makeLabel();
makeKids();
if (internals) {
makeChild();
makeOpLabel();
makeStateLabel();
}
endOptional();
makeOperatorVector();
makeNonterminals();
if (internals) {
makeOperators();
makeStringArray();
makeRuleDescArray();
makeCostArray();
makeDeltaCostArray();
makeStateStringArray();
makeNonterminalArray();
/*
makeLHSmap();
*/
}
makeClosureArray();
if (diagnostics) {
reportDiagnostics();
}
yypurge();
exit(0);
}

135
utils/Burg/map.c Normal file
View File

@ -0,0 +1,135 @@
char rcsid_map[] = "$Id$";
#include <stdio.h>
#include <string.h>
#include "b.h"
#include "fe.h"
Mapping globalMap;
static void growMapping ARGS((Mapping));
static int hash ARGS((Item_Set, int));
Mapping
newMapping(size) int size;
{
Mapping m;
m = (Mapping) zalloc(sizeof(struct mapping));
assert(m);
m->count = 0;
m->hash = (List*) zalloc(size * sizeof(List));
m->hash_size = size;
m->max_size = STATES_INCR;
m->set = (Item_Set*) zalloc(m->max_size * sizeof(Item_Set));
assert(m->set);
return m;
}
static void
growMapping(m) Mapping m;
{
Item_Set *tmp;
m->max_size += STATES_INCR;
tmp = (Item_Set*) zalloc(m->max_size * sizeof(Item_Set));
memcpy(tmp, m->set, m->count * sizeof(Item_Set));
zfree(m->set);
m->set = tmp;
}
static int
hash(ts, mod) Item_Set ts; int mod;
{
register Item *p = ts->virgin;
register int v;
register Relevant r = ts->relevant;
register int nt;
if (!ts->op) {
return 0;
}
v = 0;
for (; (nt = *r) != 0; r++) {
v ^= ((int)p[nt].rule) + (PRINCIPLECOST(p[nt].delta)<<4);
}
v >>= 4;
v &= (mod-1);
return v;
}
Item_Set
encode(m, ts, new) Mapping m; Item_Set ts; int *new;
{
int h;
List l;
assert(m);
assert(ts);
assert(m->count <= m->max_size);
if (grammarNts && errorState && m == globalMap) {
List l;
int found;
found = 0;
for (l = grammarNts; l; l = l->next) {
Symbol s;
s = (Symbol) l->x;
if (ts->virgin[s->u.nt->num].rule) {
found = 1;
break;
}
}
if (!found) {
*new = 0;
return errorState;
}
}
*new = 0;
h = hash(ts, m->hash_size);
for (l = m->hash[h]; l; l = l->next) {
Item_Set s = (Item_Set) l->x;
if (ts->op == s->op && equivSet(ts, s)) {
ts->num = s->num;
return s;
}
}
if (m->count >= m->max_size) {
growMapping(m);
}
assert(m->count < m->max_size);
m->set[m->count] = ts;
ts->num = m->count++;
*new = 1;
m->hash[h] = newList(ts, m->hash[h]);
return ts;
}
Item_Set
decode(m, t) Mapping m; ItemSetNum t;
{
assert(m);
assert(t);
assert(m->count < m->max_size);
assert(t < m->count);
return m->set[t];
}
void
dumpMapping(m) Mapping m;
{
int i;
printf("BEGIN Mapping: Size=%d\n", m->count);
for (i = 0; i < m->count; i++) {
dumpItem_Set(m->set[i]);
}
printf("END Mapping\n");
}

49
utils/Burg/nonterminal.c Normal file
View File

@ -0,0 +1,49 @@
char rcsid_nonterminal[] = "$Id$";
#include "b.h"
#include <stdio.h>
NonTerminal start;
NonTerminalNum max_nonterminal = 1;
NonTerminalNum last_user_nonterminal;
List nonterminals;
NonTerminal
newNonTerminal(name) char *name;
{
NonTerminal nt;
nt = (NonTerminal) zalloc(sizeof(struct nonterminal));
assert(nt);
if (max_nonterminal == 1) {
start = nt;
}
nt->name = name;
nt->num = max_nonterminal++;
nonterminals = newList(nt, nonterminals);
return nt;
}
int
nonTerminalName(buf, i) char *buf; int i;
{
List l;
extern char *strcpy ARGS((char *, char *));
for (l = nonterminals; l; l = l->next) {
NonTerminal nt = (NonTerminal) l->x;
if (nt->num == i) {
strcpy(buf, nt->name);
return 1;
}
}
strcpy(buf, "(Unknown NonTerminal)");
return 0;
}
void
dumpNonTerminal(n) NonTerminal n;
{
printf("%s(%d)", n->name, n->num);
}

48
utils/Burg/operator.c Normal file
View File

@ -0,0 +1,48 @@
char rcsid_operator[] = "$Id$";
#include "b.h"
#include <stdio.h>
int max_arity = -1;
List operators;
List leaves;
Operator
newOperator(name, num, arity) char *name; OperatorNum num; ArityNum arity;
{
Operator op;
assert(arity <= MAX_ARITY);
op = (Operator) zalloc(sizeof(struct operator));
assert(op);
op->name = name;
op->num = num;
op->arity = arity;
operators = newList(op, operators);
return op;
}
void
dumpOperator_s(op) Operator op;
{
printf("Op: %s(%d)=%d\n", op->name, op->arity, op->num);
}
void
dumpOperator(op, full) Operator op; int full;
{
dumpOperator_s(op);
if (full) {
dumpTable(op->table, 0);
}
}
void
dumpOperator_l(op) Operator op;
{
dumpOperator(op, 1);
}

38
utils/Burg/pattern.c Normal file
View File

@ -0,0 +1,38 @@
char rcsid_pattern[] = "$Id$";
#include <stdio.h>
#include "b.h"
Pattern
newPattern(op) Operator op;
{
Pattern p;
p = (Pattern) zalloc(sizeof(struct pattern));
p->op = op;
return p;
}
void
dumpPattern(p) Pattern p;
{
int i;
if (!p) {
printf("[no-pattern]");
return;
}
if (p->op) {
printf("%s", p->op->name);
if (p->op->arity > 0) {
printf("(");
for (i = 0; i < p->op->arity; i++) {
printf("%s ", p->children[i]->name);
}
printf(")");
}
} else {
printf("%s", p->children[0]->name);
}
}

920
utils/Burg/plank.c Normal file
View File

@ -0,0 +1,920 @@
char rcsid_plank[] = "$Id$";
#include <stdio.h>
#include <string.h>
#include "b.h"
#include "fe.h"
#define ERROR_VAL 0
int speedflag = 0;
Item_Set *sortedStates;
static struct stateMapTable smt;
int exceptionTolerance = 0;
static int plankSize = 32;
static Plank newPlank ARGS((void));
static PlankMap newPlankMap ARGS((int));
static StateMap newStateMap ARGS((void));
static Exception newException ARGS((int, int));
static void enterStateMap ARGS((PlankMap, short *, int, int *));
static List assemblePlanks ARGS((void));
static void assignRules ARGS((RuleAST));
static int stateCompare ARGS((Item_Set *, Item_Set *));
static int ruleCompare ARGS((RuleAST *, RuleAST *));
static void renumber ARGS((void));
static short * newVector ARGS((void));
static int width ARGS((int));
static PlankMap mapToPmap ARGS((Dimension));
static void doDimPmaps ARGS((Operator));
static void doNonTermPmaps ARGS((NonTerminal));
static void makePmaps ARGS((void));
static void outPlank ARGS((Plank));
static void purgePlanks ARGS((List));
static void inToEx ARGS((void));
static void makePlankRuleMacros ARGS((void));
static void makePlankRule ARGS((void));
static void exceptionSwitch ARGS((List, char *, char *, char *, int, char *));
static void doPlankLabel ARGS((Operator));
static void doPlankLabelSafely ARGS((Operator));
static void doPlankLabelMacrosSafely ARGS((Operator));
static void makePlankState ARGS((void));
static Plank
newPlank()
{
Plank p;
char buf[50];
static int num = 0;
p = (Plank) zalloc(sizeof(struct plank));
sprintf(buf, "%s_plank_%d", prefix, num++);
p->name = (char *) zalloc(strlen(buf)+1);
strcpy(p->name, buf);
return p;
}
static PlankMap
newPlankMap(offset) int offset;
{
PlankMap im;
im = (PlankMap) zalloc(sizeof(struct plankMap));
im->offset = offset;
return im;
}
static StateMap
newStateMap()
{
char buf[50];
static int num = 0;
StateMap sm;
sm = (StateMap) zalloc(sizeof(struct stateMap));
sprintf(buf, "f%d", num++);
sm->fieldname = (char *) zalloc(strlen(buf)+1);
strcpy(sm->fieldname, buf);
return sm;
}
static Exception
newException(index, value) int index; int value;
{
Exception e;
e = (Exception) zalloc(sizeof(struct except));
e->index = index;
e->value = value;
return e;
}
static void
enterStateMap(im, v, width, new) PlankMap im; short * v; int width; int *new;
{
int i;
StateMap sm;
List l;
int size;
assert(im);
assert(v);
assert(width > 0);
size = globalMap->count;
for (l = smt.maps; l; l = l->next) {
int ecount;
sm = (StateMap) l->x;
ecount = 0;
for (i = 0; i < size; i++) {
if (v[i] != -1 && sm->value[i] != -1 && v[i] != sm->value[i]) {
if (++ecount > exceptionTolerance) {
goto again;
}
}
}
for (i = 0; i < size; i++) {
assert(v[i] >= 0);
assert(sm->value[i] >= 0);
if (v[i] == -1) {
continue;
}
if (sm->value[i] == -1) {
sm->value[i] = v[i];
} else if (v[i] != sm->value[i]) {
im->exceptions = newList(newException(i,v[i]), im->exceptions);
}
}
im->values = sm;
if (width > sm->width) {
sm->width = width;
}
*new = 0;
return;
again: ;
}
sm = newStateMap();
im->values = sm;
sm->value = v;
sm->width = width;
*new = 1;
smt.maps = newList(sm, smt.maps);
}
static List
assemblePlanks()
{
List planks = 0;
Plank pl;
List p;
List s;
for (s = smt.maps; s; s = s->next) {
StateMap sm = (StateMap) s->x;
for (p = planks; p; p = p->next) {
pl = (Plank) p->x;
if (sm->width <= plankSize - pl->width) {
pl->width += sm->width;
pl->fields = newList(sm, pl->fields);
sm->plank = pl;
goto next;
}
}
pl = newPlank();
pl->width = sm->width;
pl->fields = newList(sm, 0);
sm->plank = pl;
planks = appendList(pl, planks);
next: ;
}
return planks;
}
RuleAST *sortedRules;
static int count;
static void
assignRules(ast) RuleAST ast;
{
sortedRules[count++] = ast;
}
static int
stateCompare(s, t) Item_Set *s; Item_Set *t;
{
return strcmp((*s)->op->name, (*t)->op->name);
}
static int
ruleCompare(s, t) RuleAST *s; RuleAST *t;
{
return strcmp((*s)->lhs, (*t)->lhs);
}
void
dumpSortedStates()
{
int i;
printf("dump Sorted States: ");
for (i = 0; i < globalMap->count; i++) {
printf("%d ", sortedStates[i]->num);
}
printf("\n");
}
void
dumpSortedRules()
{
int i;
printf("dump Sorted Rules: ");
for (i = 0; i < max_ruleAST; i++) {
printf("%d ", sortedRules[i]->rule->erulenum);
}
printf("\n");
}
static void
renumber()
{
int i;
Operator previousOp;
NonTerminal previousLHS;
int base_counter;
sortedStates = (Item_Set*) zalloc(globalMap->count * sizeof(Item_Set));
for (i = 1; i < globalMap->count; i++) {
sortedStates[i-1] = globalMap->set[i];
}
qsort(sortedStates, globalMap->count-1, sizeof(Item_Set), stateCompare);
previousOp = 0;
for (i = 0; i < globalMap->count-1; i++) {
sortedStates[i]->newNum = i;
sortedStates[i]->op->stateCount++;
if (previousOp != sortedStates[i]->op) {
sortedStates[i]->op->baseNum = i;
previousOp = sortedStates[i]->op;
}
}
sortedRules = (RuleAST*) zalloc(max_ruleAST * sizeof(RuleAST));
count = 0;
foreachList((ListFn) assignRules, ruleASTs);
qsort(sortedRules, max_ruleAST, sizeof(RuleAST), ruleCompare);
previousLHS = 0;
base_counter = 0;
for (i = 0; i < max_ruleAST; i++) {
if (previousLHS != sortedRules[i]->rule->lhs) {
sortedRules[i]->rule->lhs->baseNum = base_counter;
previousLHS = sortedRules[i]->rule->lhs;
base_counter++; /* make space for 0 */
}
sortedRules[i]->rule->newNum = base_counter;
sortedRules[i]->rule->lhs->ruleCount++;
sortedRules[i]->rule->lhs->sampleRule = sortedRules[i]->rule; /* kludge for diagnostics */
base_counter++;
}
}
static short *
newVector()
{
short *p;
p = (short *) zalloc(globalMap->count* sizeof(short));
return p;
}
static int
width(v) int v;
{
int c;
for (c = 0; v; v >>= 1) {
c++;
}
return c;
}
static PlankMap
mapToPmap(d) Dimension d;
{
PlankMap im;
short *v;
int i;
int new;
if (d->map->count == 1) {
return 0;
}
assert(d->map->count > 1);
im = newPlankMap(0);
v = newVector();
for (i = 0; i < globalMap->count-1; i++) {
int index = d->map->set[d->index_map.class[sortedStates[i]->num]->num]->num;
assert(index >= 0);
v[i+1] = index;
}
v[0] = 0;
enterStateMap(im, v, width(d->map->count), &new);
if (!new) {
zfree(v);
}
return im;
}
static void
doDimPmaps(op) Operator op;
{
int i, j;
Dimension d;
short *v;
PlankMap im;
int new;
if (!op->table->rules) {
return;
}
switch (op->arity) {
case 0:
break;
case 1:
d = op->table->dimen[0];
if (d->map->count > 1) {
v = newVector();
im = newPlankMap(op->baseNum);
for (i = 0; i < globalMap->count-1; i++) {
int index = d->map->set[d->index_map.class[sortedStates[i]->num]->num]->num;
if (index) {
Item_Set *ts = transLval(op->table, index, 0);
v[i+1] = (*ts)->newNum - op->baseNum+1;
assert(v[i+1] >= 0);
}
}
enterStateMap(im, v, width(d->map->count-1), &new);
if (!new) {
zfree(v);
}
d->pmap = im;
}
break;
case 2:
if (op->table->dimen[0]->map->count == 1 && op->table->dimen[1]->map->count == 1) {
op->table->dimen[0]->pmap = 0;
op->table->dimen[1]->pmap = 0;
} else if (op->table->dimen[0]->map->count == 1) {
v = newVector();
im = newPlankMap(op->baseNum);
d = op->table->dimen[1];
for (i = 0; i < globalMap->count-1; i++) {
int index = d->map->set[d->index_map.class[sortedStates[i]->num]->num]->num;
if (index) {
Item_Set *ts = transLval(op->table, 1, index);
v[i+1] = (*ts)->newNum - op->baseNum+1;
assert(v[i+1] >= 0);
}
}
enterStateMap(im, v, width(d->map->count-1), &new);
if (!new) {
zfree(v);
}
d->pmap = im;
} else if (op->table->dimen[1]->map->count == 1) {
v = newVector();
im = newPlankMap(op->baseNum);
d = op->table->dimen[0];
for (i = 0; i < globalMap->count-1; i++) {
int index = d->map->set[d->index_map.class[sortedStates[i]->num]->num]->num;
if (index) {
Item_Set *ts = transLval(op->table, index, 1);
v[i +1] = (*ts)->newNum - op->baseNum +1;
assert(v[i +1] >= 0);
}
}
enterStateMap(im, v, width(d->map->count-1), &new);
if (!new) {
zfree(v);
}
d->pmap = im;
} else {
op->table->dimen[0]->pmap = mapToPmap(op->table->dimen[0]);
op->table->dimen[1]->pmap = mapToPmap(op->table->dimen[1]);
/* output table */
fprintf(outfile, "static unsigned %s %s_%s_transition[%d][%d] = {",
op->stateCount <= 255 ? "char" : "short",
prefix,
op->name,
op->table->dimen[0]->map->count,
op->table->dimen[1]->map->count);
for (i = 0; i < op->table->dimen[0]->map->count; i++) {
if (i > 0) {
fprintf(outfile, ",");
}
fprintf(outfile, "\n{");
for (j = 0; j < op->table->dimen[1]->map->count; j++) {
Item_Set *ts = transLval(op->table, i, j);
short diff;
if (j > 0) {
fprintf(outfile, ",");
if (j % 10 == 0) {
fprintf(outfile, "\t/* row %d, cols %d-%d*/\n",
i,
j-10,
j-1);
}
}
if ((*ts)->num > 0) {
diff = (*ts)->newNum - op->baseNum +1;
} else {
diff = 0;
}
fprintf(outfile, "%5d", diff);
}
fprintf(outfile, "}\t/* row %d */", i);
}
fprintf(outfile, "\n};\n");
}
break;
default:
assert(0);
}
}
static NonTerminal *ntVector;
static void
doNonTermPmaps(n) NonTerminal n;
{
short *v;
PlankMap im;
int new;
int i;
ntVector[n->num] = n;
if (n->num >= last_user_nonterminal) {
return;
}
if (n->ruleCount <= 0) {
return;
}
im = newPlankMap(n->baseNum);
v = newVector();
for (i = 0; i < globalMap->count-1; i++) {
Rule r = globalMap->set[sortedStates[i]->num]->closed[n->num].rule;
if (r) {
r->used = 1;
v[i+1] = r->newNum - n->baseNum /*safely*/;
assert(v[i+1] >= 0);
}
}
enterStateMap(im, v, width(n->ruleCount+1), &new);
if (!new) {
zfree(v);
}
n->pmap = im;
}
static void
makePmaps()
{
foreachList((ListFn) doDimPmaps, operators);
ntVector = (NonTerminal*) zalloc((max_nonterminal) * sizeof(NonTerminal));
foreachList((ListFn) doNonTermPmaps, nonterminals);
}
static void
outPlank(p) Plank p;
{
List f;
int i;
fprintf(outfile, "static struct {\n");
for (f = p->fields; f; f = f->next) {
StateMap sm = (StateMap) f->x;
fprintf(outfile, "\tunsigned int %s:%d;\n", sm->fieldname, sm->width);
}
fprintf(outfile, "} %s[] = {\n", p->name);
for (i = 0; i < globalMap->count; i++) {
fprintf(outfile, "\t{");
for (f = p->fields; f; f = f->next) {
StateMap sm = (StateMap) f->x;
fprintf(outfile, "%4d,", sm->value[i] == -1 ? ERROR_VAL : sm->value[i]);
}
fprintf(outfile, "},\t/* row %d */\n", i);
}
fprintf(outfile, "};\n");
}
static void
purgePlanks(planks) List planks;
{
List p;
for (p = planks; p; p = p->next) {
Plank x = (Plank) p->x;
outPlank(x);
}
}
static void
inToEx()
{
int i;
int counter;
fprintf(outfile, "static short %s_eruleMap[] = {\n", prefix);
counter = 0;
for (i = 0; i < max_ruleAST; i++) {
if (counter > 0) {
fprintf(outfile, ",");
if (counter % 10 == 0) {
fprintf(outfile, "\t/* %d-%d */\n", counter-10, counter-1);
}
}
if (counter < sortedRules[i]->rule->newNum) {
assert(counter == sortedRules[i]->rule->newNum-1);
fprintf(outfile, "%5d", 0);
counter++;
if (counter > 0) {
fprintf(outfile, ",");
if (counter % 10 == 0) {
fprintf(outfile, "\t/* %d-%d */\n", counter-10, counter-1);
}
}
}
fprintf(outfile, "%5d", sortedRules[i]->rule->erulenum);
counter++;
}
fprintf(outfile, "\n};\n");
}
static void
makePlankRuleMacros()
{
int i;
for (i = 1; i < last_user_nonterminal; i++) {
List es;
PlankMap im = ntVector[i]->pmap;
fprintf(outfile, "#define %s_%s_rule(state)\t", prefix, ntVector[i]->name);
if (im) {
fprintf(outfile, "%s_eruleMap[", prefix);
for (es = im->exceptions; es; es = es->next) {
Exception e = (Exception) es->x;
fprintf(outfile, "((state) == %d ? %d :",
e->index, e->value);
}
fprintf(outfile, "%s[state].%s",
im->values->plank->name,
im->values->fieldname);
for (es = im->exceptions; es; es = es->next) {
fprintf(outfile, ")");
}
fprintf(outfile, " +%d]", im->offset);
} else {
/* nonterminal never appears on LHS. */
assert(ntVector[i] == start);
fprintf(outfile, "0");
}
fprintf(outfile, "\n");
}
fprintf(outfile, "\n");
}
static void
makePlankRule()
{
int i;
makePlankRuleMacros();
fprintf(outfile, "#ifdef __STDC__\n");
fprintf(outfile, "int %s_rule(int state, int goalnt) {\n", prefix);
fprintf(outfile, "#else\n");
fprintf(outfile, "int %s_rule(state, goalnt) int state; int goalnt; {\n", prefix);
fprintf(outfile, "#endif\n");
fprintf(outfile,
"\t%s_assert(state >= 0 && state < %d, %s_PANIC(\"Bad state %%d passed to %s_rule\\n\", state));\n",
prefix, globalMap->count, prefix, prefix);
fprintf(outfile, "\tswitch(goalnt) {\n");
for (i = 1; i < last_user_nonterminal; i++) {
fprintf(outfile, "\tcase %d:\n", i);
fprintf(outfile, "\t\treturn %s_%s_rule(state);\n", prefix, ntVector[i]->name);
}
fprintf(outfile, "\tdefault:\n");
fprintf(outfile, "\t\t%s_PANIC(\"Unknown nonterminal %%d in %s_rule;\\n\", goalnt);\n", prefix, prefix);
fprintf(outfile, "\t\tabort();\n");
fprintf(outfile, "\t\treturn 0;\n");
fprintf(outfile, "\t}\n");
fprintf(outfile, "}\n");
}
static void
exceptionSwitch(es, sw, pre, post, offset, def) List es; char *sw; char *pre; char *post; int offset; char *def;
{
if (es) {
fprintf(outfile, "\t\tswitch (%s) {\n", sw);
for (; es; es = es->next) {
Exception e = (Exception) es->x;
fprintf(outfile, "\t\tcase %d: %s %d; %s\n", e->index, pre, e->value+offset, post);
}
if (def) {
fprintf(outfile, "\t\tdefault: %s;\n", def);
}
fprintf(outfile, "\t\t}\n");
} else {
if (def) {
fprintf(outfile, "\t\t%s;\n", def);
}
}
}
static void
doPlankLabel(op) Operator op;
{
PlankMap im0;
PlankMap im1;
char buf[100];
fprintf(outfile, "\tcase %d:\n", op->num);
switch (op->arity) {
case 0:
fprintf(outfile, "\t\treturn %d;\n", op->table->transition[0]->newNum);
break;
case 1:
im0 = op->table->dimen[0]->pmap;
if (im0) {
exceptionSwitch(im0->exceptions, "l", "return ", "", im0->offset, 0);
fprintf(outfile, "\t\treturn %s[l].%s + %d;\n",
im0->values->plank->name, im0->values->fieldname, im0->offset);
} else {
Item_Set *ts = transLval(op->table, 1, 0);
if (*ts) {
fprintf(outfile, "\t\treturn %d;\n", (*ts)->newNum);
} else {
fprintf(outfile, "\t\treturn %d;\n", ERROR_VAL);
}
}
break;
case 2:
im0 = op->table->dimen[0]->pmap;
im1 = op->table->dimen[1]->pmap;
if (!im0 && !im1) {
Item_Set *ts = transLval(op->table, 1, 1);
if (*ts) {
fprintf(outfile, "\t\treturn %d;\n", (*ts)->newNum);
} else {
fprintf(outfile, "\t\treturn %d;\n", ERROR_VAL);
}
} else if (!im0) {
exceptionSwitch(im1->exceptions, "r", "return ", "", im1->offset, 0);
fprintf(outfile, "\t\treturn %s[r].%s + %d;\n",
im1->values->plank->name, im1->values->fieldname, im1->offset);
} else if (!im1) {
exceptionSwitch(im0->exceptions, "l", "return ", "", im0->offset, 0);
fprintf(outfile, "\t\treturn %s[l].%s + %d;\n",
im0->values->plank->name, im0->values->fieldname, im0->offset);
} else {
assert(im0->offset == 0);
assert(im1->offset == 0);
sprintf(buf, "l = %s[l].%s",
im0->values->plank->name, im0->values->fieldname);
exceptionSwitch(im0->exceptions, "l", "l =", "break;", 0, buf);
sprintf(buf, "r = %s[r].%s",
im1->values->plank->name, im1->values->fieldname);
exceptionSwitch(im1->exceptions, "r", "r =", "break;", 0, buf);
fprintf(outfile, "\t\treturn %s_%s_transition[l][r] + %d;\n",
prefix,
op->name,
op->baseNum);
}
break;
default:
assert(0);
}
}
static void
doPlankLabelMacrosSafely(op) Operator op;
{
PlankMap im0;
PlankMap im1;
switch (op->arity) {
case -1:
fprintf(outfile, "#define %s_%s_state\t0\n", prefix, op->name);
break;
case 0:
fprintf(outfile, "#define %s_%s_state", prefix, op->name);
fprintf(outfile, "\t%d\n", op->table->transition[0]->newNum+1);
break;
case 1:
fprintf(outfile, "#define %s_%s_state(l)", prefix, op->name);
im0 = op->table->dimen[0]->pmap;
if (im0) {
if (im0->exceptions) {
List es = im0->exceptions;
assert(0);
fprintf(outfile, "\t\tswitch (l) {\n");
for (; es; es = es->next) {
Exception e = (Exception) es->x;
fprintf(outfile, "\t\tcase %d: return %d;\n", e->index, e->value ? e->value+im0->offset : 0);
}
fprintf(outfile, "\t\t}\n");
}
if (speedflag) {
fprintf(outfile, "\t( %s[l].%s + %d )\n",
im0->values->plank->name, im0->values->fieldname,
im0->offset);
} else {
fprintf(outfile, "\t( (%s_TEMP = %s[l].%s) ? %s_TEMP + %d : 0 )\n",
prefix,
im0->values->plank->name, im0->values->fieldname,
prefix,
im0->offset);
}
} else {
Item_Set *ts = transLval(op->table, 1, 0);
if (*ts) {
fprintf(outfile, "\t%d\n", (*ts)->newNum+1);
} else {
fprintf(outfile, "\t%d\n", 0);
}
}
break;
case 2:
fprintf(outfile, "#define %s_%s_state(l,r)", prefix, op->name);
im0 = op->table->dimen[0]->pmap;
im1 = op->table->dimen[1]->pmap;
if (!im0 && !im1) {
Item_Set *ts = transLval(op->table, 1, 1);
assert(0);
if (*ts) {
fprintf(outfile, "\t\treturn %d;\n", (*ts)->newNum+1);
} else {
fprintf(outfile, "\t\treturn %d;\n", 0);
}
} else if (!im0) {
assert(0);
if (im1->exceptions) {
List es = im1->exceptions;
fprintf(outfile, "\t\tswitch (r) {\n");
for (; es; es = es->next) {
Exception e = (Exception) es->x;
fprintf(outfile, "\t\tcase %d: return %d;\n", e->index, e->value ? e->value+im1->offset : 0);
}
fprintf(outfile, "\t\t}\n");
}
fprintf(outfile, "\t\tstate = %s[r].%s; offset = %d;\n",
im1->values->plank->name, im1->values->fieldname, im1->offset);
fprintf(outfile, "\t\tbreak;\n");
} else if (!im1) {
assert(0);
if (im0->exceptions) {
List es = im0->exceptions;
fprintf(outfile, "\t\tswitch (l) {\n");
for (; es; es = es->next) {
Exception e = (Exception) es->x;
fprintf(outfile, "\t\tcase %d: return %d;\n", e->index, e->value ? e->value+im0->offset : 0);
}
fprintf(outfile, "\t\t}\n");
}
fprintf(outfile, "\t\tstate = %s[l].%s; offset = %d;\n",
im0->values->plank->name, im0->values->fieldname, im0->offset);
fprintf(outfile, "\t\tbreak;\n");
} else {
assert(im0->offset == 0);
assert(im1->offset == 0);
/*
sprintf(buf, "l = %s[l].%s",
im0->values->plank->name, im0->values->fieldname);
exceptionSwitch(im0->exceptions, "l", "l =", "break;", 0, buf);
sprintf(buf, "r = %s[r].%s",
im1->values->plank->name, im1->values->fieldname);
exceptionSwitch(im1->exceptions, "r", "r =", "break;", 0, buf);
fprintf(outfile, "\t\tstate = %s_%s_transition[l][r]; offset = %d;\n",
prefix,
op->name,
op->baseNum);
fprintf(outfile, "\t\tbreak;\n");
*/
if (speedflag) {
fprintf(outfile, "\t( %s_%s_transition[%s[l].%s][%s[r].%s] + %d)\n",
prefix,
op->name,
im0->values->plank->name, im0->values->fieldname,
im1->values->plank->name, im1->values->fieldname,
op->baseNum);
} else {
fprintf(outfile, "\t( (%s_TEMP = %s_%s_transition[%s[l].%s][%s[r].%s]) ? ",
prefix,
prefix,
op->name,
im0->values->plank->name, im0->values->fieldname,
im1->values->plank->name, im1->values->fieldname);
fprintf(outfile, "%s_TEMP + %d : 0 )\n",
prefix,
op->baseNum);
}
}
break;
default:
assert(0);
}
}
static void
doPlankLabelSafely(op) Operator op;
{
fprintf(outfile, "\tcase %d:\n", op->num);
switch (op->arity) {
case -1:
fprintf(outfile, "\t\treturn 0;\n");
break;
case 0:
fprintf(outfile, "\t\treturn %s_%s_state;\n", prefix, op->name);
break;
case 1:
fprintf(outfile, "\t\treturn %s_%s_state(l);\n", prefix, op->name);
break;
case 2:
fprintf(outfile, "\t\treturn %s_%s_state(l,r);\n", prefix, op->name);
break;
default:
assert(0);
}
}
static void
makePlankState()
{
fprintf(outfile, "\n");
fprintf(outfile, "int %s_TEMP;\n", prefix);
foreachList((ListFn) doPlankLabelMacrosSafely, operators);
fprintf(outfile, "\n");
fprintf(outfile, "#ifdef __STDC__\n");
switch (max_arity) {
case -1:
fprintf(stderr, "ERROR: no terminals in grammar.\n");
exit(1);
case 0:
fprintf(outfile, "int %s_state(int op) {\n", prefix);
fprintf(outfile, "#else\n");
fprintf(outfile, "int %s_state(op) int op; {\n", prefix);
break;
case 1:
fprintf(outfile, "int %s_state(int op, int l) {\n", prefix);
fprintf(outfile, "#else\n");
fprintf(outfile, "int %s_state(op, l) int op; int l; {\n", prefix);
break;
case 2:
fprintf(outfile, "int %s_state(int op, int l, int r) {\n", prefix);
fprintf(outfile, "#else\n");
fprintf(outfile, "int %s_state(op, l, r) int op; int l; int r; {\n", prefix);
break;
default:
assert(0);
}
fprintf(outfile, "#endif\n");
fprintf(outfile, "\tregister int %s_TEMP;\n", prefix);
fprintf(outfile, "#ifndef NDEBUG\n");
fprintf(outfile, "\tswitch (op) {\n");
opsOfArity(2);
if (max_arity >= 2) {
fprintf(outfile,
"\t\t%s_assert(r >= 0 && r < %d, %s_PANIC(\"Bad state %%d passed to %s_state\\n\", r));\n",
prefix, globalMap->count, prefix, prefix);
fprintf(outfile, "\t\t/*FALLTHROUGH*/\n");
}
opsOfArity(1);
if (max_arity > 1) {
fprintf(outfile,
"\t\t%s_assert(l >= 0 && l < %d, %s_PANIC(\"Bad state %%d passed to %s_state\\n\", l));\n",
prefix, globalMap->count, prefix, prefix);
fprintf(outfile, "\t\t/*FALLTHROUGH*/\n");
}
opsOfArity(0);
fprintf(outfile, "\t\tbreak;\n");
fprintf(outfile, "\t}\n");
fprintf(outfile, "#endif\n");
fprintf(outfile, "\tswitch (op) {\n");
fprintf(outfile,"\tdefault: %s_PANIC(\"Unknown op %%d in %s_state\\n\", op); abort(); return 0;\n",
prefix, prefix);
foreachList((ListFn) doPlankLabelSafely, operators);
fprintf(outfile, "\t}\n");
fprintf(outfile, "}\n");
}
void
makePlanks()
{
List planks;
renumber();
makePmaps();
planks = assemblePlanks();
purgePlanks(planks);
inToEx();
makePlankRule();
makePlankState();
}

64
utils/Burg/queue.c Normal file
View File

@ -0,0 +1,64 @@
char rcsid_queue[] = "$Id$";
#include "b.h"
#include <stdio.h>
Queue globalQ;
Queue
newQ()
{
Queue q;
q = (Queue) zalloc(sizeof(struct queue));
assert(q);
q->head = 0;
q->tail = 0;
return q;
}
void
addQ(q, ts) Queue q; Item_Set ts;
{
List qe;
assert(q);
assert(ts);
qe = newList(ts, 0);
if (q->head) {
assert(q->tail);
q->tail->next = qe;
q->tail = qe;
} else {
q->head = q->tail = qe;
}
}
Item_Set
popQ(q) Queue q;
{
List qe;
Item_Set ts;
assert(q);
if (q->head) {
qe = q->head;
q->head = q->head->next;
ts = (Item_Set) qe->x;
zfree(qe);
return ts;
} else {
return 0;
}
}
void
dumpQ(q) Queue q;
{
printf("Begin Queue\n");
foreachList((ListFn)dumpItem_Set, q->head);
printf("End Queue\n");
}

49
utils/Burg/rule.c Normal file
View File

@ -0,0 +1,49 @@
char rcsid_rule[] = "$Id$";
#include "b.h"
#include <stdio.h>
RuleNum max_rule;
int max_erule_num;
struct rule stub_rule;
List rules;
Rule
newRule(delta, erulenum, lhs, pat) DeltaPtr delta; ERuleNum erulenum; NonTerminal lhs; Pattern pat;
{
Rule p;
p = (Rule) zalloc(sizeof(struct rule));
assert(p);
ASSIGNCOST(p->delta, delta);
p->erulenum = erulenum;
if (erulenum > max_erule_num) {
max_erule_num = erulenum;
}
p->num = max_rule++;
p->lhs = lhs;
p->pat = pat;
rules = newList(p, rules);
return p;
}
void
dumpRule(p) Rule p;
{
dumpNonTerminal(p->lhs);
printf(" : ");
dumpPattern(p->pat);
printf(" ");
dumpCost(p->delta);
printf("\n");
}
void
dumpRuleList(l) List l;
{
foreachList((ListFn)dumpRule, l);
}

150
utils/Burg/sample.gr Normal file
View File

@ -0,0 +1,150 @@
%{
#include <stdio.h>
typedef struct node *NODEPTR_TYPE;
struct node {
int op, state_label;
NODEPTR_TYPE left, right;
};
#define OP_LABEL(p) ((p)->op)
#define STATE_LABEL(p) ((p)->state_label)
#define LEFT_CHILD(p) ((p)->left)
#define RIGHT_CHILD(p) ((p)->right)
#define PANIC printf
%}
%start reg
%term Assign=1 Constant=2 Fetch=3 Four=4 Mul=5 Plus=6
%%
con: Constant = 1 (0);
con: Four = 2 (0);
addr: con = 3 (0);
addr: Plus(con,reg) = 4 (0);
addr: Plus(con,Mul(Four,reg)) = 5 (0);
reg: Fetch(addr) = 6 (1);
reg: Assign(addr,reg) = 7 (1);
%%
#define Assign 1
#define Constant 2
#define Fetch 3
#define Four 4
#define Mul 5
#define Plus 6
#ifdef __STDC__
#define ARGS(x) x
#else
#define ARGS(x) ()
#endif
NODEPTR_TYPE buildtree ARGS((int, NODEPTR_TYPE, NODEPTR_TYPE));
void printcover ARGS((NODEPTR_TYPE, int, int));
void printtree ARGS((NODEPTR_TYPE));
int treecost ARGS((NODEPTR_TYPE, int, int));
void printMatches ARGS((NODEPTR_TYPE));
int main ARGS((void));
NODEPTR_TYPE buildtree(op, left, right) int op; NODEPTR_TYPE left; NODEPTR_TYPE right; {
NODEPTR_TYPE p;
extern void *malloc ARGS((unsigned));
p = (NODEPTR_TYPE) malloc(sizeof *p);
p->op = op;
p->left = left;
p->right = right;
return p;
}
void printcover(p, goalnt, indent) NODEPTR_TYPE p; int goalnt; int indent; {
int eruleno = burm_rule(STATE_LABEL(p), goalnt);
short *nts = burm_nts[eruleno];
NODEPTR_TYPE kids[10];
int i;
if (eruleno == 0) {
printf("no cover\n");
return;
}
for (i = 0; i < indent; i++)
printf(".");
printf("%s\n", burm_string[eruleno]);
burm_kids(p, eruleno, kids);
for (i = 0; nts[i]; i++)
printcover(kids[i], nts[i], indent+1);
}
void printtree(p) NODEPTR_TYPE p; {
int op = burm_op_label(p);
printf("%s", burm_opname[op]);
switch (burm_arity[op]) {
case 0:
break;
case 1:
printf("(");
printtree(burm_child(p, 0));
printf(")");
break;
case 2:
printf("(");
printtree(burm_child(p, 0));
printf(", ");
printtree(burm_child(p, 1));
printf(")");
break;
}
}
int treecost(p, goalnt, costindex) NODEPTR_TYPE p; int goalnt; int costindex; {
int eruleno = burm_rule(STATE_LABEL(p), goalnt);
int cost = burm_cost[eruleno][costindex], i;
short *nts = burm_nts[eruleno];
NODEPTR_TYPE kids[10];
burm_kids(p, eruleno, kids);
for (i = 0; nts[i]; i++)
cost += treecost(kids[i], nts[i], costindex);
return cost;
}
void printMatches(p) NODEPTR_TYPE p; {
int nt;
int eruleno;
printf("Node 0x%lx= ", (unsigned long)p);
printtree(p);
printf(" matched rules:\n");
for (nt = 1; burm_ntname[nt] != (char*)NULL; nt++)
if ((eruleno = burm_rule(STATE_LABEL(p), nt)) != 0)
printf("\t%s\n", burm_string[eruleno]);
}
main() {
NODEPTR_TYPE p;
p = buildtree(Assign,
buildtree(Constant, 0, 0),
buildtree(Fetch,
buildtree(Plus,
buildtree(Constant, 0, 0),
buildtree(Mul,
buildtree(Four, 0, 0),
buildtree(Fetch, buildtree(Constant, 0, 0), 0)
)
),
0
)
);
printtree(p);
printf("\n\n");
burm_label(p);
printcover(p, 1, 0);
printf("\nCover cost == %d\n\n", treecost(p, 1, 0));
printMatches(p);
return 0;
}

65
utils/Burg/string.c Normal file
View File

@ -0,0 +1,65 @@
char rcsid_string[] = "$Id$";
#include <stdio.h>
#include <string.h>
#include "b.h"
#include "fe.h"
static StrTableElement newStrTableElement ARGS((void));
StrTable
newStrTable()
{
return (StrTable) zalloc(sizeof(struct strTable));
}
static StrTableElement
newStrTableElement()
{
return (StrTableElement) zalloc(sizeof(struct strTableElement));
}
void
dumpStrTable(t) StrTable t;
{
List e;
IntList r;
printf("Begin StrTable\n");
for (e = t->elems; e; e = e->next) {
StrTableElement el = (StrTableElement) e->x;
printf("%s: ", el->str);
for (r = el->erulenos; r; r = r->next) {
int i = r->x;
printf("(%d)", i);
}
printf("\n");
}
printf("End StrTable\n");
}
StrTableElement
addString(t, s, eruleno, new) StrTable t; char *s; int eruleno; int *new;
{
List l;
StrTableElement ste;
assert(t);
for (l = t->elems; l; l = l->next) {
StrTableElement e = (StrTableElement) l->x;
assert(e);
if (!strcmp(s, e->str)) {
e->erulenos = newIntList(eruleno, e->erulenos);
*new = 0;
return e;
}
}
ste = newStrTableElement();
ste->erulenos = newIntList(eruleno, 0);
ste->str = (char *) zalloc(strlen(s) + 1);
strcpy(ste->str, s);
t->elems = newList(ste, t->elems);
*new = 1;
return ste;
}

38
utils/Burg/symtab.c Normal file
View File

@ -0,0 +1,38 @@
char rcsid_symtab[] = "$Id$";
#include <stdio.h>
#include <string.h>
#include "b.h"
#include "fe.h"
static List symtab;
Symbol
newSymbol(name) char *name;
{
Symbol s;
s = (Symbol) zalloc(sizeof(struct symbol));
assert(s);
s->name = name;
return s;
}
Symbol
enter(name, new) char *name; int *new;
{
List l;
Symbol s;
*new = 0;
for (l = symtab; l; l = l->next) {
s = (Symbol) l->x;
if (!strcmp(name, s->name)) {
return s;
}
}
*new = 1;
s = newSymbol(name);
symtab = newList(s, symtab);
return s;
}

552
utils/Burg/table.c Normal file
View File

@ -0,0 +1,552 @@
char rcsid_table[] = "$Id$";
#include "b.h"
#include <string.h>
#include <stdio.h>
static void growIndex_Map ARGS((Index_Map *));
static Relevant newRelevant ARGS((void));
static Dimension newDimension ARGS((Operator, int));
static void GT_1 ARGS((Table));
static void GT_2_0 ARGS((Table));
static void GT_2_1 ARGS((Table));
static void growTransition ARGS((Table, int));
static Item_Set restrict ARGS((Dimension, Item_Set));
static void addHP_1 ARGS((Table, Item_Set));
static void addHP_2_0 ARGS((Table, Item_Set));
static void addHP_2_1 ARGS((Table, Item_Set));
static void addHyperPlane ARGS((Table, int, Item_Set));
static void
growIndex_Map(r) Index_Map *r;
{
Index_Map new;
new.max_size = r->max_size + STATES_INCR;
new.class = (Item_Set*) zalloc(new.max_size * sizeof(Item_Set));
assert(new.class);
memcpy(new.class, r->class, r->max_size * sizeof(Item_Set));
zfree(r->class);
*r = new;
}
static Relevant
newRelevant()
{
Relevant r = (Relevant) zalloc(max_nonterminal * sizeof(*r));
return r;
}
void
addRelevant(r, nt) Relevant r; NonTerminalNum nt;
{
int i;
for (i = 0; r[i]; i++) {
if (r[i] == nt) {
break;
}
}
if (!r[i]) {
r[i] = nt;
}
}
static Dimension
newDimension(op, index) Operator op; ArityNum index;
{
Dimension d;
List pl;
Relevant r;
assert(op);
assert(index >= 0 && index < op->arity);
d = (Dimension) zalloc(sizeof(struct dimension));
assert(d);
r = d->relevant = newRelevant();
for (pl = rules; pl; pl = pl->next) {
Rule pr = (Rule) pl->x;
if (pr->pat->op == op) {
addRelevant(r, pr->pat->children[index]->num);
}
}
d->index_map.max_size = STATES_INCR;
d->index_map.class = (Item_Set*)
zalloc(d->index_map.max_size * sizeof(Item_Set));
d->map = newMapping(DIM_MAP_SIZE);
d->max_size = TABLE_INCR;
return d;
}
Table
newTable(op) Operator op;
{
Table t;
int i, size;
assert(op);
t = (Table) zalloc(sizeof(struct table));
assert(t);
t->op = op;
for (i = 0; i < op->arity; i++) {
t->dimen[i] = newDimension(op, i);
}
size = 1;
for (i = 0; i < op->arity; i++) {
size *= t->dimen[i]->max_size;
}
t->transition = (Item_Set*) zalloc(size * sizeof(Item_Set));
t->relevant = newRelevant();
assert(t->transition);
return t;
}
static void
GT_1(t) Table t;
{
Item_Set *ts;
ItemSetNum oldsize = t->dimen[0]->max_size;
ItemSetNum newsize = t->dimen[0]->max_size + TABLE_INCR;
t->dimen[0]->max_size = newsize;
ts = (Item_Set*) zalloc(newsize * sizeof(Item_Set));
assert(ts);
memcpy(ts, t->transition, oldsize * sizeof(Item_Set));
zfree(t->transition);
t->transition = ts;
}
static void
GT_2_0(t) Table t;
{
Item_Set *ts;
ItemSetNum oldsize = t->dimen[0]->max_size;
ItemSetNum newsize = t->dimen[0]->max_size + TABLE_INCR;
int size;
t->dimen[0]->max_size = newsize;
size = newsize * t->dimen[1]->max_size;
ts = (Item_Set*) zalloc(size * sizeof(Item_Set));
assert(ts);
memcpy(ts, t->transition, oldsize*t->dimen[1]->max_size * sizeof(Item_Set));
zfree(t->transition);
t->transition = ts;
}
static void
GT_2_1(t) Table t;
{
Item_Set *ts;
ItemSetNum oldsize = t->dimen[1]->max_size;
ItemSetNum newsize = t->dimen[1]->max_size + TABLE_INCR;
int size;
Item_Set *from;
Item_Set *to;
int i1, i2;
t->dimen[1]->max_size = newsize;
size = newsize * t->dimen[0]->max_size;
ts = (Item_Set*) zalloc(size * sizeof(Item_Set));
assert(ts);
from = t->transition;
to = ts;
for (i1 = 0; i1 < t->dimen[0]->max_size; i1++) {
for (i2 = 0; i2 < oldsize; i2++) {
to[i2] = from[i2];
}
to += newsize;
from += oldsize;
}
zfree(t->transition);
t->transition = ts;
}
static void
growTransition(t, dim) Table t; ArityNum dim;
{
assert(t);
assert(t->op);
assert(dim < t->op->arity);
switch (t->op->arity) {
default:
assert(0);
break;
case 1:
GT_1(t);
return;
case 2:
switch (dim) {
default:
assert(0);
break;
case 0:
GT_2_0(t);
return;
case 1:
GT_2_1(t);
return;
}
}
}
static Item_Set
restrict(d, ts) Dimension d; Item_Set ts;
{
DeltaCost base;
Item_Set r;
int found;
register Relevant r_ptr = d->relevant;
register Item *ts_current = ts->closed;
register Item *r_current;
register int i;
register int nt;
ZEROCOST(base);
found = 0;
r = newItem_Set(d->relevant);
r_current = r->virgin;
for (i = 0; (nt = r_ptr[i]) != 0; i++) {
if (ts_current[nt].rule) {
r_current[nt].rule = &stub_rule;
if (!found) {
found = 1;
ASSIGNCOST(base, ts_current[nt].delta);
} else {
if (LESSCOST(ts_current[nt].delta, base)) {
ASSIGNCOST(base, ts_current[nt].delta);
}
}
}
}
/* zero align */
for (i = 0; (nt = r_ptr[i]) != 0; i++) {
if (r_current[nt].rule) {
ASSIGNCOST(r_current[nt].delta, ts_current[nt].delta);
MINUSCOST(r_current[nt].delta, base);
}
}
assert(!r->closed);
r->representative = ts;
return r;
}
static void
addHP_1(t, ts) Table t; Item_Set ts;
{
List pl;
Item_Set e;
Item_Set tmp;
int new;
e = newItem_Set(t->relevant);
assert(e);
e->kids[0] = ts->representative;
for (pl = t->rules; pl; pl = pl->next) {
Rule p = (Rule) pl->x;
if (t->op == p->pat->op && ts->virgin[p->pat->children[0]->num].rule) {
DeltaCost dc;
ASSIGNCOST(dc, ts->virgin[p->pat->children[0]->num].delta);
ADDCOST(dc, p->delta);
if (!e->virgin[p->lhs->num].rule || LESSCOST(dc, e->virgin[p->lhs->num].delta)) {
e->virgin[p->lhs->num].rule = p;
ASSIGNCOST(e->virgin[p->lhs->num].delta, dc);
e->op = t->op;
}
}
}
trim(e);
zero(e);
tmp = encode(globalMap, e, &new);
assert(ts->num < t->dimen[0]->map->max_size);
t->transition[ts->num] = tmp;
if (new) {
closure(e);
addQ(globalQ, tmp);
} else {
freeItem_Set(e);
}
}
static void
addHP_2_0(t, ts) Table t; Item_Set ts;
{
List pl;
register Item_Set e;
Item_Set tmp;
int new;
int i2;
assert(t->dimen[1]->map->count <= t->dimen[1]->map->max_size);
for (i2 = 0; i2 < t->dimen[1]->map->count; i2++) {
e = newItem_Set(t->relevant);
assert(e);
e->kids[0] = ts->representative;
e->kids[1] = t->dimen[1]->map->set[i2]->representative;
for (pl = t->rules; pl; pl = pl->next) {
register Rule p = (Rule) pl->x;
if (t->op == p->pat->op
&& ts->virgin[p->pat->children[0]->num].rule
&& t->dimen[1]->map->set[i2]->virgin[p->pat->children[1]->num].rule){
DeltaCost dc;
ASSIGNCOST(dc, p->delta);
ADDCOST(dc, ts->virgin[p->pat->children[0]->num].delta);
ADDCOST(dc, t->dimen[1]->map->set[i2]->virgin[p->pat->children[1]->num].delta);
if (!e->virgin[p->lhs->num].rule || LESSCOST(dc, e->virgin[p->lhs->num].delta)) {
e->virgin[p->lhs->num].rule = p;
ASSIGNCOST(e->virgin[p->lhs->num].delta, dc);
e->op = t->op;
}
}
}
trim(e);
zero(e);
tmp = encode(globalMap, e, &new);
assert(ts->num < t->dimen[0]->map->max_size);
t->transition[ts->num * t->dimen[1]->max_size + i2] = tmp;
if (new) {
closure(e);
addQ(globalQ, tmp);
} else {
freeItem_Set(e);
}
}
}
static void
addHP_2_1(t, ts) Table t; Item_Set ts;
{
List pl;
register Item_Set e;
Item_Set tmp;
int new;
int i1;
assert(t->dimen[0]->map->count <= t->dimen[0]->map->max_size);
for (i1 = 0; i1 < t->dimen[0]->map->count; i1++) {
e = newItem_Set(t->relevant);
assert(e);
e->kids[0] = t->dimen[0]->map->set[i1]->representative;
e->kids[1] = ts->representative;
for (pl = t->rules; pl; pl = pl->next) {
register Rule p = (Rule) pl->x;
if (t->op == p->pat->op
&& ts->virgin[p->pat->children[1]->num].rule
&& t->dimen[0]->map->set[i1]->virgin[p->pat->children[0]->num].rule){
DeltaCost dc;
ASSIGNCOST(dc, p->delta );
ADDCOST(dc, ts->virgin[p->pat->children[1]->num].delta);
ADDCOST(dc, t->dimen[0]->map->set[i1]->virgin[p->pat->children[0]->num].delta);
if (!e->virgin[p->lhs->num].rule || LESSCOST(dc, e->virgin[p->lhs->num].delta)) {
e->virgin[p->lhs->num].rule = p;
ASSIGNCOST(e->virgin[p->lhs->num].delta, dc);
e->op = t->op;
}
}
}
trim(e);
zero(e);
tmp = encode(globalMap, e, &new);
assert(ts->num < t->dimen[1]->map->max_size);
t->transition[i1 * t->dimen[1]->max_size + ts->num] = tmp;
if (new) {
closure(e);
addQ(globalQ, tmp);
} else {
freeItem_Set(e);
}
}
}
static void
addHyperPlane(t, i, ts) Table t; ArityNum i; Item_Set ts;
{
switch (t->op->arity) {
default:
assert(0);
break;
case 1:
addHP_1(t, ts);
return;
case 2:
switch (i) {
default:
assert(0);
break;
case 0:
addHP_2_0(t, ts);
return;
case 1:
addHP_2_1(t, ts);
return;
}
}
}
void
addToTable(t, ts) Table t; Item_Set ts;
{
ArityNum i;
assert(t);
assert(ts);
assert(t->op);
for (i = 0; i < t->op->arity; i++) {
Item_Set r;
Item_Set tmp;
int new;
r = restrict(t->dimen[i], ts);
tmp = encode(t->dimen[i]->map, r, &new);
if (t->dimen[i]->index_map.max_size <= ts->num) {
growIndex_Map(&t->dimen[i]->index_map);
}
assert(ts->num < t->dimen[i]->index_map.max_size);
t->dimen[i]->index_map.class[ts->num] = tmp;
if (new) {
if (t->dimen[i]->max_size <= r->num) {
growTransition(t, i);
}
addHyperPlane(t, i, r);
} else {
freeItem_Set(r);
}
}
}
Item_Set *
transLval(t, row, col) Table t; int row; int col;
{
switch (t->op->arity) {
case 0:
assert(row == 0);
assert(col == 0);
return t->transition;
case 1:
assert(col == 0);
return t->transition + row;
case 2:
return t->transition + row * t->dimen[1]->max_size + col;
default:
assert(0);
}
return 0;
}
void
dumpRelevant(r) Relevant r;
{
for (; *r; r++) {
printf("%4d", *r);
}
}
void
dumpIndex_Map(r) Index_Map *r;
{
int i;
printf("BEGIN Index_Map: MaxSize (%d)\n", r->max_size);
for (i = 0; i < globalMap->count; i++) {
printf("\t#%d: -> %d\n", i, r->class[i]->num);
}
printf("END Index_Map:\n");
}
void
dumpDimension(d) Dimension d;
{
printf("BEGIN Dimension:\n");
printf("Relevant: ");
dumpRelevant(d->relevant);
printf("\n");
dumpIndex_Map(&d->index_map);
dumpMapping(d->map);
printf("MaxSize of dimension = %d\n", d->max_size);
printf("END Dimension\n");
}
void
dumpTable(t, full) Table t; int full;
{
int i;
if (!t) {
printf("NO Table yet.\n");
return;
}
printf("BEGIN Table:\n");
if (full) {
dumpOperator(t->op, 0);
}
for (i = 0; i < t->op->arity; i++) {
printf("BEGIN dimension(%d)\n", i);
dumpDimension(t->dimen[i]);
printf("END dimension(%d)\n", i);
}
dumpTransition(t);
printf("END Table:\n");
}
void
dumpTransition(t) Table t;
{
int i,j;
switch (t->op->arity) {
case 0:
printf("{ %d }", t->transition[0]->num);
break;
case 1:
printf("{");
for (i = 0; i < t->dimen[0]->map->count; i++) {
if (i > 0) {
printf(",");
}
printf("%5d", t->transition[i]->num);
}
printf("}");
break;
case 2:
printf("{");
for (i = 0; i < t->dimen[0]->map->count; i++) {
if (i > 0) {
printf(",");
}
printf("\n");
printf("{");
for (j = 0; j < t->dimen[1]->map->count; j++) {
Item_Set *ts = transLval(t, i, j);
if (j > 0) {
printf(",");
}
printf("%5d", (*ts)->num);
}
printf("}");
}
printf("\n}\n");
break;
default:
assert(0);
}
}

412
utils/Burg/trim.c Normal file
View File

@ -0,0 +1,412 @@
char rcsid_trim[] = "$Id$";
#include <stdio.h>
#include "b.h"
#include "fe.h"
Relation *allpairs;
int trimflag = 0;
int debugTrim = 0;
static void siblings ARGS((int, int));
static void findAllNexts ARGS((void));
static Relation *newAllPairs ARGS((void));
static void
siblings(i, j) int i; int j;
{
int k;
List pl;
DeltaCost Max;
int foundmax;
allpairs[i][j].sibComputed = 1;
if (i == 1) {
return; /* never trim start symbol */
}
if (i==j) {
return;
}
ZEROCOST(Max);
foundmax = 0;
for (k = 1; k < max_nonterminal; k++) {
DeltaCost tmp;
if (k==i || k==j) {
continue;
}
if (!allpairs[k][i].rule) {
continue;
}
if (!allpairs[k][j].rule) {
return;
}
ASSIGNCOST(tmp, allpairs[k][j].chain);
MINUSCOST(tmp, allpairs[k][i].chain);
if (foundmax) {
if (LESSCOST(Max, tmp)) {
ASSIGNCOST(Max, tmp);
}
} else {
foundmax = 1;
ASSIGNCOST(Max, tmp);
}
}
for (pl = rules; pl; pl = pl->next) {
Rule p = (Rule) pl->x;
Operator op = p->pat->op;
List oprule;
DeltaCost Min;
int foundmin;
if (!op) {
continue;
}
switch (op->arity) {
case 0:
continue;
case 1:
if (!allpairs[p->pat->children[0]->num ][ i].rule) {
continue;
}
foundmin = 0;
for (oprule = op->table->rules; oprule; oprule = oprule->next) {
Rule s = (Rule) oprule->x;
DeltaPtr Cx;
DeltaPtr Csj;
DeltaPtr Cpi;
DeltaCost tmp;
if (!allpairs[p->lhs->num ][ s->lhs->num].rule
|| !allpairs[s->pat->children[0]->num ][ j].rule) {
continue;
}
Cx = allpairs[p->lhs->num ][ s->lhs->num].chain;
Csj= allpairs[s->pat->children[0]->num ][ j].chain;
Cpi= allpairs[p->pat->children[0]->num ][ i].chain;
ASSIGNCOST(tmp, Cx);
ADDCOST(tmp, s->delta);
ADDCOST(tmp, Csj);
MINUSCOST(tmp, Cpi);
MINUSCOST(tmp, p->delta);
if (foundmin) {
if (LESSCOST(tmp, Min)) {
ASSIGNCOST(Min, tmp);
}
} else {
foundmin = 1;
ASSIGNCOST(Min, tmp);
}
}
if (!foundmin) {
return;
}
if (foundmax) {
if (LESSCOST(Max, Min)) {
ASSIGNCOST(Max, Min);
}
} else {
foundmax = 1;
ASSIGNCOST(Max, Min);
}
break;
case 2:
/* do first dimension */
if (allpairs[p->pat->children[0]->num ][ i].rule) {
foundmin = 0;
for (oprule = op->table->rules; oprule; oprule = oprule->next) {
Rule s = (Rule) oprule->x;
DeltaPtr Cx;
DeltaPtr Cb;
DeltaPtr Csj;
DeltaPtr Cpi;
DeltaCost tmp;
if (allpairs[p->lhs->num ][ s->lhs->num].rule
&& allpairs[s->pat->children[0]->num ][ j].rule
&& allpairs[s->pat->children[1]->num ][ p->pat->children[1]->num].rule) {
Cx = allpairs[p->lhs->num ][ s->lhs->num].chain;
Csj= allpairs[s->pat->children[0]->num ][ j].chain;
Cpi= allpairs[p->pat->children[0]->num ][ i].chain;
Cb = allpairs[s->pat->children[1]->num ][ p->pat->children[1]->num].chain;
ASSIGNCOST(tmp, Cx);
ADDCOST(tmp, s->delta);
ADDCOST(tmp, Csj);
ADDCOST(tmp, Cb);
MINUSCOST(tmp, Cpi);
MINUSCOST(tmp, p->delta);
if (foundmin) {
if (LESSCOST(tmp, Min)) {
ASSIGNCOST(Min, tmp);
}
} else {
foundmin = 1;
ASSIGNCOST(Min, tmp);
}
}
}
if (!foundmin) {
return;
}
if (foundmax) {
if (LESSCOST(Max, Min)) {
ASSIGNCOST(Max, Min);
}
} else {
foundmax = 1;
ASSIGNCOST(Max, Min);
}
}
/* do second dimension */
if (allpairs[p->pat->children[1]->num ][ i].rule) {
foundmin = 0;
for (oprule = op->table->rules; oprule; oprule = oprule->next) {
Rule s = (Rule) oprule->x;
DeltaPtr Cx;
DeltaPtr Cb;
DeltaPtr Csj;
DeltaPtr Cpi;
DeltaCost tmp;
if (allpairs[p->lhs->num ][ s->lhs->num].rule
&& allpairs[s->pat->children[1]->num ][ j].rule
&& allpairs[s->pat->children[0]->num ][ p->pat->children[0]->num].rule) {
Cx = allpairs[p->lhs->num ][ s->lhs->num].chain;
Csj= allpairs[s->pat->children[1]->num ][ j].chain;
Cpi= allpairs[p->pat->children[1]->num ][ i].chain;
Cb = allpairs[s->pat->children[0]->num ][ p->pat->children[0]->num].chain;
ASSIGNCOST(tmp, Cx);
ADDCOST(tmp, s->delta);
ADDCOST(tmp, Csj);
ADDCOST(tmp, Cb);
MINUSCOST(tmp, Cpi);
MINUSCOST(tmp, p->delta);
if (foundmin) {
if (LESSCOST(tmp, Min)) {
ASSIGNCOST(Min, tmp);
}
} else {
foundmin = 1;
ASSIGNCOST(Min, tmp);
}
}
}
if (!foundmin) {
return;
}
if (foundmax) {
if (LESSCOST(Max, Min)) {
ASSIGNCOST(Max, Min);
}
} else {
foundmax = 1;
ASSIGNCOST(Max, Min);
}
}
break;
default:
assert(0);
}
}
allpairs[i ][ j].sibFlag = foundmax;
ASSIGNCOST(allpairs[i ][ j].sibling, Max);
}
static void
findAllNexts()
{
int i,j;
int last;
for (i = 1; i < max_nonterminal; i++) {
last = 0;
for (j = 1; j < max_nonterminal; j++) {
if (allpairs[i ][j].rule) {
allpairs[i ][ last].nextchain = j;
last = j;
}
}
}
/*
for (i = 1; i < max_nonterminal; i++) {
last = 0;
for (j = 1; j < max_nonterminal; j++) {
if (allpairs[i ][j].sibFlag) {
allpairs[i ][ last].nextsibling = j;
last = j;
}
}
}
*/
}
static Relation *
newAllPairs()
{
int i;
Relation *rv;
rv = (Relation*) zalloc(max_nonterminal * sizeof(Relation));
for (i = 0; i < max_nonterminal; i++) {
rv[i] = (Relation) zalloc(max_nonterminal * sizeof(struct relation));
}
return rv;
}
void
findAllPairs()
{
List pl;
int changes;
int j;
allpairs = newAllPairs();
for (pl = chainrules; pl; pl = pl->next) {
Rule p = (Rule) pl->x;
NonTerminalNum rhs = p->pat->children[0]->num;
NonTerminalNum lhs = p->lhs->num;
Relation r = &allpairs[lhs ][ rhs];
if (LESSCOST(p->delta, r->chain)) {
ASSIGNCOST(r->chain, p->delta);
r->rule = p;
}
}
for (j = 1; j < max_nonterminal; j++) {
Relation r = &allpairs[j ][ j];
ZEROCOST(r->chain);
r->rule = &stub_rule;
}
changes = 1;
while (changes) {
changes = 0;
for (pl = chainrules; pl; pl = pl->next) {
Rule p = (Rule) pl->x;
NonTerminalNum rhs = p->pat->children[0]->num;
NonTerminalNum lhs = p->lhs->num;
int i;
for (i = 1; i < max_nonterminal; i++) {
Relation r = &allpairs[rhs ][ i];
Relation s = &allpairs[lhs ][ i];
DeltaCost dc;
if (!r->rule) {
continue;
}
ASSIGNCOST(dc, p->delta);
ADDCOST(dc, r->chain);
if (!s->rule || LESSCOST(dc, s->chain)) {
s->rule = p;
ASSIGNCOST(s->chain, dc);
changes = 1;
}
}
}
}
findAllNexts();
}
void
trim(t) Item_Set t;
{
int m,n;
static short *vec = 0;
int last;
assert(!t->closed);
debug(debugTrim, printf("Begin Trim\n"));
debug(debugTrim, dumpItem_Set(t));
last = 0;
if (!vec) {
vec = (short*) zalloc(max_nonterminal * sizeof(*vec));
}
for (m = 1; m < max_nonterminal; m++) {
if (t->virgin[m].rule) {
vec[last++] = m;
}
}
for (m = 0; m < last; m++) {
DeltaCost tmp;
int j;
int i;
i = vec[m];
for (j = allpairs[i ][ 0].nextchain; j; j = allpairs[i ][ j].nextchain) {
if (i == j) {
continue;
}
if (!t->virgin[j].rule) {
continue;
}
ASSIGNCOST(tmp, t->virgin[j].delta);
ADDCOST(tmp, allpairs[i ][ j].chain);
if (!LESSCOST(t->virgin[i].delta, tmp)) {
t->virgin[i].rule = 0;
ZEROCOST(t->virgin[i].delta);
debug(debugTrim, printf("Trimmed Chain (%d,%d)\n", i,j));
goto outer;
}
}
if (!trimflag) {
continue;
}
for (n = 0; n < last; n++) {
j = vec[n];
if (i == j) {
continue;
}
if (!t->virgin[j].rule) {
continue;
}
if (!allpairs[i][j].sibComputed) {
siblings(i,j);
}
if (!allpairs[i][j].sibFlag) {
continue;
}
ASSIGNCOST(tmp, t->virgin[j].delta);
ADDCOST(tmp, allpairs[i ][ j].sibling);
if (!LESSCOST(t->virgin[i].delta, tmp)) {
t->virgin[i].rule = 0;
ZEROCOST(t->virgin[i].delta);
goto outer;
}
}
outer: ;
}
debug(debugTrim, dumpItem_Set(t));
debug(debugTrim, printf("End Trim\n"));
}
void
dumpRelation(r) Relation r;
{
printf("{ %d %ld %d %ld }", r->rule->erulenum, (long) r->chain, r->sibFlag, (long) r->sibling);
}
void
dumpAllPairs()
{
int i,j;
printf("Dumping AllPairs\n");
for (i = 1; i < max_nonterminal; i++) {
for (j = 1; j < max_nonterminal; j++) {
dumpRelation(&allpairs[i ][j]);
}
printf("\n");
}
}

35
utils/Burg/zalloc.c Normal file
View File

@ -0,0 +1,35 @@
char rcsid_zalloc[] = "$Id$";
#include <stdio.h>
#include <string.h>
#include "b.h"
extern void exit ARGS((int));
extern void free ARGS((void *));
extern void *malloc ARGS((unsigned));
int
fatal(name, line) char *name; int line;
{
fprintf(stderr, "assertion failed: file %s, line %d\n", name, line);
exit(1);
return 0;
}
void *
zalloc(size) unsigned int size;
{
void *t = (void *) malloc(size);
if (!t) {
fprintf(stderr, "Malloc failed---PROGRAM ABORTED\n");
exit(1);
}
memset(t, 0, size);
return t;
}
void
zfree(p) void *p;
{
free(p);
}