Strip out surplus files. Rewrite README.
This commit is contained in:
parent
5cb3fbb3d3
commit
03b7202e54
|
@ -1,39 +0,0 @@
|
|||
Tue Aug 12 10:03:34 PDT 1997
|
||||
|
||||
makefile:
|
||||
Customized for use under NT.
|
||||
|
||||
gram.y:
|
||||
Fixed diagnostic formatting, handled cases when \n doesn't terminate
|
||||
the input buffer; protected against versions of fgets that touch
|
||||
buffer at EOF.
|
||||
|
||||
sample4.brg:
|
||||
Changed state value from int to long for 64-bit machines.
|
||||
|
||||
|
||||
Tue May 7 14:20:11 PDT 1996
|
||||
|
||||
The distribution now includes the RCS files.
|
||||
Specific changes are as follows; thanks to Francisco Arzu
|
||||
(farzu@uvg.edu.gt) for these suggestions.
|
||||
|
||||
gram.y:
|
||||
Changed TERM to TERMINAL for bison.
|
||||
Moved definition of yylineno for bison.
|
||||
Changed hard-coded 32767 to maxcost, and checked
|
||||
only costs against maxcost.
|
||||
Replaced 0s in calls with NULL.
|
||||
|
||||
iburg.1:
|
||||
Document STATE_TYPE, -maxcost=ddd, and use of SHRT_MAX.
|
||||
|
||||
iburg.c:
|
||||
Implemented STATE_TYPE, default int.
|
||||
Changed 32767 to maxcost, which is SHRT_MAX, SHRT_MAX/2
|
||||
(when sizeof(int)==sizeof(short)), or maxcost. Included limits.h.
|
||||
|
||||
|
||||
Thu May 12 11:33:48 EDT 1994
|
||||
|
||||
initial release.
|
|
@ -9,3 +9,4 @@ all the mcgg extensions).
|
|||
|
||||
iburg is licensed under the MIT open source license; see the LICENSE file.
|
||||
|
||||
|
||||
|
|
|
@ -1,285 +0,0 @@
|
|||
.TH IBURG 1 "local \- 1/26/93"
|
||||
.\" $Id$
|
||||
.SH NAME
|
||||
iburg \- code generator generator
|
||||
.SH SYNOPSIS
|
||||
.B iburg
|
||||
[
|
||||
.I option
|
||||
]...
|
||||
[ [
|
||||
.I input
|
||||
]
|
||||
.I output
|
||||
]
|
||||
.br
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
.I iburg
|
||||
reads BURG specification from
|
||||
.I input
|
||||
and writes a pattern-matching code generator to
|
||||
.IR output .
|
||||
If
|
||||
.I input
|
||||
is `\-' or is omitted,
|
||||
.I iburg
|
||||
reads the standard input;
|
||||
If
|
||||
.I output
|
||||
is `\-' or is omitted,
|
||||
.I iburg
|
||||
writes to the standard output.
|
||||
.PP
|
||||
.I iburg
|
||||
accepts BURG specifications that conform to the following EBNF grammar.
|
||||
Terminals are enclosed in single quotes, all other symbols are nonterminals,
|
||||
{X} denotes zero or more instances of X, and [X] denotes an optional X.
|
||||
.PP
|
||||
.nf
|
||||
.RS
|
||||
.ft CW
|
||||
spec: { dcl } `%%' { rule } [ `%%' ]
|
||||
|
||||
dcl: `%start' nonterm
|
||||
`%term' { identifier `=' integer }
|
||||
|
||||
rule: nonterm `:' tree `=' integer [ cost ] `;'
|
||||
|
||||
cost: `(' integer ')'
|
||||
|
||||
tree: term `(' tree `,' tree `)'
|
||||
term `(' tree `)'
|
||||
term
|
||||
nonterm
|
||||
.RE
|
||||
.fi
|
||||
.PP
|
||||
Specifications are structurally similar to
|
||||
.IR yacc 's.
|
||||
Text between
|
||||
`\f(CW%{\fP'
|
||||
and
|
||||
`\f(CW%}\fP'
|
||||
is called the configuration section; there may be several such segments.
|
||||
All are concatenated and copied verbatim into the head of the generated
|
||||
parser, which is called burm.
|
||||
Text after the second
|
||||
`\f(CW%%\fP',
|
||||
if any, is also copied verbatim into
|
||||
.IR burm ,
|
||||
at the end.
|
||||
.PP
|
||||
Specifications consist of declarations, a
|
||||
`\f(CW%%\fP'
|
||||
separator, and rules.
|
||||
Input is line-oriented; each declaration and rule must appear on a separate line,
|
||||
and declarations must begin in column 1.
|
||||
Declarations declare terminals \(em the operators in subject
|
||||
trees \(em and associate a unique, positive external symbol
|
||||
number with each one.
|
||||
Non-terminals are declared by their presence
|
||||
on the left side of rules. The
|
||||
\f(CW%start\fP
|
||||
declaration optionally declares a non-terminal as the start symbol.
|
||||
In the grammar above,
|
||||
\f(CWterm\fP
|
||||
and
|
||||
\f(CWnonterm\fP
|
||||
denote identifiers that are terminals and non-terminals, respectively.
|
||||
.PP
|
||||
Rules define tree patterns in a fully parenthesized prefix
|
||||
form. Every non-terminal denotes a tree.
|
||||
Each operator has a fixed
|
||||
arity, which is inferred from the rules in which it is used.
|
||||
A chain rule is a rule whose pattern is another non-terminal.
|
||||
If no start symbol is declared, the non-terminal defined by the first rule is used.
|
||||
.PP
|
||||
Each rule has a unique, positive external rule number, which
|
||||
comes after the pattern and is preceded by a
|
||||
`\f(CW=\fP'.
|
||||
External rule numbers are used to report the
|
||||
matching rule to a user-supplied semantic action routine.
|
||||
Rules end with an optional non-negative, integer cost; omitted costs
|
||||
default to zero.
|
||||
.PP
|
||||
The display below shows a fragment of a BURG specification.
|
||||
This example uses upper-case for terminals and lower-case for non-terminals.
|
||||
.PP
|
||||
.nf
|
||||
.ft CW
|
||||
%{
|
||||
enum { ADDI=309, ADDRLP=295, ASGNI=53,
|
||||
CNSTI=21, CVCI=85, I0I=661, INDIRC=67 };
|
||||
|
||||
typedef struct tree {
|
||||
int op;
|
||||
struct tree *kids[2];
|
||||
int val;
|
||||
struct { int state; } x;
|
||||
} *NODEPTR_TYPE, *Tree;
|
||||
#define LEFT_CHILD(p) ((p)->kids[0])
|
||||
#define RIGHT_CHILD(p) ((p)->kids[1])
|
||||
#define PANIC printf
|
||||
#define STATE_LABEL(p) ((p)->x.state)
|
||||
|
||||
int OP_LABEL(NODEPTR_TYPE p) {
|
||||
switch (p->op) {
|
||||
case CNSTI: if (p->val == 0) return 661 /* I0I */;
|
||||
default: return p->op;
|
||||
}
|
||||
}
|
||||
%}
|
||||
%term ADDI=309 ADDRLP=295 ASGNI=53
|
||||
%term CNSTI=21 CVCI=85 I0I=661 INDIRC=67
|
||||
%%
|
||||
stmt: ASGNI(disp,reg) = 4 (1);
|
||||
stmt: reg = 5;
|
||||
reg: ADDI(reg,rc) = 6 (1);
|
||||
reg: CVCI(INDIRC(disp)) = 7 (1);
|
||||
reg: I0I = 8;
|
||||
reg: disp = 9 (1);
|
||||
disp: ADDI(reg,con) = 10;
|
||||
disp: ADDRLP = 11;
|
||||
rc: con = 12;
|
||||
rc: reg = 13;
|
||||
con: CNSTI = 14;
|
||||
con: I0I = 15;
|
||||
%%
|
||||
.fi
|
||||
.PP
|
||||
The configuration section configures
|
||||
\f(CWburm\fP
|
||||
for the trees being parsed and the client's environment.
|
||||
As shown, this section must define
|
||||
\f(CWNODEPTR_TYPE\fP
|
||||
to be a visible typedef symbol for a pointer to a
|
||||
node in the subject tree.
|
||||
\f(CWburm\fP
|
||||
invokes
|
||||
\f(CWOP_LABEL(p)\fP,
|
||||
\f(CWLEFT\_CHILD(p)\fP, and
|
||||
\f(CWRIGHT\_CHILD(p)\fP
|
||||
to read the operator and children from the node pointed to by \f(CWp\fP.
|
||||
It invokes
|
||||
\f(CWPANIC\fP
|
||||
when it detects an error.
|
||||
If the configuration section defines these operations as macros, they are implemented in-line;
|
||||
otherwise, they must be implemented as functions.
|
||||
.PP
|
||||
By default,
|
||||
\f(CWburm\fP
|
||||
computes and stores a single integral state in each node of the subject tree.
|
||||
The configuration section must define a macro
|
||||
\f(CWSTATE_LABEL(p)\fP
|
||||
to access the state field of the node pointed to
|
||||
by \f(CWp\fP. It must be large enough to hold a pointer, and
|
||||
a macro is required because it is used as an lvalue.
|
||||
The configuration section may define the macro
|
||||
\f(CWSTATE_TYPE\fP
|
||||
to specify a different type for state values; if
|
||||
\f(CWSTATE_TYPE\fP
|
||||
is not defined, int is used.
|
||||
.PP
|
||||
The configuration section may also define
|
||||
\f(CWALLOC(n)\fP
|
||||
for allocating
|
||||
\f(CWn\fP
|
||||
bytes.
|
||||
If
|
||||
\f(CWALLOC\fP
|
||||
is not defined,
|
||||
.IR malloc (3)
|
||||
is used.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.BI \-p \ prefix
|
||||
.br
|
||||
.ns
|
||||
.TP
|
||||
.BI \-p prefix
|
||||
Use
|
||||
.I prefix
|
||||
as the disambiquating prefix for exported names and visible fields.
|
||||
The default is `\f(CWburm\fP'.
|
||||
.TP
|
||||
.BI \-maxcost= ddd
|
||||
Use the integral value
|
||||
.I ddd
|
||||
as the maximum cost.
|
||||
The default is \f(CWSHRT_MAX\fR
|
||||
when ints are bigger than shorts, and
|
||||
\f(CWSHRT_MAX\fP/2 when ints and shorts are the same size.
|
||||
.TP
|
||||
.B \-I
|
||||
Emit code for the following data values and functions.
|
||||
.sp
|
||||
.nf
|
||||
.ft CW
|
||||
char burm_arity[];
|
||||
char *burm_opname[];
|
||||
char *burm_ntname[];
|
||||
char *burm_string[];
|
||||
short burm_cost[][4];
|
||||
int burm_op_label(NODEPTR_TYPE p);
|
||||
NODEPTR_TYPE burm_child(NODEPTR_TYPE p, int index);
|
||||
STATE_TYPE burm_state_label(NODEPTR_TYPE p);
|
||||
.sp
|
||||
.fi
|
||||
.ft R
|
||||
\f(CWburm_arity\fP and
|
||||
\f(CWburm_opname\fP
|
||||
are indexed by external symbol numbers and gives their arities.
|
||||
\f(CWburm_ntname\fP
|
||||
is indexed by a non-terminal number and gives its string name.
|
||||
\f(CWburm_string\fP
|
||||
and
|
||||
\f(CWburm_cost\fP
|
||||
are indexed by an external rule number and give the string
|
||||
representation and cost of each rule.
|
||||
The functions encapsulate the similarly named macros.
|
||||
.TP
|
||||
.B \-T
|
||||
Arrange for
|
||||
.sp
|
||||
.nf
|
||||
.ft CW
|
||||
void burm_trace(NODEPTR_TYPE p, int eruleno,
|
||||
int cost, int bestcost);
|
||||
.sp
|
||||
.fi
|
||||
.ft R
|
||||
to be called at each successful match.
|
||||
\f(CWp\fP
|
||||
identifies the node and
|
||||
\f(CWeruleno\fP
|
||||
identifies the matching rule;
|
||||
\f(CWeruleno\fP
|
||||
is an index into \f(CWburm_string\fP.
|
||||
\f(CWcost\fP
|
||||
is the cost of the match and
|
||||
\f(CWbestcost\fP
|
||||
is the cost of the best previous match. The current match
|
||||
wins only if
|
||||
\f(CWcost\fP
|
||||
is less than \f(CWbestcost\fP.
|
||||
SHRT_MAX represents the infinite cost of no previous match.
|
||||
\f(CWburm_trace\fP must be declared in the configuration section.
|
||||
.SH "SEE ALSO"
|
||||
C. W. Fraser, R. R. Henry and T. A. Proebsting,
|
||||
`BURG \(em Fast optimal instruction selection and tree parsing,'
|
||||
.I
|
||||
SIGPLAN Notices
|
||||
.BR 27 ,
|
||||
4 (Apr. 1992), 68-76.
|
||||
.PP
|
||||
C. W. Fraser, D. R. Hanson and T. A. Proebsting,
|
||||
`Engineering a simple, efficient code generator generator,'
|
||||
.I
|
||||
ACM Letters on Programming Languages and Systems
|
||||
.BR 1 ,
|
||||
3 (Sep. 1992), 213-226.
|
||||
.br
|
||||
.SH BUGS
|
||||
Mail bug reports along with the shortest input
|
||||
that exposes them to drh@drhanson.net.
|
|
@ -1,23 +0,0 @@
|
|||
# $Id$
|
||||
O=.o
|
||||
E=
|
||||
CFLAGS=
|
||||
LDFLAGS=
|
||||
YFLAGS=
|
||||
OBJS=iburg$O gram$O
|
||||
CUSTOM=custom.mk
|
||||
include $(CUSTOM)
|
||||
|
||||
iburg$E: $(OBJS); $(CC) -o $@ $(LDFLAGS) $(OBJS)
|
||||
|
||||
$(OBJS): iburg.h
|
||||
|
||||
test: iburg$E sample4.brg sample5.brg
|
||||
./iburg$E -I sample4.brg sample4.c; $(CC) -o test4$E sample4.c; ./test4$E
|
||||
./iburg$E -I sample5.brg sample5.c; $(CC) -o test5$E sample5.c; ./test5$E
|
||||
|
||||
clean::
|
||||
rm -f *$O core sample*.c a.out test4$E test5$E
|
||||
|
||||
clobber:: clean
|
||||
rm -f y.tab.c gram.tab.c iburg$E
|
|
@ -1,109 +0,0 @@
|
|||
%{
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
enum {
|
||||
ADDI=309, ADDRLP=295, ASGNI=53,
|
||||
CNSTI=21, CVCI=85, I0I=661, INDIRC=67
|
||||
};
|
||||
|
||||
#define STATE_TYPE long
|
||||
typedef struct tree {
|
||||
int op;
|
||||
struct tree *kids[2];
|
||||
int val;
|
||||
struct { STATE_TYPE state; } x;
|
||||
} *NODEPTR_TYPE, *Tree;
|
||||
#define LEFT_CHILD(p) ((p)->kids[0])
|
||||
#define RIGHT_CHILD(p) ((p)->kids[1])
|
||||
#define PANIC printf
|
||||
#define STATE_LABEL(p) ((p)->x.state)
|
||||
|
||||
int OP_LABEL(NODEPTR_TYPE p) {
|
||||
switch (p->op) {
|
||||
case CNSTI: if (p->val == 0) return 661 /* I0I */;
|
||||
default: return p->op;
|
||||
}
|
||||
}
|
||||
|
||||
static void burm_trace(NODEPTR_TYPE, int, int, int);
|
||||
%}
|
||||
%term ADDI=309 ADDRLP=295 ASGNI=53
|
||||
%term CNSTI=21 CVCI=85 I0I=661 INDIRC=67
|
||||
%%
|
||||
stmt: ASGNI(disp,reg) = 4 (1);
|
||||
stmt: reg = 5;
|
||||
reg: ADDI(reg,rc) = 6 (1);
|
||||
reg: CVCI(INDIRC(disp)) = 7 (1);
|
||||
reg: I0I = 8;
|
||||
reg: disp = 9 (1);
|
||||
disp: ADDI(reg,con) = 10;
|
||||
disp: ADDRLP = 11;
|
||||
rc: con = 12;
|
||||
rc: reg = 13;
|
||||
con: CNSTI = 14;
|
||||
con: I0I = 15;
|
||||
%%
|
||||
|
||||
static int trace;
|
||||
|
||||
/* burm_trace - print trace message for matching p; decrement trace */
|
||||
static void burm_trace(NODEPTR_TYPE p, int eruleno, int cost, int bestcost) {
|
||||
if (trace < 0)
|
||||
fprintf(stderr, "0x%p matched %s = %d with cost %d vs. %d\n", p,
|
||||
burm_string[eruleno], eruleno, cost, bestcost);
|
||||
else if (trace > 0 && cost < bestcost) {
|
||||
--trace;
|
||||
fprintf(stderr, "0x%p matched %s = %d with cost %d\n", p,
|
||||
burm_string[eruleno], eruleno, cost);
|
||||
}
|
||||
}
|
||||
|
||||
/* dumpCover - print the matched cover for p */
|
||||
static void dumpCover(Tree p, int goalnt, int indent) {
|
||||
int eruleno = burm_rule(p->x.state, goalnt);
|
||||
short *nts = burm_nts[eruleno];
|
||||
Tree kids[10];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < indent; i++)
|
||||
fprintf(stderr, " ");
|
||||
fprintf(stderr, "%s\n", burm_string[eruleno]);
|
||||
burm_kids(p, eruleno, kids);
|
||||
for (i = 0; nts[i]; i++)
|
||||
dumpCover(kids[i], nts[i], indent + 1);
|
||||
}
|
||||
|
||||
static void gen(NODEPTR_TYPE p) {
|
||||
if (burm_label(p) == 0)
|
||||
fprintf(stderr, "no cover\n");
|
||||
else
|
||||
dumpCover(p, 1, 0);
|
||||
}
|
||||
|
||||
static Tree tree(int op, Tree l, Tree r) {
|
||||
Tree t = malloc(sizeof *t);
|
||||
|
||||
t->op = op;
|
||||
t->kids[0] = l; t->kids[1] = r;
|
||||
t->val = 0;
|
||||
t->x.state = 0;
|
||||
return t;
|
||||
}
|
||||
|
||||
main(void) {
|
||||
Tree t;
|
||||
|
||||
if (getenv("Trace"))
|
||||
trace = atoi(getenv("Trace"));
|
||||
printf("i = c + 4;\n");
|
||||
t = tree(ASGNI,
|
||||
tree(ADDRLP, 0, 0),
|
||||
tree(ADDI,
|
||||
tree(CVCI, tree(INDIRC, tree(ADDRLP, 0, 0), 0), 0),
|
||||
(t = tree(CNSTI, 0, 0), t->val = 4, t)
|
||||
)
|
||||
);
|
||||
gen(t);
|
||||
return 0;
|
||||
}
|
|
@ -1,85 +0,0 @@
|
|||
%{
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define TRACE
|
||||
|
||||
enum { MOVE=1, MEM=2, PLUS=3, NAME=4, CONST=6 };
|
||||
|
||||
#define STATE_TYPE void*
|
||||
typedef struct tree {
|
||||
int op;
|
||||
struct tree *kids[2];
|
||||
STATE_TYPE state_label;
|
||||
} *NODEPTR_TYPE;
|
||||
#define OP_LABEL(p) ((p)->op)
|
||||
#define LEFT_CHILD(p) ((p)->kids[0])
|
||||
#define RIGHT_CHILD(p) ((p)->kids[1])
|
||||
#define STATE_LABEL(p) ((p)->state_label)
|
||||
#define PANIC printf
|
||||
|
||||
static void burm_trace(NODEPTR_TYPE p, int eruleno, int cost, int bestcost) {
|
||||
#ifdef TRACE
|
||||
extern char *burm_string[];
|
||||
|
||||
fprintf(stderr, "0x%p matched %s with cost %d vs. %d\n", p,
|
||||
burm_string[eruleno], cost, bestcost);
|
||||
#endif
|
||||
}
|
||||
%}
|
||||
%term MOVE=1 MEM=2 PLUS=3 NAME=4 CONST=6
|
||||
%%
|
||||
stm: MOVE(MEM(loc),reg) = 1 (4);
|
||||
|
||||
reg: PLUS(con,reg) = 2 (3);
|
||||
reg: PLUS(reg,reg) = 3 (2);
|
||||
reg: PLUS(MEM(loc),reg) = 4 (4);
|
||||
reg: MEM(loc) = 5 (4);
|
||||
reg: con = 6 (2);
|
||||
|
||||
loc: reg = 7;
|
||||
loc: NAME = 8;
|
||||
loc: PLUS(NAME,reg) = 9;
|
||||
|
||||
con: CONST = 10;
|
||||
%%
|
||||
static void dumpCover(NODEPTR_TYPE p, int goalnt, int indent) {
|
||||
#ifdef TRACE
|
||||
int eruleno = burm_rule(STATE_LABEL(p), goalnt);
|
||||
short *nts = burm_nts[eruleno];
|
||||
NODEPTR_TYPE kids[10];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < indent; i++)
|
||||
fprintf(stderr, " ");
|
||||
fprintf(stderr, "%s\n", burm_string[eruleno]);
|
||||
burm_kids(p, eruleno, kids);
|
||||
for (i = 0; nts[i]; i++)
|
||||
dumpCover(kids[i], nts[i], indent + 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
static NODEPTR_TYPE tree(int op, NODEPTR_TYPE l, NODEPTR_TYPE r) {
|
||||
NODEPTR_TYPE p = malloc(sizeof *p);
|
||||
|
||||
assert(p);
|
||||
p->op = op;
|
||||
p->kids[0] = l; p->kids[1] = r;
|
||||
return p;
|
||||
}
|
||||
|
||||
main(void) {
|
||||
NODEPTR_TYPE p;
|
||||
|
||||
p = tree(MOVE,
|
||||
tree(MEM, tree(NAME, 0, 0), 0),
|
||||
tree(PLUS,
|
||||
tree(MEM, tree(PLUS,
|
||||
tree(NAME, 0, 0),
|
||||
tree(MEM, tree(NAME, 0, 0), 0)), 0),
|
||||
tree(CONST, 0, 0) ) );
|
||||
burm_label(p);
|
||||
dumpCover(p, 1, 0);
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue