mirror of
https://github.com/RPCS3/llvm.git
synced 2024-11-26 21:20:29 +00:00
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:
parent
24b70926d5
commit
633a5b1aac
13
support/tools/Burg/COPYRIGHT
Normal file
13
support/tools/Burg/COPYRIGHT
Normal 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
support/tools/Burg/LOG_CHANGES
Normal file
2
support/tools/Burg/LOG_CHANGES
Normal file
@ -0,0 +1,2 @@
|
||||
8/20/02 -- Vikram Adve
|
||||
be.c: Replaced "char*" with "const char*" to avoid compiler warnings.
|
84
support/tools/Burg/Makefile
Normal file
84
support/tools/Burg/Makefile
Normal 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
14
support/tools/Burg/README
Normal 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
311
support/tools/Burg/b.h
Normal 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
1052
support/tools/Burg/be.c
Normal file
File diff suppressed because it is too large
Load Diff
BIN
support/tools/Burg/burg.shar.gz
Normal file
BIN
support/tools/Burg/burg.shar.gz
Normal file
Binary file not shown.
71
support/tools/Burg/burs.c
Normal file
71
support/tools/Burg/burs.c
Normal 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
support/tools/Burg/closure.c
Normal file
95
support/tools/Burg/closure.c
Normal 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
143
support/tools/Burg/delta.c
Normal 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
403
support/tools/Burg/fe.c
Normal 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
127
support/tools/Burg/fe.h
Normal 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
90
support/tools/Burg/gram.y
Normal 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
133
support/tools/Burg/item.c
Normal 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
260
support/tools/Burg/lex.c
Normal 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
75
support/tools/Burg/list.c
Normal 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
182
support/tools/Burg/main.c
Normal 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
135
support/tools/Burg/map.c
Normal 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
support/tools/Burg/nonterminal.c
Normal file
49
support/tools/Burg/nonterminal.c
Normal 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
support/tools/Burg/operator.c
Normal file
48
support/tools/Burg/operator.c
Normal 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
support/tools/Burg/pattern.c
Normal file
38
support/tools/Burg/pattern.c
Normal 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
920
support/tools/Burg/plank.c
Normal 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
support/tools/Burg/queue.c
Normal file
64
support/tools/Burg/queue.c
Normal 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
49
support/tools/Burg/rule.c
Normal 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
support/tools/Burg/sample.gr
Normal file
150
support/tools/Burg/sample.gr
Normal 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
support/tools/Burg/string.c
Normal file
65
support/tools/Burg/string.c
Normal 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
support/tools/Burg/symtab.c
Normal file
38
support/tools/Burg/symtab.c
Normal 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
552
support/tools/Burg/table.c
Normal 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
412
support/tools/Burg/trim.c
Normal 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
support/tools/Burg/zalloc.c
Normal file
35
support/tools/Burg/zalloc.c
Normal 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
13
utils/Burg/COPYRIGHT
Normal 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
2
utils/Burg/LOG_CHANGES
Normal 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
84
utils/Burg/Makefile
Normal 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
14
utils/Burg/README
Normal 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
311
utils/Burg/b.h
Normal 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
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
BIN
utils/Burg/burg.shar.gz
Normal file
Binary file not shown.
71
utils/Burg/burs.c
Normal file
71
utils/Burg/burs.c
Normal 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
95
utils/Burg/closure.c
Normal 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
143
utils/Burg/delta.c
Normal 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
403
utils/Burg/fe.c
Normal 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
127
utils/Burg/fe.h
Normal 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
90
utils/Burg/gram.y
Normal 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
133
utils/Burg/item.c
Normal 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
260
utils/Burg/lex.c
Normal 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
75
utils/Burg/list.c
Normal 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
182
utils/Burg/main.c
Normal 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
135
utils/Burg/map.c
Normal 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
49
utils/Burg/nonterminal.c
Normal 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
48
utils/Burg/operator.c
Normal 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
38
utils/Burg/pattern.c
Normal 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
920
utils/Burg/plank.c
Normal 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
64
utils/Burg/queue.c
Normal 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
49
utils/Burg/rule.c
Normal 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
150
utils/Burg/sample.gr
Normal 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
65
utils/Burg/string.c
Normal 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
38
utils/Burg/symtab.c
Normal 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
552
utils/Burg/table.c
Normal 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
412
utils/Burg/trim.c
Normal 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
35
utils/Burg/zalloc.c
Normal 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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user