Burg not needed any more now that SparcV9 is gone.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@27901 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Reid Spencer 2006-04-20 18:39:19 +00:00
parent a29526275b
commit 63ed92e882
38 changed files with 1 additions and 6495 deletions

View File

@ -1,2 +0,0 @@
gram.tab.c
gram.tab.h

View File

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

View File

@ -1,92 +0,0 @@
##===- utils/Burg/Doc/Makefile ------------------------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
# This file was developed by the LLVM research group and is distributed under
# the University of Illinois Open Source License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
# $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

View File

@ -1,50 +0,0 @@
\relax
\bibstyle{alpha}
\citation{aho-twig-toplas}
\citation{appel-87}
\citation{balachandran-complang}
\citation{kron-phd}
\citation{hoffmann-jacm}
\citation{hatcher-popl}
\citation{chase-popl}
\citation{pelegri-popl}
\citation{pelegri-phd}
\citation{wilhelm-tr}
\citation{henry-budp}
\citation{fraser-henry-spe-91}
\citation{proebsting-91}
\@writefile{toc}{\contentsline {section}{\numberline {1}Overview}{1}}
\@writefile{toc}{\contentsline {section}{\numberline {2}Input}{1}}
\@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces A Sample Tree Grammar}}{2}}
\newlabel{fig-tree-grammar}{{1}{2}}
\@writefile{lof}{\contentsline {figure}{\numberline {2}{\ignorespaces EBNF Grammar for Tree Grammars for {\sc Burg}\ }}{3}}
\newlabel{fig-grammar-grammar}{{2}{3}}
\@writefile{toc}{\contentsline {section}{\numberline {3}Output}{3}}
\citation{aho-johnson-dp-classic}
\citation{fraser-henry-spe-91}
\citation{henry-budp}
\citation{pelegri-phd}
\@writefile{toc}{\contentsline {section}{\numberline {4}Debugging}{6}}
\@writefile{toc}{\contentsline {section}{\numberline {5}Running {\sc Burg}\ }{6}}
\newlabel{sec-man-page}{{5}{6}}
\citation{pelegri-popl}
\citation{henry-budp}
\citation{balachandran-complang}
\citation{proebsting-91}
\@writefile{lof}{\contentsline {figure}{\numberline {3}{\ignorespaces A Diverging Tree Grammar}}{7}}
\newlabel{fig-diverge-grammar}{{3}{7}}
\@writefile{toc}{\contentsline {section}{\numberline {6}Acknowledgements}{7}}
\bibcite{aho-twig-toplas}{AGT89}
\bibcite{aho-johnson-dp-classic}{AJ76}
\bibcite{appel-87}{App87}
\bibcite{balachandran-complang}{BDB90}
\bibcite{wilhelm-tr}{BMW87}
\bibcite{chase-popl}{Cha87}
\bibcite{fraser-henry-spe-91}{FH91}
\bibcite{hatcher-popl}{HC86}
\bibcite{henry-budp}{Hen89}
\bibcite{hoffmann-jacm}{HO82}
\bibcite{kron-phd}{Kro75}
\bibcite{pelegri-phd}{PL87}
\bibcite{pelegri-popl}{PLG88}
\bibcite{proebsting-91}{Pro91}

Binary file not shown.

View File

