-
Notifications
You must be signed in to change notification settings - Fork 1
/
YaccLr0.pas
133 lines (111 loc) · 3.97 KB
/
YaccLr0.pas
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
{
LR(0) set construction. For an explanation of this algorithm, see
Aho/Sethi/Ullman, "Compilers : Principles, Techniques and Tools,"
1986, Section 4.7.
Copyright (c) 1990-92 Albert Graef <[email protected]>
Copyright (C) 1996 Berend de Boer <[email protected]>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$Revision: 2 $
$Modtime: 96-07-31 14:09 $
$History: YACCLR0.PAS $
*
* ***************** Version 2 *****************
* User: Berend Date: 96-10-10 Time: 21:16
* Updated in $/Lex and Yacc/tply
* Updated for protected mode, windows and Delphi 1.X and 2.X.
}
unit YaccLR0;
interface
procedure LR0Set;
(* constructs the LR(0) state set, shift and goto transitions and
corresponding kernel items *)
implementation
uses YaccBase, YaccTabl;
(* This implementation is based on the algorithm given in Aho/Sethi/Ullman,
1986, Section 4.7. *)
procedure get_syms ( var item_set : ItemSet; var sym_set : IntSet );
(* get the symbols for which there are transitions in item_set *)
var i : Integer;
begin
with item_set do
begin
empty(sym_set);
for i := 1 to n_items do
with item[i], rule_table^[rule_no]^ do
if pos_no<=rhs_len then
include(sym_set, rhs_sym[pos_no]);
end;
end(*get_syms*);
function make_state ( var item_set : ItemSet; sym : Integer ) : Integer;
(* construct a new state for the transitions in item_set on symbol sym;
returns: the new state number *)
var i : Integer;
begin
with item_set do
begin
(* add the new state: *)
new_state;
for i := 1 to n_items do
with item[i], rule_table^[rule_no]^ do
if (pos_no<=rhs_len) and (rhs_sym[pos_no]=sym) then
add_item(rule_no, pos_no+1);
make_state := add_state;
end;
end(*make_state*);
procedure add_next_links;
(* add links to successor items for kernel items in the active state *)
var k, i : Integer;
begin
with state_table^[act_state] do
for k := trans_lo to trans_hi do
with trans_table^[k] do
for i := item_lo to item_hi do
with item_table^[i], rule_table^[rule_no]^ do
if (pos_no<=rhs_len) and (rhs_sym[pos_no]=sym) then
next := find_item(next_state, rule_no, pos_no+1 );
end(*add_next_links*);
procedure LR0Set;
var act_items : ItemSet;
act_syms : IntSet;
i : Integer;
begin
(* initialize state 0: *)
new_state;
add_item(1, 1); (* augmented start production *)
act_state := add_state;
(* build the state table: *)
repeat
(* compute the closure of the current state: *)
get_item_set(act_state, act_items);
closure(act_items);
(* sort items: *)
sort_item_set(act_items);
(* determine symbols used in shift and goto transitions: *)
get_syms(act_items, act_syms);
(* add transitions: *)
start_trans;
for i := 1 to size(act_syms) do
if act_syms[i]=0 then
(* accept action *)
add_trans(0, 0)
else
(* shift/goto action *)
add_trans(act_syms[i], make_state(act_items, act_syms[i]));
end_trans;
(* add next links to kernel items: *)
add_next_links;
(* switch to next state: *)
inc(act_state);
until act_state=n_states;
end(*LR0Set*);
end(*YaccLR0*).