1 /* $NetBSD: lalr.c,v 1.10 2006/05/24 18:06:58 christos Exp $ */
4 * Copyright (c) 1989 The Regents of the University of California.
7 * This code is derived from software contributed to Berkeley by
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 #include <sys/cdefs.h>
36 #if defined(__RCSID) && !defined(lint)
38 static char sccsid
[] = "@(#)lalr.c 5.3 (Berkeley) 6/1/90";
40 __RCSID("$NetBSD: lalr.c,v 1.10 2006/05/24 18:06:58 christos Exp $");
57 short *accessing_symbol
;
60 reductions
**reduction_table
;
65 static int tokensetsize
;
67 static short **transpose(short **, int);
68 static void set_state_table(void);
69 static void set_accessing_symbol(void);
70 static void set_shift_table(void);
71 static void set_reduction_table(void);
72 static void set_maxrhs(void);
73 static void initialize_LA(void);
74 static void set_goto_map(void);
75 static void initialize_F(void);
76 static void build_relations(void);
77 static void compute_FOLLOWS(void);
78 static void compute_lookaheads(void);
80 static int map_goto(int, int);
81 static void digraph(short **);
82 static void add_lookback_edge(int, int, int);
83 static void traverse(int);
90 static short **includes
;
91 static shorts
**lookback
;
94 static short *VERTICES
;
100 tokensetsize
= WORDSIZE(ntokens
);
103 set_accessing_symbol();
105 set_reduction_table();
112 compute_lookaheads();
117 set_state_table(void)
121 state_table
= NEW2(nstates
, core
*);
122 for (sp
= first_state
; sp
; sp
= sp
->next
)
123 state_table
[sp
->number
] = sp
;
128 set_accessing_symbol(void)
132 accessing_symbol
= NEW2(nstates
, short);
133 for (sp
= first_state
; sp
; sp
= sp
->next
)
134 accessing_symbol
[sp
->number
] = sp
->accessing_symbol
;
139 set_shift_table(void)
143 shift_table
= NEW2(nstates
, shifts
*);
144 for (sp
= first_shift
; sp
; sp
= sp
->next
)
145 shift_table
[sp
->number
] = sp
;
150 set_reduction_table(void)
154 reduction_table
= NEW2(nstates
, reductions
*);
155 for (rp
= first_reduction
; rp
; rp
= rp
->next
)
156 reduction_table
[rp
->number
] = rp
;
170 item_end
= ritem
+ nitems
;
171 for (itemp
= ritem
; itemp
< item_end
; itemp
++)
179 if (length
> max
) max
= length
;
194 lookaheads
= NEW2(nstates
+ 1, short);
197 for (i
= 0; i
< nstates
; i
++)
200 rp
= reduction_table
[i
];
204 lookaheads
[nstates
] = k
;
206 LA
= NEW2(k
* tokensetsize
, unsigned);
207 LAruleno
= NEW2(k
, short);
208 lookback
= NEW2(k
, shorts
*);
211 for (i
= 0; i
< nstates
; i
++)
213 rp
= reduction_table
[i
];
216 for (j
= 0; j
< rp
->nreds
; j
++)
218 LAruleno
[k
] = rp
->rules
[j
];
237 goto_map
= NEW2(nvars
+ 1, short) - ntokens
;
238 temp_map
= NEW2(nvars
+ 1, short) - ntokens
;
241 for (sp
= first_shift
; sp
; sp
= sp
->next
)
243 for (i
= sp
->nshifts
- 1; i
>= 0; i
--)
245 symbol
= accessing_symbol
[sp
->shift
[i
]];
247 if (ISTOKEN(symbol
)) break;
249 if (ngotos
== MAXSHORT
)
250 fatal("too many gotos");
258 for (i
= ntokens
; i
< nsyms
; i
++)
264 for (i
= ntokens
; i
< nsyms
; i
++)
265 goto_map
[i
] = temp_map
[i
];
267 goto_map
[nsyms
] = ngotos
;
268 temp_map
[nsyms
] = ngotos
;
270 from_state
= NEW2(ngotos
, short);
271 to_state
= NEW2(ngotos
, short);
273 for (sp
= first_shift
; sp
; sp
= sp
->next
)
276 for (i
= sp
->nshifts
- 1; i
>= 0; i
--)
278 state2
= sp
->shift
[i
];
279 symbol
= accessing_symbol
[state2
];
281 if (ISTOKEN(symbol
)) break;
283 k
= temp_map
[symbol
]++;
284 from_state
[k
] = state1
;
285 to_state
[k
] = state2
;
289 FREE(temp_map
+ ntokens
);
294 /* Map_goto maps a state/symbol pair into its numeric representation. */
297 map_goto(int state
, int symbol
)
304 low
= goto_map
[symbol
];
305 high
= goto_map
[symbol
+ 1];
310 middle
= (low
+ high
) >> 1;
311 s
= from_state
[middle
];
338 nwords
= ngotos
* tokensetsize
;
339 F
= NEW2(nwords
, unsigned);
341 reads
= NEW2(ngotos
, short *);
342 edge
= NEW2(ngotos
+ 1, short);
346 for (i
= 0; i
< ngotos
; i
++)
348 stateno
= to_state
[i
];
349 sp
= shift_table
[stateno
];
355 for (j
= 0; j
< k
; j
++)
357 symbol
= accessing_symbol
[sp
->shift
[j
]];
360 SETBIT(rowp
, symbol
);
365 symbol
= accessing_symbol
[sp
->shift
[j
]];
366 if (nullable
[symbol
])
367 edge
[nedges
++] = map_goto(stateno
, symbol
);
372 reads
[i
] = rp
= NEW2(nedges
+ 1, short);
374 for (j
= 0; j
< nedges
; j
++)
382 rowp
+= tokensetsize
;
388 for (i
= 0; i
< ngotos
; i
++)
400 build_relations(void)
418 short **new_includes
;
420 includes
= NEW2(ngotos
, short *);
421 edge
= NEW2(ngotos
+ 1, short);
422 states
= NEW2(maxrhs
+ 1, short);
424 for (i
= 0; i
< ngotos
; i
++)
427 state1
= from_state
[i
];
428 symbol1
= accessing_symbol
[to_state
[i
]];
430 for (rulep
= derives
[symbol1
]; *rulep
>= 0; rulep
++)
436 for (rp
= ritem
+ rrhs
[*rulep
]; *rp
>= 0; rp
++)
439 sp
= shift_table
[stateno
];
442 for (j
= 0; j
< k
; j
++)
444 stateno
= sp
->shift
[j
];
445 if (accessing_symbol
[stateno
] == symbol2
) break;
448 states
[length
++] = stateno
;
451 add_lookback_edge(stateno
, *rulep
, i
);
461 stateno
= states
[--length
];
462 edge
[nedges
++] = map_goto(stateno
, *rp
);
463 if (nullable
[*rp
] && length
> 0) isdone
= 0;
470 includes
[i
] = shortp
= NEW2(nedges
+ 1, short);
471 for (j
= 0; j
< nedges
; j
++)
477 new_includes
= transpose(includes
, ngotos
);
479 for (i
= 0; i
< ngotos
; i
++)
485 includes
= new_includes
;
493 add_lookback_edge(int stateno
, int ruleno
, int gotono
)
499 i
= lookaheads
[stateno
];
500 k
= lookaheads
[stateno
+ 1];
502 while (!found
&& i
< k
)
504 if (LAruleno
[i
] == ruleno
)
512 sp
->next
= lookback
[i
];
520 transpose(short **tR
, int n
)
529 nedges
= NEW2(n
, short);
531 for (i
= 0; i
< n
; i
++)
541 new_R
= NEW2(n
, short *);
542 temp_R
= NEW2(n
, short *);
544 for (i
= 0; i
< n
; i
++)
549 sp
= NEW2(k
+ 1, short);
558 for (i
= 0; i
< n
; i
++)
564 *temp_R
[*sp
++]++ = i
;
575 compute_FOLLOWS(void)
582 compute_lookaheads(void)
585 unsigned *fp1
, *fp2
, *fp3
;
590 n
= lookaheads
[nstates
];
591 for (i
= 0; i
< n
; i
++)
593 fp3
= rowp
+ tokensetsize
;
594 for (sp
= lookback
[i
]; sp
; sp
= sp
->next
)
597 fp2
= F
+ tokensetsize
* sp
->value
;
604 for (i
= 0; i
< n
; i
++)
605 for (sp
= lookback
[i
]; sp
; sp
= next
)
617 digraph(short **relation
)
621 infinity
= ngotos
+ 2;
622 INDEX
= NEW2(ngotos
+ 1, short);
623 VERTICES
= NEW2(ngotos
+ 1, short);
628 for (i
= 0; i
< ngotos
; i
++)
631 for (i
= 0; i
< ngotos
; i
++)
633 if (INDEX
[i
] == 0 && R
[i
])
655 INDEX
[i
] = height
= top
;
657 base
= F
+ i
* tokensetsize
;
658 fp3
= base
+ tokensetsize
;
663 while ((j
= *rp
++) >= 0)
668 if (INDEX
[i
] > INDEX
[j
])
672 fp2
= F
+ j
* tokensetsize
;
679 if (INDEX
[i
] == height
)
690 fp2
= F
+ j
* tokensetsize
;