summaryrefslogtreecommitdiff
path: root/man/1/yacc
blob: c3ec58689b45488b126a6cd60e075fbf5ceabdd7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
.TH YACC 1
.SH NAME
yacc \- yet another compiler-compiler (Limbo version)
.SH SYNOPSIS
.B yacc
[
.I option ...
]
.I grammar
.SH DESCRIPTION
.I Yacc
converts a context-free grammar and translation code
into a set of
tables for an LR(1) parser and translator.
The grammar may be ambiguous;
specified precedence rules are used to break ambiguities.
.PP
The output from
.I yacc
is a Limbo module
.B y.tab.b
containing the parse function
.B yyparse
which must be provided with a
.B YYLEX
adt providing the parser access to a lexical analyser
routine
.BR lex() ,
an error routine
.BR error() ,
and any other context required.
.PP
The options are
.TP "\w'\fL-o \fIoutput\fLXX'u"
.BI -o " output
Direct output to the specified file instead of
.BR y.tab.b .
.TP
.BI -D n
Create file
.BR y.debug ,
containing diagnostic messages.
To incorporate them in the parser, give an
.I n
greater than zero.
The amount of 
diagnostic output from the parser is regulated by
value
.IR n :
.RS 
.TP
1
Report errors.
.TP
2
Also report reductions.
.TP
3
Also report the name of each token returned by
.LR yylex .
.RE
.TP
.B -v
Create file
.BR y.output ,
containing a description of the parsing tables and of
conflicts arising from ambiguities in the grammar.
.TP
.B -d
Create file
.BR y.tab.m ,
containing the module
declaration for the parser, along with
definitions of the constants
that associate
.IR yacc -assigned
`token codes' with user-declared `token names'.
Include it in source files other than
.B y.tab.b
to give access to the token codes and the parser module.
.TP
.BI -s " stem
Change the prefix
.L y 
of the file names
.BR y.tab.b ,
.BR y.tab.m ,
.BR y.debug ,
and
.B y.output
to
.IR stem .
.TP
.B -m
Normally
.I yacc
defines the type of the
.B y.tab.b
module within the text of the module according
to the contents of the
.B %module
directive.
Giving the
.B -m
option suppresses this behaviour, leaving the implementation
free to define the module's type from an external
.B .m
file. The module's type name is still taken from the
.B %module
directive.
.TP
.BI -n " size
Specify the initial
.I size
of the token stack created for the
parser (default: 200).
.SS Differences from C yacc
The Limbo
.I yacc
is in many respects identical to the C
.IR yacc .
The differences are summarised below:
.PP
Comments follow the Limbo convention (a
.B #
symbol gives a comment until the end of the line).
.PP
A
.B %module
directive is required, which replaces the
.B %union
directive. It is of the form:
.RS
.IP
.B %module
.I modname
.B {
.br
.I 	module types, functions and constants
.br
.B }
.RE
.B Modname
will be the module's implementation type;
the body of the directive, augmented with
.B con
definitions for the
.IR yacc -assigned
token codes, gives the type of the module,
unless the
.B -m
option is given, in which case no module
definition is emitted.
.PP
A type
.B YYSTYPE
must be defined, giving the type
associated with
.I yacc
tokens. If
the angle bracket construction is used after
any of the
.BR %token ,
.BR %left ,
.BR %right ,
.BR %nonassoc 
or
.B %type
directives in order to associate a type with a token or production,
the word inside the angle brackets
refers to a member of 
an instance of
.BR YYSTYPE ,
which should be an adt.
.PP
An adt
.B YYLEX
must be defined, providing context to the parser.
The definition must consist of at least the following:
.EX
	YYLEX: adt {
		lval: YYSTYPE;
		lex: fn(l: self ref YYLEX): int;
		error: fn(l: self ref YYLEX, msg: string);
	}
.EE
.B Lex
should invoke a lexical analyser to return the
next token for
.I yacc
to analyse. The value of the token should
be left in
.BR lval .
.B Error
will be called when a parse error occurs.
.B Msg
is a string describing the error.
.PP
.B Yyparse
takes one argument, a reference to the
.B YYLEX
adt that will be used to provide it with tokens.
.PP
The parser is fully re-entrant;
.I i.e.
it does not
hold any parse state in any global variables
within the module.
.SH EXAMPLE
The following is a small but complete example of the
use of Limbo
.I yacc
to build a simple calculator.
.EX
%{
    include "sys.m";
    sys: Sys;

    include "bufio.m";
    bufio: Bufio;
    Iobuf: import bufio;

    include "draw.m";

    YYSTYPE: adt { v: real; };
    YYLEX: adt {
        lval:   YYSTYPE;
        lex: fn(l: self ref YYLEX): int;
        error: fn(l: self ref YYLEX, msg: string);
    };
%}

%module Calc{
    init:   fn(ctxt: ref Draw->Context, args: list of string);
}

%left   '+' '-'
%left   '*' '/'

%type   <v> exp uexp term
%token  <v> REAL

%%
top :
    | top '\en'
    | top exp '\en'
    {
        sys->print("%g\en", $2);
    }
    | top error '\en'
    ;

exp : uexp
    | exp '*' exp   { $$ = $1 * $3; }
    | exp '/' exp   { $$ = $1 / $3; }
    | exp '+' exp   { $$ = $1 + $3; }
    | exp '-' exp   { $$ = $1 - $3; }
    ;

uexp    : term
    | '+' uexp  { $$ = $2; }
    | '-' uexp  { $$ = -$2; }
    ;

term    : REAL
    | '(' exp ')'
    {
        $$ = $2;
    }
    ;

%%

in: ref Iobuf;
stderr: ref Sys->FD;

init(nil: ref Draw->Context, nil: list of string)
{
	sys = load Sys Sys->PATH;
	bufio = load Bufio Bufio->PATH;
	in = bufio->fopen(sys->fildes(0), Bufio->OREAD);
	stderr = sys->fildes(2);
	lex := ref YYLEX;
	yyparse(lex);
}

YYLEX.error(nil: self ref YYLEX, err: string)
{
	sys->fprint(stderr, "%s\en", err);
}

YYLEX.lex(lex: self ref YYLEX): int
{
	for(;;){
		c := in.getc();
		case c{
		' ' or '\et' =>
			;
		'-' or '+' or '*' or '/' or '\en' or '(' or ')' =>
			return c;
		'0' to '9' or '.' =>
			s := "";
			i := 0;
			s[i++] = c;
			while((c = in.getc()) >= '0' && c <= '9' ||
			      c == '.' ||
			      c == 'e' || c == 'E')
				s[i++] = c;
			in.ungetc();
			lex.lval.v = real s;
			return REAL;
		* =>
			return -1;
		}
	}
}
.EE
.SH FILES
.TF /lib/yaccpar
.TP
.B y.output
.TP
.B y.tab.b
.TP
.B y.tab.m
.TP
.B y.debug
.TP
.B /lib/yaccpar
parser prototype
.SH SOURCE
.B /appl/cmd/yacc.b
.SH "SEE ALSO"
S. C. Johnson and R. Sethi,
``Yacc: A parser generator'',
.I
Unix Research System Programmer's Manual,
Tenth Edition, Volume 2
.br
B. W. Kernighan and Rob Pike,
.I
The UNIX Programming Environment,
Prentice Hall, 1984
.SH BUGS
The parser may not have full information when it writes to
.B y.debug
so that the names of the tokens returned by
.L yylex
may be missing.