1 /* $OpenBSD: lalr.c,v 1.19 2017/05/25 20:11:03 tedu Exp $ */
2 /* $NetBSD: lalr.c,v 1.4 1996/03/19 03:21:33 jtc Exp $ */
5 * Copyright (c) 1989 The Regents of the University of California.
8 * This code is derived from software contributed to Berkeley by
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 typedef struct shorts
{
47 short *accessing_symbol
;
50 reductions
**reduction_table
;
55 short **transpose(short **, int);
56 void set_state_table(void);
57 void set_accessing_symbol(void);
58 void set_shift_table(void);
59 void set_reduction_table(void);
60 void set_maxrhs(void);
61 void initialize_LA(void);
62 void set_goto_map(void);
63 void initialize_F(void);
64 void build_relations(void);
65 void compute_FOLLOWS(void);
66 void compute_lookaheads(void);
67 int map_goto(int, int);
68 void digraph(short **);
69 void add_lookback_edge(int, int, int);
76 static short **includes
;
77 static shorts
**lookback
;
80 static short *VERTICES
;
86 tokensetsize
= WORDSIZE(ntokens
);
89 set_accessing_symbol();
91 set_reduction_table();
105 set_state_table(void)
109 state_table
= NEW2(nstates
, core
*);
110 for (sp
= first_state
; sp
; sp
= sp
->next
)
111 state_table
[sp
->number
] = sp
;
116 set_accessing_symbol(void)
120 accessing_symbol
= NEW2(nstates
, short);
121 for (sp
= first_state
; sp
; sp
= sp
->next
)
122 accessing_symbol
[sp
->number
] = sp
->accessing_symbol
;
127 set_shift_table(void)
131 shift_table
= NEW2(nstates
, shifts
*);
132 for (sp
= first_shift
; sp
; sp
= sp
->next
)
133 shift_table
[sp
->number
] = sp
;
138 set_reduction_table(void)
142 reduction_table
= NEW2(nstates
, reductions
*);
143 for (rp
= first_reduction
; rp
; rp
= rp
->next
)
144 reduction_table
[rp
->number
] = rp
;
151 short *itemp
, *item_end
;
156 item_end
= ritem
+ nitems
;
157 for (itemp
= ritem
; itemp
< item_end
; itemp
++) {
161 if (length
> max
) max
= length
;
176 lookaheads
= NEW2(nstates
+ 1, short);
179 for (i
= 0; i
< nstates
; i
++) {
181 rp
= reduction_table
[i
];
185 lookaheads
[nstates
] = k
;
187 LA
= NEW2(k
* tokensetsize
, unsigned);
188 LAruleno
= NEW2(k
, short);
189 lookback
= NEW2(k
, shorts
*);
192 for (i
= 0; i
< nstates
; i
++) {
193 rp
= reduction_table
[i
];
195 for (j
= 0; j
< rp
->nreds
; j
++) {
196 LAruleno
[k
] = rp
->rules
[j
];
211 goto_map
= NEW2(nvars
+ 1, short) - ntokens
;
212 temp_map
= NEW2(nvars
+ 1, short) - ntokens
;
215 for (sp
= first_shift
; sp
; sp
= sp
->next
) {
216 for (i
= sp
->nshifts
- 1; i
>= 0; i
--) {
217 symbol
= accessing_symbol
[sp
->shift
[i
]];
219 if (ISTOKEN(symbol
)) break;
221 if (ngotos
== MAXSHORT
)
222 fatal("too many gotos");
230 for (i
= ntokens
; i
< nsyms
; i
++) {
235 for (i
= ntokens
; i
< nsyms
; i
++)
236 goto_map
[i
] = temp_map
[i
];
238 goto_map
[nsyms
] = ngotos
;
239 temp_map
[nsyms
] = ngotos
;
241 from_state
= NEW2(ngotos
, short);
242 to_state
= NEW2(ngotos
, short);
244 for (sp
= first_shift
; sp
; sp
= sp
->next
) {
246 for (i
= sp
->nshifts
- 1; i
>= 0; i
--) {
247 state2
= sp
->shift
[i
];
248 symbol
= accessing_symbol
[state2
];
250 if (ISTOKEN(symbol
)) break;
252 k
= temp_map
[symbol
]++;
253 from_state
[k
] = state1
;
254 to_state
[k
] = state2
;
258 free(temp_map
+ ntokens
);
263 /* Map_goto maps a state/symbol pair into its numeric representation. */
266 map_goto(int state
, int symbol
)
268 int high
, low
, middle
, s
;
270 low
= goto_map
[symbol
];
271 high
= goto_map
[symbol
+ 1];
275 middle
= (low
+ high
) >> 1;
276 s
= from_state
[middle
];
292 short *edge
, *rp
, **reads
;
294 int nedges
, stateno
, symbol
, nwords
;
296 nwords
= ngotos
* tokensetsize
;
297 F
= NEW2(nwords
, unsigned);
299 reads
= NEW2(ngotos
, short *);
300 edge
= NEW2(ngotos
+ 1, short);
304 for (i
= 0; i
< ngotos
; i
++) {
305 stateno
= to_state
[i
];
306 sp
= shift_table
[stateno
];
311 for (j
= 0; j
< k
; j
++) {
312 symbol
= accessing_symbol
[sp
->shift
[j
]];
315 SETBIT(rowp
, symbol
);
319 symbol
= accessing_symbol
[sp
->shift
[j
]];
320 if (nullable
[symbol
])
321 edge
[nedges
++] = map_goto(stateno
, symbol
);
325 reads
[i
] = rp
= NEW2(nedges
+ 1, short);
327 for (j
= 0; j
< nedges
; j
++)
335 rowp
+= tokensetsize
;
341 for (i
= 0; i
< ngotos
; i
++)
350 build_relations(void)
355 int length
, nedges
, done
;
356 int state1
, stateno
, symbol1
, symbol2
;
357 short *shortp
, *edge
, *states
;
358 short **new_includes
;
360 includes
= NEW2(ngotos
, short *);
361 edge
= NEW2(ngotos
+ 1, short);
362 states
= NEW2(maxrhs
+ 1, short);
364 for (i
= 0; i
< ngotos
; i
++) {
366 state1
= from_state
[i
];
367 symbol1
= accessing_symbol
[to_state
[i
]];
369 for (rulep
= derives
[symbol1
]; *rulep
>= 0; rulep
++) {
374 for (rp
= ritem
+ rrhs
[*rulep
]; *rp
>= 0; rp
++) {
376 sp
= shift_table
[stateno
];
379 for (j
= 0; j
< k
; j
++) {
380 stateno
= sp
->shift
[j
];
381 if (accessing_symbol
[stateno
] == symbol2
)
385 states
[length
++] = stateno
;
388 add_lookback_edge(stateno
, *rulep
, i
);
396 stateno
= states
[--length
];
397 edge
[nedges
++] = map_goto(stateno
, *rp
);
398 if (nullable
[*rp
] && length
> 0)
405 includes
[i
] = shortp
= NEW2(nedges
+ 1, short);
406 for (j
= 0; j
< nedges
; j
++)
412 new_includes
= transpose(includes
, ngotos
);
414 for (i
= 0; i
< ngotos
; i
++)
419 includes
= new_includes
;
426 add_lookback_edge(int stateno
, int ruleno
, int gotono
)
431 i
= lookaheads
[stateno
];
432 k
= lookaheads
[stateno
+ 1];
434 while (!found
&& i
< k
) {
435 if (LAruleno
[i
] == ruleno
)
443 sp
->next
= lookback
[i
];
451 transpose(short **old_R
, int n
)
453 short **new_R
, **temp_R
, *nedges
, *sp
;
456 nedges
= NEW2(n
, short);
458 for (i
= 0; i
< n
; i
++) {
466 new_R
= NEW2(n
, short *);
467 temp_R
= NEW2(n
, short *);
469 for (i
= 0; i
< n
; i
++) {
472 sp
= NEW2(k
+ 1, short);
481 for (i
= 0; i
< n
; i
++) {
485 *temp_R
[*sp
++]++ = i
;
496 compute_FOLLOWS(void)
502 compute_lookaheads(void)
505 unsigned int *fp1
, *fp2
, *fp3
;
510 n
= lookaheads
[nstates
];
511 for (i
= 0; i
< n
; i
++) {
512 fp3
= rowp
+ tokensetsize
;
513 for (sp
= lookback
[i
]; sp
; sp
= sp
->next
) {
515 fp2
= F
+ tokensetsize
* sp
->value
;
522 for (i
= 0; i
< n
; i
++)
523 for (sp
= lookback
[i
]; sp
; sp
= next
) {
533 digraph(short **relation
)
537 infinity
= ngotos
+ 2;
538 INDEX
= NEW2(ngotos
+ 1, short);
539 VERTICES
= NEW2(ngotos
+ 1, short);
543 memset(INDEX
, 0, ngotos
* sizeof(short));
544 for (i
= 0; i
< ngotos
; i
++)
556 unsigned int *base
, *fp1
, *fp2
, *fp3
;
561 INDEX
[i
] = height
= top
;
563 base
= F
+ i
* tokensetsize
;
564 fp3
= base
+ tokensetsize
;
568 while ((j
= *rp
++) >= 0) {
572 if (INDEX
[i
] > INDEX
[j
])
576 fp2
= F
+ j
* tokensetsize
;
583 if (INDEX
[i
] == height
) {
592 fp2
= F
+ j
* tokensetsize
;