@ -1,157 +0,0 @@
This is TeX, Version 3.14159 (Web2C 7.3.2) (format=latex 2000.8.30) 4 JUN 2001 13:20
**doc
(doc.tex
LaTeX2e <2000/06/01>
(/usr/dcs/software/supported/encap/TeX/share/texmf/tex/latex/base/latex209.def
File: latex209.def 1998/05/13 v0.52 Standard LaTeX file
Entering LaTeX 2.09 COMPATIBILITY MODE
*************************************************************
!!WARNING!! !!WARNING!! !!WARNING!! !!WARNING!!
This mode attempts to provide an emulation of the LaTeX 2.09
author environment so that OLD documents can be successfully
processed. It should NOT be used for NEW documents!
New documents should use Standard LaTeX conventions and start
with the \documentclass command.
Compatibility mode is UNLIKELY TO WORK with LaTeX 2.09 style
files that change any internal macros, especially not with
those that change the FONT SELECTION or OUTPUT ROUTINES.
Therefore such style files MUST BE UPDATED to use
Current Standard LaTeX: LaTeX2e.
If you suspect that you may be using such a style file, which
is probably very, very old by now, then you should attempt to
get it updated by sending a copy of this error message to the
author of that file.
*************************************************************
\footheight=\dimen102
\@maxsep=\dimen103
\@dblmaxsep=\dimen104
\@cla=\count79
\@clb=\count80
\mscount=\count81
(/usr/dcs/software/supported/encap/TeX/share/texmf/tex/latex/base/tracefnt.sty
Package: tracefnt 1997/05/29 v3.0j Standard LaTeX package (font tracing)
\tracingfonts=\count82
LaTeX Info: Redefining \selectfont on input line 96.
)
\symbold=\mathgroup4
\symsans=\mathgroup5
\symtypewriter=\mathgroup6
\symitalic=\mathgroup7
\symsmallcaps=\mathgroup8
\symslanted=\mathgroup9
LaTeX Font Info: Redeclaring math alphabet \mathbf on input line 288.
LaTeX Font Info: Redeclaring math alphabet \mathsf on input line 289.
LaTeX Font Info: Redeclaring math alphabet \mathtt on input line 290.
LaTeX Font Info: Redeclaring math alphabet \mathit on input line 296.
LaTeX Info: Redefining \em on input line 306.
(/usr/dcs/software/supported/encap/TeX/share/texmf/tex/latex/base/latexsym.sty
Package: latexsym 1998/08/17 v2.2e Standard LaTeX package (lasy symbols)
\symlasy=\mathgroup10
LaTeX Font Info: Overwriting symbol font `lasy' in version `bold'
(Font) U/lasy/m/n --> U/lasy/b/n on input line 42.
)
LaTeX Font Info: Redeclaring math delimiter \lgroup on input line 370.
LaTeX Font Info: Redeclaring math delimiter \rgroup on input line 372.
LaTeX Font Info: Redeclaring math delimiter \bracevert on input line 374.
(/usr/dcs/software/supported/encap/TeX/share/texmf/tex/latex/config/latex209.cf
g
(/usr/dcs/software/supported/encap/TeX/share/texmf/tex/latex/tools/rawfonts.sty
Compatibility mode: package `' requested, but `rawfonts' provided.
Package: rawfonts 1994/05/08 Low-level LaTeX 2.09 font compatibility
(/usr/dcs/software/supported/encap/TeX/share/texmf/tex/latex/tools/somedefs.sty
Package: somedefs 1994/06/01 Toolkit for optional definitions
)
LaTeX Font Info: Try loading font information for U+lasy on input line 44.
(/usr/dcs/software/supported/encap/TeX/share/texmf/tex/latex/base/ulasy.fd
File: ulasy.fd 1998/08/17 v2.2eLaTeX symbol font definitions
)))) (/usr/dcs/software/supported/encap/TeX/share/texmf/tex/latex/base/article.
cls
Document Class: article 2000/05/19 v1.4b Standard LaTeX document class
(/usr/dcs/software/supported/encap/TeX/share/texmf/tex/latex/base/size11.clo
File: size11.clo 2000/05/19 v1.4b Standard LaTeX file (size option)
)
\c@part=\count83
\c@section=\count84
\c@subsection=\count85
\c@subsubsection=\count86
\c@paragraph=\count87
\c@subparagraph=\count88
\c@figure=\count89
\c@table=\count90
\abovecaptionskip=\skip41
\belowcaptionskip=\skip42
Compatibility mode: definition of \rm ignored.
Compatibility mode: definition of \sf ignored.
Compatibility mode: definition of \tt ignored.
Compatibility mode: definition of \bf ignored.
Compatibility mode: definition of \it ignored.
Compatibility mode: definition of \sl ignored.
Compatibility mode: definition of \sc ignored.
LaTeX Info: Redefining \cal on input line 501.
LaTeX Info: Redefining \mit on input line 502.
\bibindent=\dimen105
)
(/usr/dcs/software/supported/encap/TeX/share/texmf/tex/latex/pstex/fullpage.sty
) (doc.aux)
\openout1 = `doc.aux'.
LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 2.
LaTeX Font Info: ... okay on input line 2.
LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 2.
LaTeX Font Info: ... okay on input line 2.
LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 2.
LaTeX Font Info: ... okay on input line 2.
LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 2.
LaTeX Font Info: ... okay on input line 2.
LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 2.
LaTeX Font Info: ... okay on input line 2.
LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 2.
LaTeX Font Info: ... okay on input line 2.
LaTeX Font Info: External font `cmex10' loaded for size
(Font) <12> on input line 33.
LaTeX Font Info: External font `cmex10' loaded for size
(Font) <8> on input line 33.
LaTeX Font Info: External font `cmex10' loaded for size
(Font) <6> on input line 33.
LaTeX Font Info: Try loading font information for OMS+cmtt on input line 100
.
LaTeX Font Info: No file OMScmtt.fd. on input line 100.
LaTeX Font Warning: Font shape `OMS/cmtt/m/n' undefined
(Font) using `OMS/cmsy/m/n' instead
(Font) for symbol `textbraceleft' on input line 100.
[1
]
LaTeX Font Info: External font `cmex10' loaded for size
(Font) <10.95> on input line 150.
[2] [3] [4] [5] [6]
Overfull \hbox (1.38191pt too wide) in paragraph at lines 480--484
[]\OT1/cmr/m/n/10.95 Emit code for \OT1/cmtt/m/n/10.95 burm[]arity\OT1/cmr/m/n/
10.95 , \OT1/cmtt/m/n/10.95 burm[]child\OT1/cmr/m/n/10.95 , \OT1/cmtt/m/n/10.95
burm[]cost\OT1/cmr/m/n/10.95 , \OT1/cmtt/m/n/10.95 burm[]ntname\OT1/cmr/m/n/10
.95 , \OT1/cmtt/m/n/10.95 burm[]op[]label\OT1/cmr/m/n/10.95 , \OT1/cmtt/m/n/10.
95 burm[]opname\OT1/cmr/m/n/10.95 ,
[]
[7] [8] [9] (doc.aux)
LaTeX Font Warning: Some font shapes were not available, defaults substituted.
)
Here is how much of TeX's memory you used:
543 strings out of 12968
6147 string characters out of 289029
446019 words of memory out of 1453895
3433 multiletter control sequences out of 10000+10000
23403 words of font info for 87 fonts, out of 400000 for 2000
14 hyphenation exceptions out of 1000
21i,6n,20p,308b,283s stack positions out of 300i,100n,500p,50000b,4000s
Output written on doc.dvi (9 pages, 29856 bytes).

View File

