[comp.sources.misc] v19i089: wacco - A C++ LL parser generator, Part02/06

parag@hpsdeb.sde.hp.com (Parag Patel) (05/19/91)

Submitted-by: Parag Patel <parag@hpsdeb.sde.hp.com>
Posting-number: Volume 19, Issue 89
Archive-name: wacco/part02

---- Cut Here and feed the following to sh ----
#!/bin/sh
# This is part 02 of wacco
# ============= wacco.doc.iw ==============
if test -f 'wacco.doc.iw' -a X"$1" != X"-c"; then
	echo 'x - skipping wacco.doc.iw (File already exists)'
else
echo 'x - extracting wacco.doc.iw (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'wacco.doc.iw' &&
104 pgscriptver 
X
100 DefSpaceEx 100 DefCharEx 1 DefNormalHyphenationOn 100 
DefTypeColor (Times-Roman) DefTypeFace ENGLISH DefLanguage 12 DefPointSize 
USE_POINTSIZE DefSetSize (@default) DefTypeResource 
X
JUSTIFYLEFT DefJustifyFlags 2 DefBeginParaLeadValue ABSOLUTE 
DefBeginParaLeadMode 2 DefEndParaLeadValue ABSOLUTE DefEndParaLeadMode 120 
DefLeadValue PROPORTIONAL DefLeadMode 1 46 0 TAB_LEFT  720 DefTab 1 46 0 
TAB_LEFT  2160 DefTab 1 46 0 TAB_LEFT  3600 DefTab 1 46 0 
TAB_LEFT  5040 DefTab 1 46 0 TAB_LEFT  6480 DefTab 1 46 0 
TAB_LEFT  7920 DefTab 1 46 0 TAB_LEFT  9360 DefTab 0 46 0 
TAB_LEFT  24480 DefTab 0 46 0 TAB_LEFT  24480 DefTab 0 46 0 
TAB_LEFT  24480 DefTab 0 46 0 TAB_LEFT  24480 DefTab 0 46 0 
TAB_LEFT  24480 DefTab 0 46 0 TAB_LEFT  24480 DefTab 0 46 0 
TAB_LEFT  24480 DefTab 0 46 0 TAB_LEFT  24480 DefTab 0 46 0 
TAB_LEFT  24480 DefTab 0 46 0 TAB_LEFT  24480 DefTab 0 46 0 
TAB_LEFT  24480 DefTab 0 46 0 TAB_LEFT  24480 DefTab 0 46 0 
TAB_LEFT  24480 DefTab 0 46 0 TAB_LEFT  24480 DefTab 0 46 0 
TAB_LEFT  24480 DefTab 0 46 0 TAB_LEFT  24480 DefTab 0 46 0 
TAB_LEFT  24480 DefTab 0 46 0 TAB_LEFT  24480 DefTab 0 46 0 
TAB_LEFT  24480 DefTab 0 46 0 TAB_LEFT  24480 DefTab 0 46 0 
TAB_LEFT  24480 DefTab 0 46 0 TAB_LEFT  24480 DefTab 0 46 0 
TAB_LEFT  24480 DefTab 0 46 0 TAB_LEFT  24480 DefTab 0 46 0 
TAB_LEFT  24480 DefTab 0 46 0 TAB_LEFT  24480 DefTab 0 46 0 
TAB_LEFT  24480 DefTab 0 46 0 TAB_LEFT  24480 DefTab 0 46 0 
TAB_LEFT  24480 DefTab 0 46 0 TAB_LEFT  24480 DefTab 0 46 0 
TAB_LEFT  24480 DefTab 0 46 0 TAB_LEFT  24480 DefTab 0 46 0 
TAB_LEFT  24480 DefTab 0 46 0 TAB_LEFT  24480 DefTab 0 46 0 
TAB_LEFT  24480 DefTab 0 46 0 TAB_LEFT  24480 DefTab 0 46 0 
TAB_LEFT  24480 DefTab 0 46 0 TAB_LEFT  24480 DefTab 0 46 0 
TAB_LEFT  24480 DefTab 0 46 0 TAB_LEFT  24480 DefTab 0 46 0 
TAB_LEFT  24480 DefTab 80 DefWSMN 100 DefWSNM 150 DefWSMX 110 
DefLSMX 100 DefLeaderEx 46 DefLeaderChar 0 DefFirstIndent 0 
DefLeftIndent 0 DefRightIndent 0 DefNumberingOn 0 DefNumberingType 0 
DefNumberingRestart 1 DefNumberingLevel 0 DefNumberingStyle 0 
DefNumberingTabAfter 1 DefNumberingShowAllLevels 1 DefNumberingStart 1 
DefNumberingIncrement () DefNumberingPrefix () DefNumberingSuffix (.) 
DefNumberingSeparator (*default) DefParaResource 
X
0 DefLineWidth TRANSPARENT DefPenColor TRANSPARENT DefFillColor 1 DefIG 300 
DefResolution 100 DefYScale 100 DefXScale (=default) DefPolyResource 
X
0 DefPageDimensions 12240 DefPageWidth 15840 DefPageHeight 1440 
DefInsideMargin 1080 DefOutsideMargin 1080 DefTopMargin 1080 
DefBottomMargin 0 DefOrientation 0 DefPageStyle 1 DefColumns 360 
DefGutter (%default) DefMasterPage 
X
0 DefPageDimensions 12240 DefPageWidth 15840 DefPageHeight 1440 
DefInsideMargin 1080 DefOutsideMargin 1080 DefTopMargin 1080 
DefBottomMargin 0 DefOrientation 0 DefPageStyle 1 DefColumns 360 
DefGutter (%code) DefMasterPage ResDefEnd 
X
0 DefFirstLeft 0 DefDocSetup 1 DefNumPages 1 AutoPage 1 
DefStartPageNum () DefPageNumPrefix 1 DefGraphicLocation document 
X
0 DefAutoPage 
0 (%default) 1 DefPage 
0 DefAutoPage 
0 (%default) 2 DefPage 
0 DefAutoPage 
0 (%default) 3 DefPage 
0 DefAutoPage 
0 (%default) 4 DefPage 
0 DefAutoPage 
0 (%default) 5 DefPage 
0 DefAutoPage 
0 (%default) 6 DefPage 
0 DefAutoPage 
0 (%default) 7 DefPage 
0 DefAutoPage 
0 (%default) 8 DefPage 
0 DefAutoPage 
0 (%default) 9 DefPage 
0 DefAutoPage 
0 (%default) 10 DefPage 
0 DefAutoPage 
0 (%default) 11 DefPage 
0 DefAutoPage 
0 (%default) 12 DefPage 
0 DefAutoPage 
0 (%default) 13 DefPage 
1 DefAutoPage 
0 (%default) 14 DefPage 
X
POLY_OBJECT POLY_EMPTY |  DefPolyType 
X
0 DefLineWidth TRANSPARENT DefPenColor TRANSPARENT DefFillColor 1 DefIG 300 
DefResolution 100 DefYScale 100 DefXScale (=default) DefPolyResId 0 
DefMasterRef 
MP_CPSUCC_LINK MP_CPPRED_LINK POLY_COLUMN | |  DefSLinksFlags 0 DefStreamSucc 0 
DefStreamPred 
1440 1080 11160 1080 11160 14760 1440 14760 4 
POLY_OBJECT POLY_EMPTY |  (%default) 0 1 TextPolygon 
X
POLY_OBJECT POLY_EMPTY |  DefPolyType 
X
0 DefLineWidth TRANSPARENT DefPenColor TRANSPARENT DefFillColor 1 DefIG 300 
DefResolution 100 DefYScale 100 DefXScale (=default) DefPolyResId 0 
DefMasterRef 
MP_CPSUCC_LINK MP_CPPRED_LINK POLY_COLUMN | |  DefSLinksFlags 0 DefStreamSucc 0 
DefStreamPred 
1440 1080 11160 1080 11160 14760 1440 14760 4 
POLY_OBJECT POLY_EMPTY |  (%code) 0 2 TextPolygon 
X
POLY_OBJECT POLY_TEXT |  DefPolyType 
X
0 DefLineWidth TRANSPARENT DefPenColor TRANSPARENT DefFillColor 1 DefIG 300 
DefResolution 100 DefYScale 100 DefXScale (=default) DefPolyResId 1 
DefMasterRef 
MP_CPSUCC_LINK MP_CPPRED_LINK MPREF_VALID POLY_COLUMN | | |  DefSLinksFlags 0 
DefStreamSucc 0 DefStreamPred 4 DefTextHandle 
1440 1080 11160 1080 11160 14760 1440 14760 4 
POLY_OBJECT POLY_TEXT |  (1) 0 3 TextPolygon 
X
4 asciitextstream 
<(AvantGarde) cf ><24 cs><eop>
<eop>
<eop>
<eop>
<eop>
<eop>
<eop>
<32 cs><ON bo><CENTER align><tab>WACCO<BO type_rev><eop>
<24 cs><ON bo><eop>
<eop>
<tab>W<BO type_rev>hy <ON bo>A<BO type_rev>nother <ON bo>C<BO type_rev>ompiler 
<ON bo>Co<BO type_rev>mpiler?<eop>
<eop>
<tab>Why not!!!<eop>
<eop>
<eop>
<14 cs>by<eop>
Parag Patel
<textstream_end> 
X
POLY_OBJECT POLY_TEXT |  DefPolyType 
X
0 DefLineWidth TRANSPARENT DefPenColor TRANSPARENT DefFillColor 1 DefIG 300 
DefResolution 100 DefYScale 100 DefXScale (=default) DefPolyResId 1 
DefMasterRef 
X
MP_CPSUCC_LINK MP_CPPRED_LINK LINK_OVERFLOW MPREF_VALID POLY_COLUMN AUTO_STREAM | | | | | 
DefSLinksFlags 8 DefStreamSucc 0 DefStreamPred 6 DefTextHandle 
1440 1080 11160 1080 11160 14760 1440 14760 4 
POLY_OBJECT POLY_TEXT |  (2) 0 5 TextPolygon 
X
6 asciitextstream 
<(Palatino) cf ><eop>
<16 cs><(AvantGarde) cf ><ON bo><CENTER align>Overview<SIZE type_rev><(Palatino
) cf ><BO type_rev><eop>
<ALIGN para_rev><eop>
<eop>
<1440 FirstIndent><1440 LeftIndent><1440 RightIndent>Wacco is another compiler 
compiler. It generates a C++ recursive-descent LL(1) parser rather than a botto
m-up style LALR parser. It also directly supports lexical scanning, making it v
ery easy to describe a complete language within a single wacco source file.<eop
>
<eop>
The underlying philosophy in wacco is that the code generated should be exactly
X like that someone would generate by hand, if they were writing a recursive-des
cent compiler the hard way.<eop>
<eop>
Wacco also generates some relatively simple-minded error recovery schemes using
X FIRST and FOLLOW sets. While it leaves a lot to be desired, it's seems to be m
uch better than <ON it>yacc(1)<IT type_rev>'s!  Indeed, wacco was written to  p
rovide a platform for experimenting with various error recovery schemes, but tu
rned out to be quite useful in its own right.<eop>
<eop>
For more details about how to run wacco, please see the <ON it>wacco(1)<IT type
_rev> manual page. This document is intended to describe the wacco grammar form
at.<eop>
<eop>
<eop>
<eop>
<eop>
<eop>
<eop>
<eop>
<eop>
<eop>
<eop>
<eop>
<eop>
<eop>
<eop>
<eop>
<eop>
<eop>
<eop>
<eop>
<9 cs>Copyright ) 1991 by Parag Patel.  All Rights Reserved.<pe><FIRSTINDENT pa
ra_rev><LEFTINDENT para_rev><RIGHTINDENT para_rev><FIRSTINDENT para_rev><LEFTIN
DENT para_rev><RIGHTINDENT para_rev><FIRSTINDENT para_rev><LEFTINDENT para_rev>
<RIGHTINDENT para_rev><SIZE type_rev><eop>
<CENTER align><16 cs><(AvantGarde) cf ><ON bo>File format<SIZE type_rev><
(Palatino) cf ><BO type_rev><eop>
<ALIGN para_rev><eop>
<eop>
The basic wacco grammar file format is:<eop>
<eop>
<(Courier) cf ><tab>/* C style comments */<eop>
<tab>%opt <(Palatino) cf ><ON it>directives<IT type_rev><eop>
<tab><(Courier) cf >{ <(Palatino) cf ><ON it>header<
(Courier) cf ><IT type_rev> }<eop>
<(Palatino) cf ><tab><ON it>rules<(Courier) cf ><IT type_rev><tab>// C++ style 
comments<eop>
<tab>$$<eop>
<(Palatino) cf ><tab><ON it>scanner<IT type_rev><eop>
<eop>
Wacco directives may be placed on the optional <(Courier) cf >%opt<
(Palatino) cf > line at the top of the source grammar.  Only one such line is a
llowed in the grammar source, and it MUST be first in the source.  The directiv
es are actually the command-line options for wacco!  Options may thus be set ei
ther on the command line, or in the wacco source itself.  The entire "<(Courier
) cf >%opt<(Palatino) cf >" line is parsed as if it were the command line.  Ple
ase see the man page for descriptions of the command-line options.<eop>
<eop>
The header section (which is optional) is a set of code in curly-braces <(Couri
er) cf >{}<(Palatino) cf > that is put at the top of the output <ON it>parser.C
<IT type_rev> file.  This a the place to include files, define classes, or setu
p global variables.  Naturally, there are no curlies <
(Courier) cf >{}<(Palatino) cf > if there is no need for a header section.<eop>
X
<eop>
The scanner section (the two<(Courier) cf ><(Palatino) cf > "<(Courier) cf >$$<
X
(Palatino) cf >" and everything after) is entirely optional.  It is included in
X the grammar file to make it easy to refer to the actual values of tokens witho
ut explicitly defining those values by hand.<eop>
<eop>
Without any of the optional parts, a grammar consists only of rules.<eop>
<pe><eop>
<CENTER align><16 cs><
(AvantGarde) cf ><ON bo>Rules<SIZE type_rev><(Palatino) cf ><BO type_rev><eop>
<ALIGN para_rev><eop>
<eop>
The rules look much like those of yacc at first glance but there are some inter
esting differences.  A rule looks like:<eop>
<eop>
<(Courier) cf ><tab>id <la>TYPE<ra>  : <(Palatino) cf ><ON it>stuff<(Courier) c
f ><IT type_rev> ;<eop>
<
(Palatino) cf ><eop>
The <ON it>id <IT type_rev>on the left-hand side is a non-terminal and so  is e
ventually turned into a function.  The <ON it>TYPE <IT type_rev>is the type tha
t this function will accept in and return as a reference argument.  It is optio
nal and must be in angle-brackets  if present . The default <ON it>TYPE<IT type
_rev> is  "<(Courier) cf >int<(Palatino) cf >". This <ON it>TYPE<IT type_rev> i
s used to pass information into and out of the rule, as will be seen later.<eop
>
<eop>
<(Courier) cf ><tab>id : <(Palatino) cf ><ON it>stuff<
(Courier) cf ><IT type_rev> ;<eop>
<tab>id <la>TYPE<ra> : <(Palatino) cf ><ON it>stuff<(Courier) cf ><IT type_rev>
X ;<eop>
<(Palatino) cf ><eop>
A vertical-bar "<(Courier) cf >|<
(Palatino) cf >" may be used to avoid duplicating the left-hand side:<eop>
<eop>
<(Courier) cf ><tab>id : <(Palatino) cf ><ON it>stuff1<(Courier) cf ><IT type_r
ev> ;<eop>
<tab>id : <(Palatino) cf ><ON it>stuff2<
(Courier) cf ><IT type_rev> ;<eop>
<(Palatino) cf ><eop>
is equivalent to<eop>
<eop>
<(Courier) cf ><tab>id : <(Palatino) cf ><ON it>stuff1<(Courier) cf ><IT type_r
ev> | <
(Palatino) cf ><ON it>stuff2<(Courier) cf ><IT type_rev> ;<(Palatino) cf ><eop>
X
<eop>
The <ON it>stuff<IT type_rev> on the right-hand side can get kind of interestin
g.  Like, yacc, this is basically a list of terminals or non-terminals that are
X expected in sequence.<eop>
<eop>
<
(Courier) cf ><tab>parenexpr : LPAREN expr RPAREN ;<eop>
<(Palatino) cf ><eop>
<eop>
<(AvantGarde) cf ><ON bo><14 cs>Terminals<(Palatino) cf ><BO type_rev><SIZE typ
e_rev><eop>
<eop>
Terminals can be described in several different ways.<eop>
<eop>
Simple character tokens are straight-forward.  Their token value is always that
X of the character they represent.  The null character '\0' may not be used as a
X token - its value used for other things internally.<eop>
<eop>
<(Courier) cf ><tab>parenexpr : '(' expr ')' ;<eop>
<
(Palatino) cf ><eop>
For more complicated strings, just use the strings themselves!<eop>
<eop>
<(Courier) cf ><tab>parenexpr : "<la><la>" expr "<ra><ra>" ;<eop>
<(Palatino) cf ><eop>
The same string may be used in other rules to refer to that very same token.<eo
p>
<eop>
Also, any identifier name may be used to define a terminal.  If that id does no
t appear on the left side of a colon "<(Courier) cf >:<(Palatino) cf >", then i
t is assumed to be a terminal symbol in the grammar.<eop>
<eop>
Token codes for terminals are automatically assigned and stored in the <ON it>t
okens.h<IT type_rev> header file.  The token value of a string is pretty much i
naccessible.  A character constant will always be its own token.  Any other ter
minal name like <ON it>LPAREN<IT type_rev> above will be in the header file as 
an enum with the same name, allowing it to be used symbolically.<eop>
<eop>
<eop>
<
(AvantGarde) cf ><ON bo><14 cs>Actions<(Palatino) cf ><BO type_rev><SIZE type_r
ev><eop>
<eop>
Actions (that is, C++ code) are imbedded anywhere on the right-hand side within
X pairs of curly-braces <(Courier) cf >{}<(Palatino) cf >.<eop>
<eop>
<(Courier) cf ><tab>parenexpr: '(' expr { $$ = $expr; } ')'<eop>
<
(Palatino) cf ><eop>
This introduces some other features that wacco has which yacc doesn't. First th
ough, the value that the non-terminal returns is always "<(Courier) cf >$$<(Pal
atino) cf >".<eop>
<eop>
The values of the right-hand side are referred to directly via their symbolic n
ames.  Thus we use "<(Courier) cf >$expr<(Palatino) cf >" instead of "<
(Courier) cf >$2<(Palatino) cf >" in yacc!  Also, <ON it>expr<IT type_rev>s mus
t return <(Courier) cf >int<(Palatino) cf >s or the C++ compiler will complain!
<eop>
<eop>
Wacco generates an appropriate temporary variable if and only if it is used by 
referring to a "<(Courier) cf >$$<
(Palatino) cf >" inside some code for that rule.  Thus <ON it>parenexpr<IT type
_rev> above will have an in/out argument defined for it.  If there were no code
X in <(Courier) cf >{}<(Palatino) cf >, then <ON it>parenexpr<IT type_rev> would
n't be passed anything at all.<eop>
<eop>
<eop>
<(AvantGarde) cf ><14 cs><ON bo>Types<(Palatino) cf ><SIZE type_rev><BO type_re
v><eop>
<eop>
Actually, The <ON it>TYPE<IT type_rev> specifier of a non-terminal may actually
X be a lot more complicated than just a simple type:<eop>
<eop>
<
(Courier) cf ><tab>example <la>double d; int i, j<ra> : ... { $$.d = 0.0; $$.i 
= 34; }<eop>
<(Palatino) cf ><eop>
In this case, wacco creates a struct for this non-terminal instead of a simple 
variable.  The contents of the  <
(Courier) cf >"<la><ra><(Palatino) cf >" are put into this struct.  This allows
X passing more information in and out of a non-terminal without having to create
X a dummy <(Courier) cf >struct<(Palatino) cf > by hand.  It is also passed to t
he non-terminal function by reference rather than copying, and thus is very eff
icient.<eop>
<eop>
<(Courier) cf ><tab>expr <la>int left, right<ra> :  ...  ;<eop>
<tab>example : expr ';' { $$ = $expr.left + $expr.right } ;<eop>
<
(Palatino) cf ><eop>
Note that all exported non-terminals <ON bo>must<BO type_rev> have simple types
, to avoid bogus structure naming conventions.  If you must have a complicated 
type returned from a start-symbol, you should create a specially named <(Courie
r) cf >struct<(Palatino) cf > or <(Courier) cf >class<(Palatino) cf > and use i
t instead. (more about start symbols later)<eop>
<eop>
Also, simple types must not be named.  The following is illegal as well as redu
ndant, and kind of silly anyway:<eop>
<eop>
<
(Courier) cf ><tab>expr <la>int var<ra> : ... ;<tab>// ILLEGAL!!!<eop>
<(Palatino) cf ><eop>
<eop>
<(AvantGarde) cf ><14 cs><ON bo>Aliases<(Palatino) cf ><SIZE type_rev><BO type_
rev><eop>
<eop>
If we have 2 <ON it>expr<IT type_rev>s on the right, things get a little messie
r:<eop>
<eop>
<(Courier) cf ><tab>example: '(' expr ',' expr ')'<eop>
<tab><tab>{ $$ = $expr1 + $expr2; };<eop>
<
(Palatino) cf >or<eop>
<(Courier) cf ><tab>example: '(' expr=front ',' expr=back ')'<eop>
<tab><tab>{ $$ = $front + $back; };<eop>
<
(Palatino) cf ><eop>
The second form introduces the ability to name (alias) one of the right-hand si
de's non-terminal names!  Here we name <ON it>expr1<IT type_rev> to be called <
ON it>front<IT type_rev> and <ON it>expr2<IT type_rev> to be <ON it>back<IT typ
e_rev> for just this particular right-hand side.<eop>
<eop>
<eop>
<(AvantGarde) cf ><14 cs><ON bo>More actions<(Palatino) cf ><SIZE type_rev><BO 
type_rev><eop>
<eop>
Since wacco generates a C++ recursive-descent parser, we can do even more inter
esting things on the right.  Wacco passes the local vars to store return values
X by reference.  Thus we can pass information into a rule as well as get stuff o
ut of it.<eop>
<eop>
<(Courier) cf ><tab>example: { $expr = $$; } '(' expr ')' { $$ = $expr; };<eop>
X
<(Palatino) cf ><eop>
This initializes the temp-var used to store the return value from <ON it>expr<I
T type_rev> to whatever was passed in to <ON it>example<IT type_rev> then passe
s it to <ON it>expr.<IT type_rev>  If a non-terminal never uses "<
(Courier) cf >$$<(Palatino) cf >", then it is assumed to not return anything, a
nd no temp-var will be declared nor passed into it.<eop>
<eop>
Other things that one can do:<eop>
<eop>
<(Courier) cf ><tab>example: '(' { int v = 2; } expr ')' { v = $expr; };<(Palat
ino) cf ><eop>
<(Courier) cf ><
(Palatino) cf ><eop>
and create temp C++ vars anywhere you want.  Wacco carefully avoids putting out
X unnecessary sets of blocks in the output parser file.<eop>
<eop>
To generate incomplete blocks, and allow a wierd sort of free-form grammar, the
X <
(Courier) cf >%{%}<(Palatino) cf > format may be used wherever a {} is normally
X used. This allows creating incomplete blocks:<eop>
<eop>
<(Courier) cf ><tab>example: '(' %{ if (somevar) { %} expr ')' %{ } %} ;<eop>
<(Palatino) cf ><eop>
Curly-braces are not counted within <(Courier) cf >%{%}<
(Palatino) cf > blocks, and <(Courier) cf >%{%}<(Palatino) cf > blocks may be u
sed wherever <(Courier) cf >{}<(Palatino) cf > blocks are allowed.<eop>
<eop>
<eop>
<
(AvantGarde) cf ><14 cs><ON bo>Empty symbol<SIZE type_rev><(Palatino) cf ><BO t
ype_rev><eop>
<eop>
The empty rule may not be implicitly specified is in yacc, but must be defined 
with the special "<(Courier) cf >[]<(Palatino) cf >" symbol:<eop>
<eop>
<(Courier) cf ><tab>null: [] ;<eop>
<tab>expr: '(' expr ')' | [] ;<eop>
<
(Palatino) cf ><eop>
An empty statement is an error in wacco to help protect against typos and other
X mistakes.<eop>
<eop>
<eop>
<(AvantGarde) cf ><14 cs><ON bo>Parenthesized expressions<(Palatino) cf ><SIZE 
type_rev><BO type_rev><eop>
<eop>
Right-hand sides may have parentheses for grouping.  Basically, a function must
X be generated for every parenthesized expression to maintain the parsing semant
ics:<eop>
<eop>
<(Courier) cf ><tab>value: (ID | INT) | [];<eop>
<(Palatino) cf ><eop>
is the equivalent of:<eop>
<eop>
<
(Courier) cf ><tab>value: v1 | [];<eop>
<tab>v1: ID | INT;<eop>
<(Palatino) cf ><eop>
Just like every other non-terminal, parenthesized expressions have return value
s, types, aliases, and may be referred to in other parts of the right-hand side
.  The default type is the type of the enclosing parens or left-hand side for t
he outer-most parens:<eop>
<eop>
<
(Courier) cf ><tab>example: (<la>long<ra> ID | INT) { $$ = $_; };<eop>
<(Palatino) cf ><eop>
Multiple sets of parens on the right may be referred to as<(Courier) cf > $_1<(
Palatino) cf >,<(Courier) cf > $_2<
(Palatino) cf >, and so on.  They may be named as well:<eop>
<eop>
<(Courier) cf ><tab>example<la>float<ra>: (ID | FLOAT)=num { $$ = $num; };<eop>
X
<(Palatino) cf ><eop>
Here the parenthesized expression <ON it>num<IT type_rev> inherits the type <(C
ourier) cf >float<(Palatino) cf > from <ON it>example<IT type_rev>.<eop>
<eop>
Since the left-hand side may be used on the right for recursive functions, so m
ay parenthesized expressions.  The names just get a little strange.<eop>
<eop>
<
(Courier) cf ><tab>strange: (ID (OP # #1 #2 #3 #* | []) | []);<eop>
<(Palatino) cf ><eop>
The inner "<(Courier) cf >#<(Palatino) cf >" refers to the inner-most set of pa
rens enclosing the "<(Courier) cf >OP...<
(Palatino) cf >".  The strings "<(Courier) cf >#<(Palatino) cf >" and "<(Courie
r) cf >#1<(Palatino) cf >" are equivalent and refer to this inner most set of p
arens.  "<
(Courier) cf >#2<(Palatino) cf >" refers to the next outer parens starting the 
"<(Courier) cf >ID...<(Palatino) cf >".  "<(Courier) cf >#3<
(Palatino) cf >" and "<(Courier) cf >#*<(Palatino) cf >" refer the the name of 
the left-hand side, just for completeness.  These can be viewed as the outermos
t "parens" in the expression.  Ugly but sometimes useful.<eop>
<eop>
<eop>
<(AvantGarde) cf ><14 cs><ON bo>Special tokens<(Palatino) cf ><SIZE type_rev><B
O type_rev><eop>
<eop>
Other things defined in <ON it>tokens.h<IT type_rev> include the end-of-input t
oken <ON it>EOI<IT type_rev> which has value 0, and the constants <ON it>RETOK<
IT type_rev> and <ON it>RETERR,<IT type_rev> for appropriate return values.  Th
ese have the values of <ON it>TRUE<IT type_rev> (1) and <ON it>FALSE<IT type_re
v> (0) respectively.  These may be used in the right-hand side of rules if it i
s determined that further parsing of rules is un-necessary.<eop>
<eop>
<
(Courier) cf ><tab>parenexpr: LPAREN expr<eop>
<tab><tab>{ if ($expr == BOGUS) return RETERR; } RPAREN;<eop>
<(Palatino) cf ><eop>
The return-code from various rules is always available as the magic string "<(C
ourier) cf >$?<(Palatino) cf >" directly after that particular rule is called:<
eop>
<eop>
<(Courier) cf ><tab>parenexpr: LPAREN expr<eop>
<tab><tab>{ if ($? != RETOK) return RETERR; } RPAREN;<eop>
<
(Palatino) cf ><eop>
The return code is overwritten with each call to a non-terminal on the right-ha
nd side, so if a previous return value is needed, you must save it in some vari
able yourself. The generated parser code does not look at the actual return val
ue of non-terminals (functions), so other return values may be used if desired.
<eop>
<eop>
<(AvantGarde) cf ><14 cs><ON bo>Start symbols<(Palatino) cf ><SIZE type_rev><BO
X type_rev><eop>
<eop>
By default, the first rule in the grammar is considered to be the start symbol.
X  Instead of calling <
(Courier) cf >yyparse()<(Palatino) cf > to initiate the parse, the function to 
call is the name of the left-hand <ON it>ID<IT type_rev> in the first rule.  It
X is called with no arguments.  It returns either <ON it>RETOK<IT type_rev> or <
ON it>RETERR<IT type_rev> depending on whether the parse succeeded or not.<eop>
X
<eop>
<(Courier) cf ><tab>firstsymbol: ... ;<eop>
<tab>...<eop>
<eop>
<tab>main()<eop>
<tab>{<eop>
<tab><tab>if (firstsymbol() == RETOK)<eop>
<tab><tab><tab>return 0;<eop>
<tab><tab>return -1;<eop>
<tab>}<eop>
<(Palatino) cf ><eop>
But you don't have to have just one entry point!  Adding a "<(Courier) cf >%exp
ort<
(Palatino) cf >" modifier after a non-terminal just before the "<(Courier) cf >
:<(Palatino) cf >" causes that symbol to become callable from outside the gramm
ar:<eop>
<eop>
<(Courier) cf ><tab>thing<la>type<ra> %export :  ...  ;<eop>
<eop>
<(Palatino) cf >And in some another source file:<eop>
<
(Courier) cf ><eop>
<tab>func() { type var;  return thing(var); }<eop>
<(Palatino) cf ><eop>
The first non-terminal in the grammar is automatically exported unless <(Courie
r) cf >%export<(Palatino) cf > is used somewhere in the grammar.  Also, notice 
that if a <ON it>type<IT type_rev> is defined and used for a non-terminal, that
X <ON it>type<IT type_rev> must be passed in by reference to that function.<eop>
X
<eop>
The <(Courier) cf >%export<
(Palatino) cf > feature lets you call several non-terminals in the grammar.  Th
is can be used to export parts of a grammar, say sub-expression parsing, or let
X you put several different parsers into one grammar file.  All exported non-ter
minals are also listed as "<
(Courier) cf >extern<(Palatino) cf >"s in the <ON it>tokens.h<IT type_rev> head
er file.<eop>
<eop>
Also remember that <ON it>type<IT type_rev> must be a simple type and not a com
plex struct for a start symbol.<pe><eop>
<CENTER align><16 cs><(AvantGarde) cf ><ON bo>Scanning<SIZE type_rev><(Palatino
) cf ><BO type_rev><eop>
<ALIGN para_rev><eop>
<eop>
The scanner section is optional.  If there is a "<(Courier) cf >$$<
(Palatino) cf >" at the end of the file, the rest is considered to be almost st
raight <ON it>lex(1)<IT type_rev> source.  If there is a "<(Courier) cf >$$<(Pa
latino) cf >", every terminal must have a lexical value associated with it.  Ch
aracter and string constants are self-defining.  Other non-terminals need to be
X described in the lex section.<eop>
<eop>
An example wacco source file with scanner:<eop>
<eop>
<(Courier) cf ><tab>expr: LPAREN expr RPAREN | "id" | [];<eop>
<eop>
<tab>$$<eop>
<eop>
<tab>%%<eop>
<eop>
<tab>"."<tab><tab>{ return (int)EOI; }<eop>
<eop>
<tab>$LPAREN<tab><tab>"("|"["<eop>
<tab>$RPAREN<tab><tab>")"|"]"<eop>
<eop>
<tab>[ \t\v\n\f]<tab>;<eop>
<tab>.  { w_scanerr("Illegal character %d (%c)",<eop>
<tab><tab>yytext[0], yytext[0]); }<eop>
<(Palatino) cf ><eop>
The string "<
(Courier) cf >id<(Palatino) cf >" naturally stands for itself.  <ON it>LPAREN<I
T type_rev> and <ON it>RPAREN<IT type_rev> are described in the lex section in 
reverse order from a normal lex file.  Wacco will convert those lines starting 
with a "<(Courier) cf >$<(Palatino) cf >" into the appropriate lex output. This
X is not only to make sure that all terminals are defined, but allows defining a
X language without ever having to manually define token ids for any terminal sym
bol!<eop>
<eop>
<eop>
<
(AvantGarde) cf ><14 cs><ON bo>Default scanner<(Palatino) cf ><SIZE type_rev><B
O type_rev><eop>
<eop>
The default scanner (located in -lwacco) maintains its own I/O file pointer.  T
his is so that user code can implement the equivalent of "<(Courier) cf >#inclu
de<(Palatino) cf >" without too much work.  The functions in the scanner includ
e:<eop>
<eop>
<tab><(Courier) cf >int w_openfile(char *fname)<
(Palatino) cf ><tab>// open a file to the specified name<eop>
<tab><(Courier) cf >void w_closefile()<(Palatino) cf ><tab><tab>// close the la
st opened file<eop>
<tab><(Courier) cf >void w_setfile(FILE *f)<(Palatino) cf ><tab>// set the curr
ent file to this<eop>
<tab><
(Courier) cf >FILE *w_getfile()<(Palatino) cf ><tab><tab>// return the currentl
y opened file<eop>
<tab><(Courier) cf >int w_currcol()<(Palatino) cf ><tab><tab>// the current col
umn in the input<eop>
<tab><(Courier) cf >int w_currline()<
(Palatino) cf ><tab><tab>// the current line in the input<eop>
<tab><(Courier) cf >char *w_getcurrline()<(Palatino) cf ><tab>// the text of th
e current line<eop>
<tab><(Courier) cf >int w_input()<tab><(Palatino) cf ><tab>// basic I/O routine
s which are<eop>
<tab><
(Courier) cf >int w_unput(int c)<(Palatino) cf ><tab><tab>//          to be use
d by the scanner<eop>
<tab><(Courier) cf >void w_output(int c)<(Palatino) cf ><eop>
<eop>
You should call either <(Courier) cf >w_setfile()<
(Palatino) cf > or <(Courier) cf >w_openfile()<(Palatino) cf > before starting 
the parse or the default scanner will probably dump core.<eop>
<eop>
<eop>
<
(AvantGarde) cf ><14 cs><ON bo>Parser's requirements<(Palatino) cf ><SIZE type_
rev><BO type_rev><eop>
<eop>
The functions that the parser expects to have available are:<eop>
<eop>
<tab><(Courier) cf >int w_gettoken()<(Palatino) cf ><tab><tab>// get the next t
oken - usually calls yylex()<eop>
<tab><tab><tab><tab>// - must return <ON it>EOI<IT type_rev> on end-of-input<eo
p>
<eop>
<tab><(Courier) cf >int w_scanerr()<
(Palatino) cf ><tab><tab>// printf-type error printing routine<eop>
<tab><tab><tab><tab>// - must always returns <ON it>RETERR<IT type_rev><eop>
<tab><tab><tab><tab>// - is called with a <ON it>NULL<IT type_rev> argument<eop
>
<tab><tab><tab><tab>// when just skipping a token in the input<eop>
<eop>
These are either are in the wacco library -lwacco, or must be provided by the u
ser.<eop>
<eop>
The default <(Courier) cf >w_scanerr()<(Palatino) cf > will try to print the li
ne that had the error, and underneath it print "<(Courier) cf >^<(Palatino) cf 
>" where the error occurred and "<
(Courier) cf >*<(Palatino) cf >" where tokens were skipped when re-syncing.  Be
cause of some lex(1) funnies, this doesn't always work as expected.<eop>
<eop>
<eop>
<(AvantGarde) cf ><14 cs><ON bo>Parser functions<(Palatino) cf ><SIZE type_rev>
<BO type_rev><eop>
<eop>
Some other convenient functions defined in <ON it>parser.C<IT type_rev> include
:<eop>
<eop>
<tab><(Courier) cf >int w_nexttoken(<
(Palatino) cf >)<tab>// return the value of the next token but don't<eop>
<tab><tab><tab>// scan it yet - calls <(Courier) cf >w_gettoken()<(Palatino) cf
X > at most once<eop>
<tab><tab><tab>// - useful for token look-ahead<eop>
<eop>
<tab><(Courier) cf >void w_skiptoken()<(Palatino) cf ><tab>// scan the current 
token - the next call to<eop>
<tab><tab><tab>// <
(Courier) cf >w_nexttoken()<(Palatino) cf > will actually read another token<eo
p>
<eop>
<tab><(Courier) cf >char *w_tokenname(int tokid)<(Palatino) cf ><tab>// return 
the string name of a token<eop>
<tab><tab><tab><tab>// whose id is tokid<eop>
<eop>
These are only really useful if you are writing your own scanner instead of usi
ng lex.  <(Courier) cf >w_nexttoken()<
(Palatino) cf > and <(Courier) cf >w_skiptoken()<(Palatino) cf > can also be us
ed to somewhat direct the parse.  If you provide your own infinite push-back st
ack of tokens, you can completely alter the parse at run-time!<eop>
<eop>
<eop>
<(AvantGarde) cf ><14 cs><ON bo>Flex<(Palatino) cf ><SIZE type_rev><BO type_rev
><eop>
<eop>
The program <ON it>flex(1)<IT type_rev> may be used instead of <ON it>lex(1)<IT
X type_rev> if desired, and is highly recommended.<eop>
<eop>
The extern for "<
(Courier) cf >yytext<(Palatino) cf >" is automatically declared in <ON it>parse
r.C<IT type_rev>. Unfortunately, it may be wrong for the scanner generator actu
ally being used.  To change the definition, the macro <ON it>YYTEXT_DECL<IT typ
e_rev> may be redefined at the top of your wacco grammar if you wish to use fle
x:<eop>
<eop>
<(Courier) cf ><tab>{<eop>
<tab>#undef YYTEXT_DECL<eop>
<tab>#define YYTEXT_DECL char *yytext<eop>
<tab>}<eop>
<tab>...<eop>
<(Palatino) cf ><eop>
<pe><eop>
<CENTER align><CENTER align><(AvantGarde) cf ><ON bo> <16 cs>Example Wacco Gram
mar<SIZE type_rev><eop>
<ALIGN para_rev><
(Palatino) cf ><BO type_rev><eop>
<eop>
// This is the usual required calculator sample.  It can still use<eop>
// a LOT of work, but it illustrates the basics.  Note that the<eop>
// precedence of operators is all wrong.<eop>
<eop>
<
(Courier) cf >{<eop>
#include <la>stdio.h<ra><eop>
#include <la>stdlib.h<ra><eop>
}<eop>
<eop>
calc<eop>
<tab>:<tab>%{<eop>
<tab><tab><tab>while (w_nexttoken() != EOI) {<eop>
<tab><tab>%}<eop>
<tab><tab>expr ([] | '=' | ';' | ',')<eop>
<tab><tab>%{<eop>
<tab><tab><tab>printf("%f\n", $expr);<eop>
<tab><tab><tab>}<eop>
<tab><tab>%}<eop>
<tab>| []<eop>
<tab>;<eop>
<eop>
expr<la>double<ra><eop>
<tab>:<tab>term { $binop_expr = $term; }<eop>
<tab><tab><tab>binop_expr { $$ = $binop_expr; }<eop>
<tab>;<eop>
<eop>
binop_expr<la>double<ra><eop>
<tab>:<tab>'+' expr { $$ += $expr; }<eop>
<tab>|<tab>'-' expr { $$ -= $expr; }<eop>
<tab>|<tab>'*' expr { $$ *= $expr; }<eop>
<tab>|<tab>'/' expr { $$ /= $expr; }<eop>
<tab>|<tab>'&' expr { $$ = (int)$$ & (int)$expr; }<eop>
<tab>|<tab>'|' expr { $$ = (int)$$ | (int)$expr; }<eop>
<tab>|<tab>'^' expr { $$ = (int)$$ ^ (int)$expr; }<eop>
<tab>|<tab>"<la><la>" expr { $$ = (int)$$ <la><la> (int)$expr; }<eop>
<tab>|<tab>"<ra><ra>" expr { $$ = (int)$$ <ra><ra> (int)$expr; }<eop>
<tab>|<tab>"&&" expr { $$ = $$ && $expr; }<eop>
<tab>|<tab>"||" expr { $$ = $$ || $expr; }<eop>
<tab>|<tab>[]<eop>
<tab>;<eop>
<eop>
term<la>double<ra><eop>
<tab>:<tab>DOUBLE { $$ = atof((char *)yytext); }<eop>
<tab>|<tab>'-' expr { $$ = -$expr; }<eop>
<tab>|<tab>'~' expr { $$ = ~(int)$expr; }<eop>
<tab>|<tab>'!' expr { $$ = !$expr; }<eop>
<tab>|<tab>'(' expr ')' { $$ = $expr; }<eop>
<tab>;<eop>
<eop>
{<eop>
<tab>main()<eop>
<tab>{<eop>
<tab><tab>w_setfile(stdin);<eop>
<tab><tab>calc();<eop>
<tab>}<eop>
}<eop>
<eop>
$$<eop>
<eop>
D<tab>[0-9]<eop>
L<tab>[_A-Za-z]<eop>
<eop>
%%<eop>
<eop>
"."<tab><tab>{ return (int)EOI; }<eop>
<eop>
$DOUBLE<tab>({D}+)|({D}+\.{D}+)|({D}+[Ee]-?{D}+)|({D}+\.{D}+[Ee]-?{D}+)<eop>
<eop>
"#".*$<tab><tab>;<eop>
<eop>
[ \t\v\n\f]<tab>;<eop>
.<tab>{ w_scanerr("Illegal character %d ($c)", yytext[0], yytext[0]); }<eop>
X
<textstream_end> 5580 1725 7080 1725 
0 100 -1 0 0 0 0 (2) 7 
rule 
X
POLY_OBJECT POLY_TEXT |  DefPolyType 
X
0 DefLineWidth TRANSPARENT DefPenColor TRANSPARENT DefFillColor 1 DefIG 300 
DefResolution 100 DefYScale 100 DefXScale (=default) DefPolyResId 1 
DefMasterRef 
X
MP_CPSUCC_LINK MP_CPPRED_LINK LINK_OVERFLOW MPREF_VALID POLY_COLUMN AUTO_STREAM | | | | | 
DefSLinksFlags 10 DefStreamSucc 5 DefStreamPred 6 DefTextHandle 
1440 1080 11160 1080 11160 14760 1440 14760 4 
POLY_OBJECT POLY_TEXT |  (3) 0 8 TextPolygon 5520 1710 7110 1710 
0 100 -1 0 0 0 0 (3) 9 
rule 
X
POLY_OBJECT POLY_TEXT |  DefPolyType 
X
0 DefLineWidth TRANSPARENT DefPenColor TRANSPARENT DefFillColor 1 DefIG 300 
DefResolution 100 DefYScale 100 DefXScale (=default) DefPolyResId 1 
DefMasterRef 
X
MP_CPSUCC_LINK MP_CPPRED_LINK LINK_OVERFLOW MPREF_VALID POLY_COLUMN AUTO_STREAM | | | | | 
DefSLinksFlags 12 DefStreamSucc 8 DefStreamPred 6 DefTextHandle 
1440 1080 11160 1080 11160 14760 1440 14760 4 
POLY_OBJECT POLY_TEXT |  (4) 0 10 TextPolygon 5910 1695 6720 1695 
0 100 -1 0 0 0 0 (4) 11 
rule 
X
POLY_OBJECT POLY_TEXT |  DefPolyType 
X
0 DefLineWidth TRANSPARENT DefPenColor TRANSPARENT DefFillColor 1 DefIG 300 
DefResolution 100 DefYScale 100 DefXScale (=default) DefPolyResId 1 
DefMasterRef 
X
MP_CPSUCC_LINK MP_CPPRED_LINK LINK_OVERFLOW MPREF_VALID POLY_COLUMN AUTO_STREAM | | | | | 
DefSLinksFlags 13 DefStreamSucc 10 DefStreamPred 6 DefTextHandle 
1440 1080 11160 1080 11160 14760 1440 14760 4 
POLY_OBJECT POLY_TEXT |  (5) 0 12 TextPolygon 
X
POLY_OBJECT POLY_TEXT |  DefPolyType 
X
0 DefLineWidth TRANSPARENT DefPenColor TRANSPARENT DefFillColor 1 DefIG 300 
DefResolution 100 DefYScale 100 DefXScale (=default) DefPolyResId 1 
DefMasterRef 
X
MP_CPSUCC_LINK MP_CPPRED_LINK LINK_OVERFLOW MPREF_VALID POLY_COLUMN AUTO_STREAM | | | | | 
DefSLinksFlags 14 DefStreamSucc 12 DefStreamPred 6 DefTextHandle 
1440 1080 11160 1080 11160 14760 1440 14760 4 
POLY_OBJECT POLY_TEXT |  (6) 0 13 TextPolygon 
X
POLY_OBJECT POLY_TEXT |  DefPolyType 
X
0 DefLineWidth TRANSPARENT DefPenColor TRANSPARENT DefFillColor 1 DefIG 300 
DefResolution 100 DefYScale 100 DefXScale (=default) DefPolyResId 1 
DefMasterRef 
X
MP_CPSUCC_LINK MP_CPPRED_LINK LINK_OVERFLOW MPREF_VALID POLY_COLUMN AUTO_STREAM | | | | | 
DefSLinksFlags 15 DefStreamSucc 13 DefStreamPred 6 DefTextHandle 
1440 1080 11160 1080 11160 14760 1440 14760 4 
POLY_OBJECT POLY_TEXT |  (7) 0 14 TextPolygon 
X
POLY_OBJECT POLY_TEXT |  DefPolyType 
X
0 DefLineWidth TRANSPARENT DefPenColor TRANSPARENT DefFillColor 1 DefIG 300 
DefResolution 100 DefYScale 100 DefXScale (=default) DefPolyResId 1 
DefMasterRef 
X
MP_CPSUCC_LINK MP_CPPRED_LINK LINK_OVERFLOW MPREF_VALID POLY_COLUMN AUTO_STREAM | | | | | 
DefSLinksFlags 16 DefStreamSucc 14 DefStreamPred 6 DefTextHandle 
1440 1080 11160 1080 11160 14760 1440 14760 4 
POLY_OBJECT POLY_TEXT |  (8) 0 15 TextPolygon 
X
POLY_OBJECT POLY_TEXT |  DefPolyType 
X
0 DefLineWidth TRANSPARENT DefPenColor TRANSPARENT DefFillColor 1 DefIG 300 
DefResolution 100 DefYScale 100 DefXScale (=default) DefPolyResId 1 
DefMasterRef 
X
MP_CPSUCC_LINK MP_CPPRED_LINK LINK_OVERFLOW MPREF_VALID POLY_COLUMN AUTO_STREAM | | | | | 
DefSLinksFlags 17 DefStreamSucc 15 DefStreamPred 6 DefTextHandle 
1440 1080 11160 1080 11160 14760 1440 14760 4 
POLY_OBJECT POLY_TEXT |  (9) 0 16 TextPolygon 
X
POLY_OBJECT POLY_TEXT |  DefPolyType 
X
0 DefLineWidth TRANSPARENT DefPenColor TRANSPARENT DefFillColor 1 DefIG 300 
DefResolution 100 DefYScale 100 DefXScale (=default) DefPolyResId 1 
DefMasterRef 
X
MP_CPSUCC_LINK MP_CPPRED_LINK LINK_OVERFLOW MPREF_VALID POLY_COLUMN AUTO_STREAM | | | | | 
DefSLinksFlags 19 DefStreamSucc 16 DefStreamPred 6 DefTextHandle 
1440 1080 11160 1080 11160 14760 1440 14760 4 
POLY_OBJECT POLY_TEXT |  (10) 0 17 TextPolygon 5580 1725 7020 1725 
0 100 -1 0 0 0 0 (10) 18 
rule 
X
POLY_OBJECT POLY_TEXT |  DefPolyType 
X
0 DefLineWidth TRANSPARENT DefPenColor TRANSPARENT DefFillColor 1 DefIG 300 
DefResolution 100 DefYScale 100 DefXScale (=default) DefPolyResId 1 
DefMasterRef 
X
MP_CPSUCC_LINK MP_CPPRED_LINK LINK_OVERFLOW MPREF_VALID POLY_COLUMN AUTO_STREAM | | | | | 
DefSLinksFlags 20 DefStreamSucc 17 DefStreamPred 6 DefTextHandle 
1440 1080 11160 1080 11160 14760 1440 14760 4 
POLY_OBJECT POLY_TEXT |  (11) 0 19 TextPolygon 
X
POLY_OBJECT POLY_TEXT |  DefPolyType 
X
0 DefLineWidth TRANSPARENT DefPenColor TRANSPARENT DefFillColor 1 DefIG 300 
DefResolution 100 DefYScale 100 DefXScale (=default) DefPolyResId 1 
DefMasterRef 
X
MP_CPSUCC_LINK MP_CPPRED_LINK LINK_OVERFLOW MPREF_VALID POLY_COLUMN AUTO_STREAM | | | | | 
DefSLinksFlags 21 DefStreamSucc 19 DefStreamPred 6 DefTextHandle 
1440 1080 11160 1080 11160 14760 1440 14760 4 
POLY_OBJECT POLY_TEXT |  (12) 0 20 TextPolygon 
X
POLY_OBJECT POLY_TEXT |  DefPolyType 
X
0 DefLineWidth TRANSPARENT DefPenColor TRANSPARENT DefFillColor 1 DefIG 300 
DefResolution 100 DefYScale 100 DefXScale (=default) DefPolyResId 1 
DefMasterRef 
X
MP_CPSUCC_LINK MP_CPPRED_LINK LINK_OVERFLOW MPREF_VALID POLY_COLUMN AUTO_STREAM | | | | | 
DefSLinksFlags 23 DefStreamSucc 20 DefStreamPred 6 DefTextHandle 
1440 1080 11160 1080 11160 14760 1440 14760 4 
POLY_OBJECT POLY_TEXT |  (13) 0 21 TextPolygon 4260 1725 8415 1725 
0 100 -1 0 0 0 0 (13) 22 
rule 
X
POLY_OBJECT POLY_TEXT |  DefPolyType 
X
0 DefLineWidth TRANSPARENT DefPenColor TRANSPARENT DefFillColor 1 DefIG 300 
DefResolution 100 DefYScale 100 DefXScale (=default) DefPolyResId 1 
DefMasterRef 
MP_CPSUCC_LINK MP_CPPRED_LINK MPREF_VALID POLY_COLUMN AUTO_STREAM | | | |  
DefSLinksFlags 0 DefStreamSucc 21 DefStreamPred 6 DefTextHandle 
1440 1080 11160 1080 11160 14760 1440 14760 4 
POLY_OBJECT POLY_TEXT |  (14) 0 23 TextPolygon 
X
BeginProfile 
(Number of Pages) (14)  DefProfileString 
(Language) (ENGLISH)  DefProfileString 
(Version) (IslandWrite Version 2.1)  DefProfileString 
(Creation Date) (31.July.1990 16:31)  DefProfileString 
(Revision History) (parag May 17, 1991 4:26 PM)  DefProfileString 
(Revision History) (parag May 17, 1991 4:22 PM)  DefProfileString 
(Revision History) (parag February 21, 1991 5:06 PM)  DefProfileString 
(Revision History) (parag February 21, 1991 5:05 PM)  DefProfileString 
(Revision History) (February 21, 1991 3:02 PM)  DefProfileString 
(Revision History) (.August.1990 15:43)  DefProfileString 
(Revision History) (.August.1990 15:32)  DefProfileString 
(Revision History) (.August.1990 14:40)  DefProfileString 
(Revision History) (.August.1990 14:37)  DefProfileString 
(Revision History) (.August.1990 14:37)  DefProfileString 
(Revision History) (.August.1990 14:31)  DefProfileString 
(Revision History) (.August.1990 14:28)  DefProfileString 
(Revision History) (.August.1990 14:27)  DefProfileString 
(Revision History) (.August.1990 14:26)  DefProfileString 
(Revision History) (.August.1990 14:26)  DefProfileString 
(Revision History) (.August.1990 14:23)  DefProfileString 
(Revision History) (.August.1990 14:18)  DefProfileString 
(Revision History) (.August.1990 14:17)  DefProfileString 
(Revision History) (.August.1990 14:16)  DefProfileString 
(Revision History) (.August.1990 14:12)  DefProfileString 
(Revision History) (.August.1990 17:42)  DefProfileString 
(Revision History) (.August.1990 17:08)  DefProfileString 
(Revision History) (.August.1990 16:45)  DefProfileString 
(Revision History) (.August.1990 16:12)  DefProfileString 
(Revision History) (.August.1990 14:58)  DefProfileString 
(Revision History) (.August.1990 14:58)  DefProfileString 
(Revision History) (.August.1990 14:55)  DefProfileString 
(Revision History) (.August.1990 14:55)  DefProfileString 
(Revision History) (.August.1990 14:55)  DefProfileString 
(Revision History) (.August.1990 14:54)  DefProfileString 
(Revision History) (.August.1990 14:53)  DefProfileString 
(Revision History) (.August.1990 14:52)  DefProfileString 
(Revision History) (.August.1990 14:47)  DefProfileString 
(Revision History) (.August.1990 14:41)  DefProfileString 
(Revision History) (.August.1990 14:38)  DefProfileString 
(Revision History) (.August.1990 14:38)  DefProfileString 
(Revision History) (.August.1990 14:37)  DefProfileString 
(Revision History) (.August.1990 14:34)  DefProfileString 
(Revision History) (.August.1990 14:20)  DefProfileString 
(Revision History) (.August.1990 14:13)  DefProfileString 
(Revision History) (.August.1990 14:04)  DefProfileString 
(Revision History) (.August.1990 13:35)  DefProfileString 
(Revision History) (.August.1990 13:29)  DefProfileString 
(Revision History) (.August.1990 13:28)  DefProfileString 
(Revision History) (.August.1990 12:00)  DefProfileString 
(Revision History) (.August.1990 11:56)  DefProfileString 
(Revision History) (.August.1990 11:55)  DefProfileString 
(Revision History) (.August.1990 11:52)  DefProfileString 
(Revision History) (.August.1990 11:51)  DefProfileString 
(Revision History) (.August.1990 11:48)  DefProfileString 
(Revision History) (.August.1990 11:44)  DefProfileString 
(Revision History) (31.July.1990 17:29)  DefProfileString 
(Revision History) (31.July.1990 17:28)  DefProfileString 
(Revision History) (31.July.1990 17:24)  DefProfileString 
(Revision History) (31.July.1990 17:22)  DefProfileString 
(Revision History) (31.July.1990 17:19)  DefProfileString 
(Revision History) (31.July.1990 17:18)  DefProfileString 
(Revision History) (31.July.1990 17:15)  DefProfileString 
(Revision History) (31.July.1990 17:14)  DefProfileString 
(Revision History) (31.July.1990 17:11)  DefProfileString 
(Revision History) (31.July.1990 17:11)  DefProfileString 
(Revision History) (31.July.1990 17:10)  DefProfileString 
(Revision History) (31.July.1990 17:08)  DefProfileString 
(Revision History) (31.July.1990 17:07)  DefProfileString 
(Revision History) (31.July.1990 17:05)  DefProfileString 
(Revision History) (31.July.1990 16:54)  DefProfileString 
(Revision History) (31.July.1990 16:48)  DefProfileString 
(Revision History) (31.July.1990 16:40)  DefProfileString 
(Revision History) (31.July.1990 16:37)  DefProfileString 
(Revision History) (31.July.1990 16:35)  DefProfileString 
(Revision History) (31.July.1990 16:34)  DefProfileString 
(Revision History) (31.July.1990 16:31)  DefProfileString 
(Text Formats) (default)  DefProfileString 
(Container Formats) (default)  DefProfileString 
(Page Formats) (default)  DefProfileString 
(Fonts) (AvantGarde)  DefProfileString 
(Fonts) (Palatino)  DefProfileString 
(Fonts) (Courier)  DefProfileString 
(Fonts) (Times-Roman)  DefProfileString 
(File Path) ()  DefProfileString 
(External Contents) ()  DefProfileString 
(Title) ()  DefProfileString 
(Status) ()  DefProfileString 
(Distribution List) ()  DefProfileString 
(Preparer) ()  DefProfileString 
(Owner) ()  DefProfileString 
(Author) ()  DefProfileString 
(Superseded Documents) ()  DefProfileString 
EndProfile 
X
pgscriptdone 
SHAR_EOF
chmod 0444 wacco.doc.iw ||
echo 'restore of wacco.doc.iw failed'
Wc_c="`wc -c < 'wacco.doc.iw'`"
test 42897 -eq "$Wc_c" ||
	echo 'wacco.doc.iw: original size 42897, current size' "$Wc_c"
fi
true || echo 'restore of wacco.doc.ps failed'
echo End of part 2, continue with part 3
exit 0

exit 0 # Just in case...
-- 
Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
Sterling Software, IMD           UUCP:     uunet!sparky!kent
Phone:    (402) 291-8300         FAX:      (402) 291-4362
Please send comp.sources.misc-related mail to kent@uunet.uu.net.