@ -1,596 +0,0 @@
\documentstyle[11pt,fullpage]{article}
\begin{document}
\def\AddSpace#1{\ifcat#1a\ \fi#1} % if next is a letter, add a space
\def\YACC#1{{\sc Yacc}\AddSpace#1}
\def\TWIG#1{{\sc Twig}\AddSpace#1}
\def\PROG#1{{\sc Burg}\AddSpace#1}
\def\PARSER#1{{\sc Burm}\AddSpace#1}
\def\CODEGEN#1{{\sc Codegen}\AddSpace#1}
\title{{\sc Burg} --- Fast Optimal Instruction Selection and Tree Parsing}
\author{
Christopher W. Fraser \\
AT\&T Bell Laboratories \\
600 Mountain Avenue 2C-464 \\
Murray Hill, NJ 07974-0636 \\
{\tt cwf@research.att.com}
\and
Robert R. Henry \\
Tera Computer Company \\
400 N. 34th St., Suite 300 \\
Seattle, WA 98103-8600 \\
{\tt rrh@tera.com}
\and
Todd A. Proebsting \\
Dept. of Computer Sciences \\
University of Wisconsin \\
Madison, WI 53706 \\
{\tt todd@cs.wisc.edu}
}
\date{December 1991}
\maketitle
\bibliographystyle{alpha}
\newcommand\term[1]{{\it #1}}
\newcommand\secref[1]{\S\ref{#1}}
\newcommand\figref[1]{Figure~\ref{#1}}
%
% rationale table making
%
{\catcode`\^^M=13 \gdef\Obeycr{\catcode`\^^M=13 \def^^M{\\}}%
\gdef\Restorecr{\catcode`\^^M=5 }} %
%
% for printing out options
%
\newcommand\option[1]{% #1=option character
{\tt -#1}%
}
\newcommand\var[1]{%
{\tt #1}%
}
\section{Overview}
\PROG is a program that generates a fast tree parser using BURS
(Bottom-Up Rewrite System) technology. It accepts a cost-augmented
tree grammar and emits a C program that discovers in linear time an
optimal parse of trees in the language described by the grammar. \PROG
has been used to construct fast optimal instruction selectors for use
in code generation. \PROG addresses many of the problems addressed by
{\sc Twig}~\cite{aho-twig-toplas,appel-87}, but it is somewhat less flexible and
much faster. \PROG is available via anonymous \var{ftp} from
\var{kaese.cs.wisc.edu}. The compressed \var{shar} file
\var{pub/burg.shar.Z} holds the complete distribution.
This document describes only that fraction of the BURS model that is
required to use \PROG. Readers interested in more detail might start
with Reference~\cite{balachandran-complang}. Other relevant documents
include References~\cite{kron-phd,hoffmann-jacm,hatcher-popl,chase-popl,pelegri-popl,pelegri-phd,wilhelm-tr,henry-budp,fraser-henry-spe-91,proebsting-91}.
\section{Input}
\PROG accepts a tree grammar and emits a BURS tree parser.
\figref{fig-tree-grammar} shows a sample grammar that implements a very
simple instruction selector.
\begin{figure}
\begin{verbatim}
%{
#define NODEPTR_TYPE treepointer
#define OP_LABEL(p) ((p)->op)
#define LEFT_CHILD(p) ((p)->left)
#define RIGHT_CHILD(p) ((p)->right)
#define STATE_LABEL(p) ((p)->state_label)
#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);
\end{verbatim}
\caption{A Sample Tree Grammar\label{fig-tree-grammar}}
\end{figure}
\PROG grammars are structurally similar to \YACC's. Comments follow C
conventions. Text between ``\var{\%\{}'' and ``\var{\%\}}'' is called
the \term{configuration section}; there may be several such segments.
All are concatenated and copied verbatim into the head of the generated
parser, which is called \PARSER. Text after the second ``\var{\%\%}'',
if any, is also copied verbatim into \PARSER, at the end.
The configuration section configures \PARSER for the trees being parsed
and the client's environment. This section must define
\var{NODEPTR\_TYPE} to be a visible typedef symbol for a pointer to a
node in the subject tree. \PARSER invokes \var{OP\_LABEL(p)},
\var{LEFT\_CHILD(p)}, and \var{RIGHT\_CHILD(p)} to read the operator
and children from the node pointed to by \var{p}. It invokes
\var{PANIC} 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. The section on
diagnostics elaborates on \var{PANIC}.
\PARSER computes and stores a single integral \term{state} in each node
of the subject tree. The configuration section must define a macro
\var{STATE\_LABEL(p)} to access the state field of the node pointed to
by \var{p}. A macro is required because \PROG uses it as an lvalue. A
C \var{short} is usually the right choice; typical code generation
grammars require 100--1000 distinct state labels.
The tree grammar follows the configuration section.
\figref{fig-grammar-grammar} gives an EBNF grammar for \PROG tree
grammars.
\begin{figure}
\begin{verbatim}
grammar: {dcl} '%%' {rule}
dcl: '%start' Nonterminal
dcl: '%term' { Identifier '=' Integer }
rule: Nonterminal ':' tree '=' Integer cost ';'
cost: /* empty */
cost: '(' Integer { ',' Integer } ')'
tree: Term '(' tree ',' tree ')'
tree: Term '(' tree ')'
tree: Term
tree: Nonterminal
\end{verbatim}
\caption{EBNF Grammar for Tree Grammars for \PROG\ \label{fig-grammar-grammar}}
\end{figure}
Comments, the text between ``\var{\%\{}'' and ``\var{\%\}}'', and the
text after the optional second ``\var{\%\%}'' are treated lexically, so
the figure omits them. In the EBNF grammar, quoted text must appear
literally, \var{Nonterminal} and \var{Integer} are self-explanatory,
and \var{Term} denotes an identifier previously declared as a
terminal. {\tt\{$X$\}} denotes zero or more instances of $X$.
Text before the first ``\var{\%\%}'' declares the start symbol and the
terminals or operators in subject trees. All terminals must be
declared; each line of such declarations begins with \var{\%term}.
Each terminal has fixed arity, which \PROG infers from the rules using that terminal.
\PROG restricts terminals to have at most two children. Each terminal
is declared with a positive, unique, integral \term{external symbol
number} after a ``\var{=}''. \var{OP\_LABEL(p)} must return the valid
external symbol number for \var{p}. Ideally, external symbol numbers
form a dense enumeration. Non-terminals are not declared, but the
start symbol may be declared with a line that begins with
\var{\%start}.
Text after the first ``\var{\%\%}'' declares the rules. A tree grammar
is like a context-free grammar: it has rules, non-terminals,
terminals, and a special start non-terminal. The right-hand side of a
rule, called the \term{pattern}, is a tree. Tree patterns appear in
prefix parenthesized form. Every non-terminal denotes a tree. A chain
rule is a rule whose pattern is another non-terminal. If no start
symbol is declared, \PROG uses the non-terminal defined by the first
rule. \PROG needs a single start symbol; grammars for which it is
natural to use multiple start symbols must be augmented with an
artificial start symbol that derives, with zero cost, the grammar's
natural start symbols. \PARSER will automatically select one
that costs least for any given tree.
\PROG accepts no embedded semantic actions like \YACC's, because no one
format suited all intended applications. Instead, each rule has a
positive, unique, integral \term{external rule number}, after the
pattern and preceded by a ``\var{=}''. Ideally, external rule numbers
form a dense enumeration. \PARSER uses these numbers to report the
matching rule to a user-supplied routine, which must implement any
desired semantic action; see below. Humans may select these integers
by hand, but \PROG is intended as a \term{server} for building BURS
tree parsers. Thus some \PROG clients will consume a richer
description and translate it into \PROG's simpler input.
Rules end with a vector of non-negative, integer costs, in parentheses
and separated by commas. If the cost vector is omitted, then all
elements are assumed to be zero. \PROG retains only the first four
elements of the list. The cost of a derivation is the sum of the costs
for all rules applied in the derivation. Arithmetic on cost vectors
treats each member of the vector independently. The tree parser finds
the cheapest parse of the subject tree. It breaks ties arbitrarily.
By default, \PROG uses only the \term{principal cost} of each cost
vector, which defaults to the first element, but options described
below provide alternatives.
\section{Output}
\PARSER traverses the subject tree twice. The first pass or
\term{labeller} runs bottom-up and left-to-right, visiting each node
exactly once. Each node is labeled with a state, a single number that
encodes all full and partial optimal pattern matches viable at that
node. The second pass or \term{reducer} traverses the subject tree
top-down. The reducer accepts a tree node's state label and a
\term{goal} non-terminal --- initially the root's state label and the
start symbol --- which combine to determine the rule to be applied at
that node. By construction, the rule has the given goal non-terminal
as its left-hand side. The rule's pattern identifies the subject
subtrees and goal non-terminals for all recursive visits. Here, a
``subtree'' is not necessarily an immediate child of the current node.
Patterns with interior operators cause the reducer to skip the
corresponding subject nodes, so the reducer may proceed directly to
grandchildren, great-grandchildren, and so on. On the other hand,
chain rules cause the reducer to revisit the current subject node, with
a new goal
non-terminal, so \term{x} is also regarded as a subtree of \term{x}.
As the reducer visits (and possibly revisits) each node, user-supplied
code implements semantic action side effects and controls the order in
which subtrees are visited. The labeller is self-contained, but the
reducer combines code from \PROG with code from the user, so \PARSER
does not stand alone.
The \PARSER that is generated by \PROG provides primitives for
labelling and reducing trees. These mechanisms are a compromise
between expressibility, abstraction, simplicity, flexibility and
efficiency. Clients may combine primitives into labellers and reducers
that can traverse trees in arbitrary ways, and they may call semantic
routines when and how they wish during traversal. Also, \PROG
generates a few higher level routines that implement common
combinations of primitives, and it generates mechanisms that help debug
the tree parse.
\PROG generates the labeller as a function named \var{burm\_label} with
the signature
\begin{verbatim}
extern int burm_label(NODEPTR_TYPE p);
\end{verbatim}
It labels the entire subject tree pointed to by \var{p} and returns the
root's state label. State zero labels unmatched trees. The trees may
be corrupt or merely inconsistent with the grammar.
The simpler \var{burm\_state} is \var{burm\_label} without the
code to traverse the tree and to read and write its fields. It may be
used to integrate labelling into user-supplied traversal code. A
typical signature is
\begin{verbatim}
extern int burm_state(int op, int leftstate, int rightstate);
\end{verbatim}
It accepts an external symbol number for a node and the labels for the
node's left and right children. It returns the state label to assign
to that node. For unary operators, the last argument is ignored; for
leaves, the last two arguments are ignored. In general, \PROG
generates a \var{burm\_state} that accepts the maximum number of child
states required by the input grammar. For example, if the grammar
includes no binary operators, then \var{burm\_state} will have the
signature
\begin{verbatim}
extern int burm_state(int op, int leftstate);
\end{verbatim}
This feature is included to permit future expansion to operators with
more than two children.
The user must write the reducer, but \PARSER writes code and data that
help. Primary is
\begin{verbatim}
extern int burm_rule(int state, int goalnt);
\end{verbatim}
which accepts a tree's state label and a goal non-terminal and returns the
external rule number of a rule. The rule will have matched the tree
and have the goal non-terminal on the left-hand side; \var{burm\_rule}
returns zero when the tree labelled with the given state did not match
the goal non-terminal. For the initial, root-level call, \var{goalnt}
must be one, and \PARSER exports an array that identifies the values
for nested calls:
\begin{verbatim}
extern short *burm_nts[] = { ... };
\end{verbatim}
is an array indexed by external rule numbers. Each element points to a
zero-terminated vector of short integers, which encode the goal
non-terminals for that rule's pattern, left-to-right. The user needs
only these two externals to write a complete reducer, but a third
external simplifies some applications:
\begin{verbatim}
extern NODEPTR_TYPE *burm_kids(NODEPTR_TYPE p, int eruleno, NODEPTR_TYPE kids[]);
\end{verbatim}
accepts the address of a tree \var{p}, an external rule number, and an
empty vector of pointers to trees. The procedure assumes that \var{p}
matched the given rule, and it fills in the vector with the subtrees (in
the sense described above) of \var{p} that must be reduced recursively.
\var{kids} is returned. It is not zero-terminated.
The simple user code below labels and then fully reduces a subject tree;
the reducer prints the tree cover. \var{burm\_string} is defined below.
\begin{verbatim}
parse(NODEPTR_TYPE p) {
burm_label(p); /* label the tree */
reduce(p, 1, 0); /* and reduce it */
}
reduce(NODEPTR_TYPE p, int goalnt, int indent) {
int eruleno = burm_rule(STATE_LABEL(p), goalnt); /* matching rule number */
short *nts = burm_nts[eruleno]; /* subtree goal non-terminals */
NODEPTR_TYPE kids[10]; /* subtree pointers */
int i;
for (i = 0; i < indent; i++)
printf("."); /* print indented ... */
printf("%s\n", burm_string[eruleno]); /* ... text of rule */
burm_kids(p, eruleno, kids); /* initialize subtree pointers */
for (i = 0; nts[i]; i++) /* traverse subtrees left-to-right */
reduce(kids[i], nts[i], indent+1); /* and print them recursively */
}
\end{verbatim}
The reducer may recursively traverse subtrees in any order, and it may
interleave arbitrary semantic actions with recursive traversals.
Multiple reducers may be written, to implement multi-pass algorithms
or independent single-pass algorithms.
For each non-terminal $x$, \PROG emits a preprocessor directive to
equate \var{burm\_}$x$\var{\_NT} with $x$'s integral encoding. It also
defines a macro \var{burm\_}$x$\var{\_rule(a)} that is equivalent to
\var{burm\_rule(a,}$x$\var{)}. For the grammar in
\figref{fig-tree-grammar}, \PROG emits
\begin{verbatim}
#define burm_reg_NT 1
#define burm_con_NT 2
#define burm_addr_NT 3
#define burm_reg_rule(a) ...
#define burm_con_rule(a) ...
#define burm_addr_rule(a) ...
\end{verbatim}
Such symbols are visible only to the code after the second
``\var{\%\%}''. If the symbols \var{burm\_}$x$\var{\_NT} are needed
elsewhere, extract them from the \PARSER source.
The \option{I} option directs \PROG to emit an encoding of the input
that may help the user produce diagnostics. The vectors
\begin{verbatim}
extern char *burm_opname[];
extern char burm_arity[];
\end{verbatim}
hold the name and number of children, respectively, for each terminal.
They are indexed by the terminal's external symbol number. The vectors
\begin{verbatim}
extern char *burm_string[];
extern short burm_cost[][4];
\end{verbatim}
hold the text and cost vector for each rule. They are indexed by the
external rule number. The zero-terminated vector
\begin{verbatim}
extern char *burm_ntname[];
\end{verbatim}
is indexed by \var{burm\_}$x$\var{\_NT} and holds the name of
non-terminal $x$. Finally, the procedures
\begin{verbatim}
extern int burm_op_label(NODEPTR_TYPE p);
extern int burm_state_label(NODEPTR_TYPE p);
extern NODEPTR_TYPE burm_child(NODEPTR_TYPE p, int index);
\end{verbatim}
are callable versions of the configuration macros.
\var{burm\_child(p,0)} implements \var{LEFT\_CHILD(p)}, and
\var{burm\_child(p,1)} implements \var{RIGHT\_CHILD(p)}. A sample use
is the grammar-independent expression
\var{burm\_opname[burm\_op\_label(p)]}, which yields the textual name
for the operator in the tree node pointed to by \var{p}.
A complete tree parser can be assembled from just \var{burm\_state},
\var{burm\_rule}, and \var{burm\_nts}, which use none of the
configuration section except \var{PANIC}. The generated routines that
use the rest of the configuration section are compiled only if the
configuration section defines \var{STATE\_LABEL}, so they can be
omitted if the user prefers to hide the tree structure from \PARSER.
This course may be wise if, say, the tree structure is defined in a
large header file with symbols that might collide with \PARSER's.
\PARSER selects an optimal parse without dynamic programming at compile
time~\cite{aho-johnson-dp-classic}. Instead, \PROG does the dynamic
programming at compile-compile time, as it builds \PARSER.
Consequently, \PARSER parses quickly. Similar labellers have taken as
few as 15 instructions per node, and reducers as few as 35 per node
visited~\cite{fraser-henry-spe-91}.
\section{Debugging}
\PARSER invokes \var{PANIC} when an error prevents it from proceeding.
\var{PANIC} has the same signature as \var{printf}. It should pass its
arguments to \var{printf} if diagnostics are desired and then either
abort (say via \var{exit}) or recover (say via \var{longjmp}). If it
returns, \PARSER aborts. Some errors are not caught.
\PROG assumes a robust preprocessor, so it omits full consistency
checking and error recovery. \PROG constructs a set of states using a
closure algorithm like that used in LR table construction. \PROG
considers all possible trees generated by the tree grammar and
summarizes infinite sets of trees with finite sets. The summary
records the cost of those trees but actually manipulates the
differences in costs between viable alternatives using a dynamic
programming algorithm. Reference~\cite{henry-budp} elaborates.
Some grammars derive trees whose optimal parses depend on arbitrarily
distant data. When this happens, \PROG and the tree grammar
\term{cost diverge}, and \PROG attempts to build an infinite
set of states; it first thrashes and ultimately exhausts
memory and exits. For example, the tree grammar in
\figref{fig-diverge-grammar}
\begin{figure}
\begin{verbatim}
%term Const=17 RedFetch=20 GreenFetch=21 Plus=22
%%
reg: GreenFetch(green_reg) = 10 (0);
reg: RedFetch(red_reg) = 11 (0);
green_reg: Const = 20 (0);
green_reg: Plus(green_reg,green_reg) = 21 (1);
red_reg: Const = 30 (0);
red_reg: Plus(red_reg,red_reg) = 31 (2);
\end{verbatim}
\caption{A Diverging Tree Grammar\label{fig-diverge-grammar}}
\end{figure}
diverges, since non-terminals \var{green\_reg} and \var{red\_reg}
derive identical infinite trees with different costs. If the cost of
rule 31 is changed to 1, then the grammar does not diverge.
Practical tree grammars describing instruction selection do not
cost-diverge because infinite trees are derived from non-terminals
that model temporary registers. Machines can move data between
different types of registers for a small bounded cost, and the rules
for these instructions prevent divergence. For example, if
\figref{fig-diverge-grammar} included rules to move data between red
and green registers, the grammar would not diverge. If a bonafide
machine grammar appears to make \PROG loop, try a host with more
memory. To apply \PROG to problems other than instruction selection,
be prepared to consult the literature on
cost-divergence~\cite{pelegri-phd}.
\section{Running \PROG\ }\label{sec-man-page}
\PROG reads a tree grammar and writes a \PARSER in C. \PARSER can be
compiled by itself or included in another file. When suitably named
with the \option{p} option, disjoint instances of \PARSER should link
together without name conflicts. The command:
\begin{flushleft}
\var{burg} [ {\it arguments} ] [ {\it file} ]
\end{flushleft}
invokes \PROG. If a {\it file} is named, \PROG expects its grammar
there; otherwise it reads the standard input. The options include:
\def\Empty{}
%
\newcommand\odescr[2]{% #1=option character, #2=optional argument
\gdef\Arg2{#2}%
\item[\option{#1}\ifx\Arg2\Empty\else{{\it #2}}\fi]
}
\begin{description}
%
\odescr{c}{} $N$
Abort if any relative cost exceeds $N$, which keeps \PROG from looping on
diverging grammars. Several
references~\cite{pelegri-popl,henry-budp,balachandran-complang,proebsting-91}
explain relative costs.
%
\odescr{d}{}
Report a few statistics and flag unused rules and terminals.
%
\odescr{o}{} {\it file}
Write parser into {\it file}. Otherwise it writes to the standard output.
%
\odescr{p}{} {\it prefix}
Start exported names with {\it prefix}. The default is \var{burm}.
%
\odescr{t}{}
Generates smaller tables faster, but all goal non-terminals passed to
\var{burm\_rule} must come from an appropriate \var{burm\_nts}. Using
\var{burm\_}$x$\var{\_NT} instead may give unpredictable results.
%
\odescr{I}{}
Emit code for \var{burm\_arity}, \var{burm\_child}, \var{burm\_cost},
\var{burm\_ntname}, \var{burm\_op\_label}, \var{burm\_opname},
\var{burm\_state\_label}, and \var{burm\_string}.
%
\odescr{O}{} $N$
Change the principal cost to $N$. Elements of each cost vector are
numbered from zero.
%
\odescr{=}{}
Compare costs lexicographically, using all costs in the given order.
This option slows \PROG and may produce a larger parser. Increases
range from small to astronomical.
\end{description}
\section{Acknowledgements}
The first \PROG was adapted by the second author from his \CODEGEN
package, which was developed at the University of Washington with
partial support from NSF Grant CCR-88-01806. It was unbundled from
\CODEGEN with the support of Tera Computer. The current \PROG was
written by the third author with the support of NSF grant
CCR-8908355. The interface, documentation, and testing involved
all three authors.
Comments from a large group at the 1991 Dagstuhl Seminar on Code
Generation improved \PROG's interface. Robert Giegerich and Susan
Graham organized the workshop, and the International Conference and
Research Center for Computer Science, Schloss Dagstuhl, provided an
ideal environment for such collaboration. Beta-testers included Helmut
Emmelmann, Dave Hanson, John Hauser, Hugh Redelmeier, and Bill Waite.
\begin{thebibliography}{BMW87}
\bibitem[AGT89]{aho-twig-toplas}
Alfred~V. Aho, Mahadevan Ganapathi, and Steven W.~K. Tjiang.
\newblock Code generation using tree matching and dynamic programming.
\newblock {\em ACM Transactions on Programming Languages and Systems},
11(4):491--516, October 1989.
\bibitem[AJ76]{aho-johnson-dp-classic}
Alfred~V. Aho and Steven~C. Johnson.
\newblock Optimal code generation for expression trees.
\newblock {\em Journal of the ACM}, 23(3):458--501, July 1976.
\bibitem[App87]{appel-87}
Andrew~W. Appel.
\newblock Concise specification of locally optimal code generators.
\newblock Technical report CS-TR-080-87, Princeton University, 1987.
\bibitem[BDB90]{balachandran-complang}
A.~Balachandran, D.~M. Dhamdhere, and S.~Biswas.
\newblock Efficient retargetable code generation using bottom-up tree pattern
matching.
\newblock {\em Computer Languages}, 15(3):127--140, 1990.
\bibitem[BMW87]{wilhelm-tr}
J\"{u}rgen B\"{o}rstler, Ulrich M\"{o}nche, and Reinhard Wilhelm.
\newblock Table compression for tree automata.
\newblock Technical Report Aachener Informatik-Berichte No. 87-12, RWTH Aachen,
Fachgruppe Informatik, Aachen, Fed. Rep. of Germany, 1987.
\bibitem[Cha87]{chase-popl}
David~R. Chase.
\newblock An improvement to bottom up tree pattern matching.
\newblock {\em Fourteenth Annual ACM Symposium on Principles of Programming
Languages}, pages 168--177, January 1987.
\bibitem[FH91]{fraser-henry-spe-91}
Christopher~W. Fraser and Robert~R. Henry.
\newblock Hard-coding bottom-up code generation tables to save time and space.
\newblock {\em Software---Practice\&Experience}, 21(1):1--12, January 1991.
\bibitem[HC86]{hatcher-popl}
Philip~J. Hatcher and Thomas~W. Christopher.
\newblock High-quality code generation via bottom-up tree pattern matching.
\newblock {\em Thirteenth Annual ACM Symposium on Principles of Programming
Languages}, pages 119--130, January 1986.
\bibitem[Hen89]{henry-budp}
Robert~R. Henry.
\newblock Encoding optimal pattern selection in a table-driven bottom-up
tree-pattern matcher.
\newblock Technical Report 89-02-04, University of Washington Computer Science
Department, Seattle, WA, February 1989.
\bibitem[HO82]{hoffmann-jacm}
Christoph Hoffmann and Michael~J. O'Donnell.
\newblock Pattern matching in trees.
\newblock {\em Journal of the ACM}, 29(1):68--95, January 1982.
\bibitem[Kro75]{kron-phd}
H.~H. Kron.
\newblock {\em Tree Templates and Subtree Transformational Grammars}.
\newblock PhD thesis, UC Santa Cruz, December 1975.
\bibitem[PL87]{pelegri-phd}
Eduardo Pelegri-Llopart.
\newblock {\em Tree Transformations in Compiler Systems}.
\newblock PhD thesis, UC Berkeley, December 1987.
\bibitem[PLG88]{pelegri-popl}
Eduardo Pelegri-Llopart and Susan~L. Graham.
\newblock Optimal code generation for expression trees: An application of
{BURS} theory.
\newblock {\em Fifteenth Annual ACM Symposium on Principles of Programming
Languages}, pages 294--308, January 1988.
\bibitem[Pro91]{proebsting-91}
Todd~A. Proebsting.
\newblock Simple and efficient {BURS} table generation.
\newblock Technical report, Department of Computer Sciences, University of
Wisconsin, 1991.
\end{thebibliography}
\end{document}

View File

@ -1,19 +0,0 @@
Burg
------------------------------------------------------------------------------
Burg is licensed under the LLVM license. It has the following additional
copyrights and restrictions:
Copyright (C) 1991 Todd A. Proebsting
All Rights Reserved.
If you distribute a modified version of Burg, please document the changes you
make in addition to redistributing our list of changes to the original Burg.
See llvm/utils/Burg/LOG_CHANGES for a list of changes we have made to Burg.
Burg is also located in llvm/test/Programs/MultiSource/Applications/Burg. The
only modifications made to it are to allow it to compile.
We originally downloaded Burg from the following URL:
ftp://ftp.cs.arizona.edu/people/todd/burg.shar.Z

View File

@ -1,10 +0,0 @@
8/20/02 -- Vikram Adve
be.c: Replaced "char*" with "const char*" to avoid compiler warnings.
9/9/03 -- John Criswell
b.h be.c fe.h gram.y lex.c main.c map.c nontermainl.c plan.c zalloc.c:
A cursory look through our logs and comments indicates that these are
the only modified files. No feature enhancements have been made;
rather, all changes either fix minor programming errors, get rid of
warnings, ANSI-ify the code, or integrate Burg into our build system.

View File

@ -1,41 +0,0 @@
##===- utils/Burg/Makefile ---------------------------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
# This file was developed by the LLVM research group and is distributed under
# the University of Illinois Open Source License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
LEVEL = ../..
TOOLNAME = burg
BUILT_SOURCES = gram.tab.c gram.tab.h
EXTRA_DIST = gram.yc gram.tab.c gram.tab.h sample.gr burg.shar.gz COPYRIGHT Doc
include $(LEVEL)/Makefile.common
gram.tab.c gram.tab.h: gram.yc
$(Verb) $(BISON) -o gram.tab.c -d $<
$(ObjDir)/lex.o : gram.tab.h
clean::
$(Verb) $(RM) -rf gram.tab.h gram.tab.c core* *.aux *.log *.dvi sample sample.c tmp
doc.dvi: doc.tex
$(Verb) latex doc; latex doc
check:: $(ToolBuildPath) $(BUILD_SRC_DIR)/sample.gr
$(ToolBuildPath) -I <$(BUILD_SRC_DIR)/sample.gr >sample.c \
&& $(CC) $(CFLAGS) -o sample sample.c && ./sample
$(ToolBuildPath) -I $(BUILD_SRC_DIR)/sample.gr >tmp \
&& cmp tmp sample.c
$(ToolBuildPath) -I <$(BUILD_SRC_DIR)/sample.gr -o tmp \
&& cmp tmp sample.c
$(ToolBuildPath) -I $(BUILD_SRC_DIR)/sample.gr -o tmp \
&& cmp tmp sample.c
$(ToolBuildPath) -I -O0 <$(BUILD_SRC_DIR)/sample.gr >tmp \
&& cmp tmp sample.c
$(ToolBuildPath) -I -= <$(BUILD_SRC_DIR)/sample.gr >tmp \
&& cmp tmp sample.c
$(RM) -f tmp sample.c

View File

@ -1,14 +0,0 @@
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.

View File

@ -1,311 +0,0 @@
/* $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((const char *, int));
extern void yyerror ARGS((const char *));
extern void yyerror1 ARGS((const char *));

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

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

View File

@ -1,95 +0,0 @@
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 = 0;
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;
}
}
}
}
}

View File

@ -1,143 +0,0 @@
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);
}
}

View File

@ -1,403 +0,0 @@
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);
}
}

View File

@ -1,132 +0,0 @@
/* $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 void doGrammarNts ARGS((void));
void makeRuleDescArray ARGS((void));
void makeDeltaCostArray ARGS((void));
void makeStateStringArray ARGS((void));
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 const char *prefix;
extern int trimflag;
extern int speedflag;
extern int grammarflag;

View File

@ -1,91 +0,0 @@
%{
char rcsid_gram[] = "$Id$";
#include <stdio.h>
#include "b.h"
#include "fe.h"
void doGram(List);
%}
%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); }
;

View File

@ -1,133 +0,0 @@
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);
}

View File

@ -1,259 +0,0 @@
char rcsid_lex[] = "$Id$";
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include "b.h"
#include "fe.h"
#include "gram.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(const char *str)
{
fprintf(stderr, "line %d: %s", yyline, str);
}
void
yyerror(const char *str)
{
yyerror1(str);
fprintf(stderr, "\n");
exit(1);
}

View File

@ -1,75 +0,0 @@
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;
}

View File

@ -1,182 +0,0 @@
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 int main ARGS((int argc, char **argv));
int
main(argc, argv) int argc; char **argv;
{
int i;
extern int atoi ARGS((const 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 = (char**)&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);
}

View File

@ -1,135 +0,0 @@
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 ^= ((long)p[nt].rule) + (PRINCIPLECOST(p[nt].delta)<<4);
}
v >>= 4;
v &= (mod-1);
return v;
}
Item_Set
encode(m, ts, new) Mapping m; Item_Set ts; int *new;
{
int h;
List l;
assert(m);
assert(ts);
assert(m->count <= m->max_size);
if (grammarNts && errorState && m == globalMap) {
List l;
int found;
found = 0;
for (l = grammarNts; l; l = l->next) {
Symbol s;
s = (Symbol) l->x;
if (ts->virgin[s->u.nt->num].rule) {
found = 1;
break;
}
}
if (!found) {
*new = 0;
return errorState;
}
}
*new = 0;
h = hash(ts, m->hash_size);
for (l = m->hash[h]; l; l = l->next) {
Item_Set s = (Item_Set) l->x;
if (ts->op == s->op && equivSet(ts, s)) {
ts->num = s->num;
return s;
}
}
if (m->count >= m->max_size) {
growMapping(m);
}
assert(m->count < m->max_size);
m->set[m->count] = ts;
ts->num = m->count++;
*new = 1;
m->hash[h] = newList(ts, m->hash[h]);
return ts;
}
Item_Set
decode(m, t) Mapping m; ItemSetNum t;
{
assert(m);
assert(t);
assert(m->count < m->max_size);
assert(t < m->count);
return m->set[t];
}
void
dumpMapping(m) Mapping m;
{
int i;
printf("BEGIN Mapping: Size=%d\n", m->count);
for (i = 0; i < m->count; i++) {
dumpItem_Set(m->set[i]);
}
printf("END Mapping\n");
}

View File

@ -1,49 +0,0 @@
char rcsid_nonterminal[] = "$Id$";
#include "b.h"
#include <stdio.h>
#include <string.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;
for (l = nonterminals; l; l = l->next) {
NonTerminal nt = (NonTerminal) l->x;
if (nt->num == i) {
strcpy(buf, nt->name);
return 1;
}
}
strcpy(buf, "(Unknown NonTerminal)");
return 0;
}
void
dumpNonTerminal(n) NonTerminal n;
{
printf("%s(%d)", n->name, n->num);
}

View File

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

View File

@ -1,38 +0,0 @@
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);
}
}

View File

@ -1,921 +0,0 @@
char rcsid_plank[] = "$Id$";
#include <stdio.h>
#include <string.h>
#include <stdlib.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, const char *, const char *, const char *, int, const 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), (int(*)(const void *, const void *))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), (int(*)(const void *, const void *))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; const char *sw; const char *pre; const char *post; int offset; const char *def;
{
if (es) {
fprintf(outfile, "\t\tswitch (%s) {\n", sw);
for (; es; es = es->next) {
Exception e = (Exception) es->x;
fprintf(outfile, "\t\tcase %d: %s %d; %s\n", e->index, pre, e->value+offset, post);
}
if (def) {
fprintf(outfile, "\t\tdefault: %s;\n", def);
}
fprintf(outfile, "\t\t}\n");
} else {
if (def) {
fprintf(outfile, "\t\t%s;\n", def);
}
}
}
static void
doPlankLabel(op) Operator op;
{
PlankMap im0;
PlankMap im1;
char buf[100];
fprintf(outfile, "\tcase %d:\n", op->num);
switch (op->arity) {
case 0:
fprintf(outfile, "\t\treturn %d;\n", op->table->transition[0]->newNum);
break;
case 1:
im0 = op->table->dimen[0]->pmap;
if (im0) {
exceptionSwitch(im0->exceptions, "l", "return ", "", im0->offset, 0);
fprintf(outfile, "\t\treturn %s[l].%s + %d;\n",
im0->values->plank->name, im0->values->fieldname, im0->offset);
} else {
Item_Set *ts = transLval(op->table, 1, 0);
if (*ts) {
fprintf(outfile, "\t\treturn %d;\n", (*ts)->newNum);
} else {
fprintf(outfile, "\t\treturn %d;\n", ERROR_VAL);
}
}
break;
case 2:
im0 = op->table->dimen[0]->pmap;
im1 = op->table->dimen[1]->pmap;
if (!im0 && !im1) {
Item_Set *ts = transLval(op->table, 1, 1);
if (*ts) {
fprintf(outfile, "\t\treturn %d;\n", (*ts)->newNum);
} else {
fprintf(outfile, "\t\treturn %d;\n", ERROR_VAL);
}
} else if (!im0) {
exceptionSwitch(im1->exceptions, "r", "return ", "", im1->offset, 0);
fprintf(outfile, "\t\treturn %s[r].%s + %d;\n",
im1->values->plank->name, im1->values->fieldname, im1->offset);
} else if (!im1) {
exceptionSwitch(im0->exceptions, "l", "return ", "", im0->offset, 0);
fprintf(outfile, "\t\treturn %s[l].%s + %d;\n",
im0->values->plank->name, im0->values->fieldname, im0->offset);
} else {
assert(im0->offset == 0);
assert(im1->offset == 0);
sprintf(buf, "l = %s[l].%s",
im0->values->plank->name, im0->values->fieldname);
exceptionSwitch(im0->exceptions, "l", "l =", "break;", 0, buf);
sprintf(buf, "r = %s[r].%s",
im1->values->plank->name, im1->values->fieldname);
exceptionSwitch(im1->exceptions, "r", "r =", "break;", 0, buf);
fprintf(outfile, "\t\treturn %s_%s_transition[l][r] + %d;\n",
prefix,
op->name,
op->baseNum);
}
break;
default:
assert(0);
}
}
static void
doPlankLabelMacrosSafely(op) Operator op;
{
PlankMap im0;
PlankMap im1;
switch (op->arity) {
case -1:
fprintf(outfile, "#define %s_%s_state\t0\n", prefix, op->name);
break;
case 0:
fprintf(outfile, "#define %s_%s_state", prefix, op->name);
fprintf(outfile, "\t%d\n", op->table->transition[0]->newNum+1);
break;
case 1:
fprintf(outfile, "#define %s_%s_state(l)", prefix, op->name);
im0 = op->table->dimen[0]->pmap;
if (im0) {
if (im0->exceptions) {
List es = im0->exceptions;
assert(0);
fprintf(outfile, "\t\tswitch (l) {\n");
for (; es; es = es->next) {
Exception e = (Exception) es->x;
fprintf(outfile, "\t\tcase %d: return %d;\n", e->index, e->value ? e->value+im0->offset : 0);
}
fprintf(outfile, "\t\t}\n");
}
if (speedflag) {
fprintf(outfile, "\t( %s[l].%s + %d )\n",
im0->values->plank->name, im0->values->fieldname,
im0->offset);
} else {
fprintf(outfile, "\t( (%s_TEMP = %s[l].%s) ? %s_TEMP + %d : 0 )\n",
prefix,
im0->values->plank->name, im0->values->fieldname,
prefix,
im0->offset);
}
} else {
Item_Set *ts = transLval(op->table, 1, 0);
if (*ts) {
fprintf(outfile, "\t%d\n", (*ts)->newNum+1);
} else {
fprintf(outfile, "\t%d\n", 0);
}
}
break;
case 2:
fprintf(outfile, "#define %s_%s_state(l,r)", prefix, op->name);
im0 = op->table->dimen[0]->pmap;
im1 = op->table->dimen[1]->pmap;
if (!im0 && !im1) {
Item_Set *ts = transLval(op->table, 1, 1);
assert(0);
if (*ts) {
fprintf(outfile, "\t\treturn %d;\n", (*ts)->newNum+1);
} else {
fprintf(outfile, "\t\treturn %d;\n", 0);
}
} else if (!im0) {
assert(0);
if (im1->exceptions) {
List es = im1->exceptions;
fprintf(outfile, "\t\tswitch (r) {\n");
for (; es; es = es->next) {
Exception e = (Exception) es->x;
fprintf(outfile, "\t\tcase %d: return %d;\n", e->index, e->value ? e->value+im1->offset : 0);
}
fprintf(outfile, "\t\t}\n");
}
fprintf(outfile, "\t\tstate = %s[r].%s; offset = %d;\n",
im1->values->plank->name, im1->values->fieldname, im1->offset);
fprintf(outfile, "\t\tbreak;\n");
} else if (!im1) {
assert(0);
if (im0->exceptions) {
List es = im0->exceptions;
fprintf(outfile, "\t\tswitch (l) {\n");
for (; es; es = es->next) {
Exception e = (Exception) es->x;
fprintf(outfile, "\t\tcase %d: return %d;\n", e->index, e->value ? e->value+im0->offset : 0);
}
fprintf(outfile, "\t\t}\n");
}
fprintf(outfile, "\t\tstate = %s[l].%s; offset = %d;\n",
im0->values->plank->name, im0->values->fieldname, im0->offset);
fprintf(outfile, "\t\tbreak;\n");
} else {
assert(im0->offset == 0);
assert(im1->offset == 0);
/*
sprintf(buf, "l = %s[l].%s",
im0->values->plank->name, im0->values->fieldname);
exceptionSwitch(im0->exceptions, "l", "l =", "break;", 0, buf);
sprintf(buf, "r = %s[r].%s",
im1->values->plank->name, im1->values->fieldname);
exceptionSwitch(im1->exceptions, "r", "r =", "break;", 0, buf);
fprintf(outfile, "\t\tstate = %s_%s_transition[l][r]; offset = %d;\n",
prefix,
op->name,
op->baseNum);
fprintf(outfile, "\t\tbreak;\n");
*/
if (speedflag) {
fprintf(outfile, "\t( %s_%s_transition[%s[l].%s][%s[r].%s] + %d)\n",
prefix,
op->name,
im0->values->plank->name, im0->values->fieldname,
im1->values->plank->name, im1->values->fieldname,
op->baseNum);
} else {
fprintf(outfile, "\t( (%s_TEMP = %s_%s_transition[%s[l].%s][%s[r].%s]) ? ",
prefix,
prefix,
op->name,
im0->values->plank->name, im0->values->fieldname,
im1->values->plank->name, im1->values->fieldname);
fprintf(outfile, "%s_TEMP + %d : 0 )\n",
prefix,
op->baseNum);
}
}
break;
default:
assert(0);
}
}
static void
doPlankLabelSafely(op) Operator op;
{
fprintf(outfile, "\tcase %d:\n", op->num);
switch (op->arity) {
case -1:
fprintf(outfile, "\t\treturn 0;\n");
break;
case 0:
fprintf(outfile, "\t\treturn %s_%s_state;\n", prefix, op->name);
break;
case 1:
fprintf(outfile, "\t\treturn %s_%s_state(l);\n", prefix, op->name);
break;
case 2:
fprintf(outfile, "\t\treturn %s_%s_state(l,r);\n", prefix, op->name);
break;
default:
assert(0);
}
}
static void
makePlankState()
{
fprintf(outfile, "\n");
fprintf(outfile, "int %s_TEMP;\n", prefix);
foreachList((ListFn) doPlankLabelMacrosSafely, operators);
fprintf(outfile, "\n");
fprintf(outfile, "#ifdef __STDC__\n");
switch (max_arity) {
case -1:
fprintf(stderr, "ERROR: no terminals in grammar.\n");
exit(1);
case 0:
fprintf(outfile, "int %s_state(int op) {\n", prefix);
fprintf(outfile, "#else\n");
fprintf(outfile, "int %s_state(op) int op; {\n", prefix);
break;
case 1:
fprintf(outfile, "int %s_state(int op, int l) {\n", prefix);
fprintf(outfile, "#else\n");
fprintf(outfile, "int %s_state(op, l) int op; int l; {\n", prefix);
break;
case 2:
fprintf(outfile, "int %s_state(int op, int l, int r) {\n", prefix);
fprintf(outfile, "#else\n");
fprintf(outfile, "int %s_state(op, l, r) int op; int l; int r; {\n", prefix);
break;
default:
assert(0);
}
fprintf(outfile, "#endif\n");
fprintf(outfile, "\tregister int %s_TEMP;\n", prefix);
fprintf(outfile, "#ifndef NDEBUG\n");
fprintf(outfile, "\tswitch (op) {\n");
opsOfArity(2);
if (max_arity >= 2) {
fprintf(outfile,
"\t\t%s_assert(r >= 0 && r < %d, %s_PANIC(\"Bad state %%d passed to %s_state\\n\", r));\n",
prefix, globalMap->count, prefix, prefix);
fprintf(outfile, "\t\t/*FALLTHROUGH*/\n");
}
opsOfArity(1);
if (max_arity > 1) {
fprintf(outfile,
"\t\t%s_assert(l >= 0 && l < %d, %s_PANIC(\"Bad state %%d passed to %s_state\\n\", l));\n",
prefix, globalMap->count, prefix, prefix);
fprintf(outfile, "\t\t/*FALLTHROUGH*/\n");
}
opsOfArity(0);
fprintf(outfile, "\t\tbreak;\n");
fprintf(outfile, "\t}\n");
fprintf(outfile, "#endif\n");
fprintf(outfile, "\tswitch (op) {\n");
fprintf(outfile,"\tdefault: %s_PANIC(\"Unknown op %%d in %s_state\\n\", op); abort(); return 0;\n",
prefix, prefix);
foreachList((ListFn) doPlankLabelSafely, operators);
fprintf(outfile, "\t}\n");
fprintf(outfile, "}\n");
}
void
makePlanks()
{
List planks;
renumber();
makePmaps();
planks = assemblePlanks();
purgePlanks(planks);
inToEx();
makePlankRule();
makePlankState();
}

View File

@ -1,64 +0,0 @@
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");
}

View File

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

View File

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

View File

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

View File

@ -1,38 +0,0 @@
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;
}

View File

@ -1,552 +0,0 @@
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);
}
}

View File

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

View File

@ -1,32 +0,0 @@
char rcsid_zalloc[] = "$Id$";
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "b.h"
int
fatal(const 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);
}

View File

@ -8,7 +8,7 @@
##===----------------------------------------------------------------------===##
LEVEL = ..
DIRS = Burg TableGen fpcmp PerfectShuffle
DIRS = TableGen fpcmp PerfectShuffle
EXTRA_DIST := cgiplotNLT.pl check-each-file codegen-diff countloc.sh cvsupdate \
DSAclean.py DSAextract.py emacs findsym.pl GenLibDeps.pl \