| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Parse::Eyapp::Lalr; |
|
2
|
|
|
|
|
|
|
@ISA=qw( Parse::Eyapp::Grammar ); |
|
3
|
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
require 5.004; |
|
5
|
|
|
|
|
|
|
|
|
6
|
61
|
|
|
61
|
|
21774
|
use Parse::Eyapp::Grammar; |
|
|
61
|
|
|
|
|
208
|
|
|
|
61
|
|
|
|
|
1935
|
|
|
7
|
61
|
|
|
61
|
|
343
|
use Data::Dumper; |
|
|
61
|
|
|
|
|
132
|
|
|
|
61
|
|
|
|
|
3256
|
|
|
8
|
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
# Parse::Eyapp::Compile Object Structure: |
|
10
|
|
|
|
|
|
|
# -------------------------------------- |
|
11
|
|
|
|
|
|
|
# { |
|
12
|
|
|
|
|
|
|
# GRAMMAR => Parse::Eyapp::Grammar, |
|
13
|
|
|
|
|
|
|
# STATES => [ { CORE => [ items... ], |
|
14
|
|
|
|
|
|
|
# ACTIONS => { term => action } |
|
15
|
|
|
|
|
|
|
# GOTOS => { nterm => stateno } |
|
16
|
|
|
|
|
|
|
# }... ] |
|
17
|
|
|
|
|
|
|
# CONFLICTS=>{ SOLVED => { stateno => [ ruleno, token, solved ] }, |
|
18
|
|
|
|
|
|
|
# FORCED => { TOTAL => [ nbsr, nbrr ], |
|
19
|
|
|
|
|
|
|
# DETAIL => { stateno => { TOTAL => [ nbsr, nbrr ] } |
|
20
|
|
|
|
|
|
|
# LIST => [ ruleno, token ] |
|
21
|
|
|
|
|
|
|
# } |
|
22
|
|
|
|
|
|
|
# } |
|
23
|
|
|
|
|
|
|
# } |
|
24
|
|
|
|
|
|
|
# } |
|
25
|
|
|
|
|
|
|
# |
|
26
|
|
|
|
|
|
|
# 'items' are of form: [ ruleno, dotpos ] |
|
27
|
|
|
|
|
|
|
# 'term' in ACTIONS is '' means default action |
|
28
|
|
|
|
|
|
|
# 'action' may be: |
|
29
|
|
|
|
|
|
|
# undef: explicit error (nonassociativity) |
|
30
|
|
|
|
|
|
|
# 0 : accept |
|
31
|
|
|
|
|
|
|
# >0 : shift and go to state 'action' |
|
32
|
|
|
|
|
|
|
# <0 : reduce using rule -'action' |
|
33
|
|
|
|
|
|
|
# 'solved' may have values of: |
|
34
|
|
|
|
|
|
|
# 'shift' if solved as Shift |
|
35
|
|
|
|
|
|
|
# 'reduce' if solved as Reduce |
|
36
|
|
|
|
|
|
|
# 'error' if solved by discarding both Shift and Reduce (nonassoc) |
|
37
|
|
|
|
|
|
|
# |
|
38
|
|
|
|
|
|
|
# SOLVED is a set of states containing Solved conflicts |
|
39
|
|
|
|
|
|
|
# FORCED are forced conflict resolutions |
|
40
|
|
|
|
|
|
|
# |
|
41
|
|
|
|
|
|
|
# nbsr and nbrr are number of shift/reduce and reduce/reduce conflicts |
|
42
|
|
|
|
|
|
|
# |
|
43
|
|
|
|
|
|
|
# TOTAL is the total number of SR/RR conflicts for the parser |
|
44
|
|
|
|
|
|
|
# |
|
45
|
|
|
|
|
|
|
# DETAIL is the detail of conflicts for each state |
|
46
|
|
|
|
|
|
|
# TOTAL is the total number of SR/RR conflicts for a state |
|
47
|
|
|
|
|
|
|
# LIST is the list of discarded reductions (for display purpose only) |
|
48
|
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
|
|
50
|
61
|
|
|
61
|
|
388
|
use strict; |
|
|
61
|
|
|
|
|
135
|
|
|
|
61
|
|
|
|
|
1209
|
|
|
51
|
|
|
|
|
|
|
|
|
52
|
61
|
|
|
61
|
|
284
|
use Carp; |
|
|
61
|
|
|
|
|
124
|
|
|
|
61
|
|
|
|
|
298593
|
|
|
53
|
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
############### |
|
55
|
|
|
|
|
|
|
# Constructor # |
|
56
|
|
|
|
|
|
|
############### |
|
57
|
|
|
|
|
|
|
sub new { |
|
58
|
54
|
|
|
54
|
0
|
182
|
my($class)=shift; |
|
59
|
|
|
|
|
|
|
|
|
60
|
54
|
50
|
|
|
|
205
|
ref($class) |
|
61
|
|
|
|
|
|
|
and $class=ref($class); |
|
62
|
|
|
|
|
|
|
|
|
63
|
54
|
|
|
|
|
533
|
my($self)=$class->SUPER::new(@_); |
|
64
|
54
|
|
|
|
|
651
|
$self->_Compile(); |
|
65
|
54
|
|
|
|
|
614
|
$self->_DynamicConflicts(); # call it only if dynamic conflict handlers |
|
66
|
|
|
|
|
|
|
|
|
67
|
54
|
50
|
|
|
|
396
|
if ($self->Option('prefix')) { |
|
68
|
|
|
|
|
|
|
# weak accept for nested parsing !!!!!!!!!!!! |
|
69
|
|
|
|
|
|
|
# substitute End Of Input by DEFAULT for each state |
|
70
|
0
|
|
|
|
|
0
|
for (@{$self->{STATES}}) { |
|
|
0
|
|
|
|
|
0
|
|
|
71
|
0
|
0
|
|
|
|
0
|
if (exists($_->{ACTIONS}{"\c@"})) { |
|
72
|
|
|
|
|
|
|
# what if DEFAULT action already exists ? |
|
73
|
|
|
|
|
|
|
# Shall I have to use an option in eyapp???? |
|
74
|
0
|
|
|
|
|
0
|
$_->{ACTIONS}{''} = $_->{ACTIONS}{"\c@"}; |
|
75
|
0
|
|
|
|
|
0
|
delete($_->{ACTIONS}{"\c@"}); |
|
76
|
|
|
|
|
|
|
} |
|
77
|
|
|
|
|
|
|
} |
|
78
|
|
|
|
|
|
|
} |
|
79
|
|
|
|
|
|
|
|
|
80
|
54
|
|
|
|
|
418
|
bless($self,$class); |
|
81
|
|
|
|
|
|
|
} |
|
82
|
|
|
|
|
|
|
########### |
|
83
|
|
|
|
|
|
|
# Methods # |
|
84
|
|
|
|
|
|
|
########### |
|
85
|
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
########################### |
|
87
|
|
|
|
|
|
|
# Method To View Warnings # |
|
88
|
|
|
|
|
|
|
########################### |
|
89
|
|
|
|
|
|
|
sub Warnings { |
|
90
|
4
|
|
|
4
|
0
|
51
|
my($self)=shift; |
|
91
|
4
|
|
|
|
|
12
|
my($text) = ''; |
|
92
|
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
# $nbsr = number of shift-reduce conflicts |
|
94
|
|
|
|
|
|
|
# $nbrr = number of reduce-reduce conflicts |
|
95
|
4
|
|
|
|
|
8
|
my($nbsr,$nbrr)=@{$$self{CONFLICTS}{FORCED}{TOTAL}}; |
|
|
4
|
|
|
|
|
20
|
|
|
96
|
|
|
|
|
|
|
|
|
97
|
4
|
|
|
|
|
31
|
$text=$self->SUPER::Warnings(); |
|
98
|
|
|
|
|
|
|
|
|
99
|
4
|
|
|
|
|
12
|
my $expected = $$self{GRAMMAR}{EXPECT}; |
|
100
|
4
|
50
|
|
|
|
23
|
my ($sre, $rre) = ref($expected) ? @$expected : ($expected, 0); |
|
101
|
|
|
|
|
|
|
|
|
102
|
4
|
100
|
66
|
|
|
24
|
$nbsr != $sre and $nbsr > 0 and do { |
|
103
|
1
|
50
|
|
|
|
7
|
$text.="$nbsr shift/reduce conflict".($nbsr > 1 ? "s " : " "); |
|
104
|
|
|
|
|
|
|
}; # end of $nbsr != $sre There were shift-reduce conflicts |
|
105
|
|
|
|
|
|
|
|
|
106
|
4
|
50
|
33
|
|
|
19
|
$nbrr != $rre and $nbrr > 0 and do { |
|
107
|
0
|
0
|
|
|
|
0
|
$nbsr != $sre and $text.="and "; |
|
108
|
0
|
0
|
|
|
|
0
|
$text.="$nbrr reduce/reduce conflict".($nbrr > 1 ? "s" : ""); |
|
109
|
|
|
|
|
|
|
}; |
|
110
|
|
|
|
|
|
|
|
|
111
|
4
|
|
|
|
|
17
|
$text; |
|
112
|
|
|
|
|
|
|
} |
|
113
|
|
|
|
|
|
|
############################# |
|
114
|
|
|
|
|
|
|
# Method To View DFA States # |
|
115
|
|
|
|
|
|
|
############################# |
|
116
|
|
|
|
|
|
|
sub ShowDfa { |
|
117
|
0
|
|
|
0
|
0
|
0
|
my($self)=shift; |
|
118
|
0
|
|
|
|
|
0
|
my($text) = ''; |
|
119
|
0
|
|
|
|
|
0
|
my($grammar,$states)=($$self{GRAMMAR}, $$self{STATES}); |
|
120
|
|
|
|
|
|
|
|
|
121
|
0
|
|
|
|
|
0
|
for my $stateno (0..$#$states) { |
|
122
|
0
|
|
|
|
|
0
|
my(@shifts,@reduces,@errors,$default); |
|
123
|
|
|
|
|
|
|
|
|
124
|
0
|
|
|
|
|
0
|
$text.="State $stateno:\n\n"; |
|
125
|
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
#Dump Kernel Items |
|
127
|
0
|
0
|
|
|
|
0
|
for (sort { $$a[0] <=> $$b[0] |
|
|
0
|
|
|
|
|
0
|
|
|
128
|
0
|
|
|
|
|
0
|
or $$a[1] <=> $$b[1] } @{$$states[$stateno]{'CORE'}}) { |
|
129
|
0
|
|
|
|
|
0
|
my($ruleno,$pos)=@$_; |
|
130
|
0
|
|
|
|
|
0
|
my($lhs,$rhs)=@{$$grammar{RULES}[$ruleno]}[0,1]; |
|
|
0
|
|
|
|
|
0
|
|
|
131
|
0
|
|
|
|
|
0
|
my(@rhscopy)=@$rhs; |
|
132
|
|
|
|
|
|
|
|
|
133
|
0
|
0
|
|
|
|
0
|
$ruleno |
|
134
|
|
|
|
|
|
|
or $rhscopy[-1] = '$end'; |
|
135
|
|
|
|
|
|
|
|
|
136
|
0
|
|
|
|
|
0
|
splice(@rhscopy,$pos,0,'.'); |
|
137
|
0
|
|
|
|
|
0
|
$text.= "\t$lhs -> ".join(' ',@rhscopy)."\t(Rule $ruleno)\n"; |
|
138
|
|
|
|
|
|
|
} |
|
139
|
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
#Prepare Actions |
|
141
|
0
|
|
|
|
|
0
|
for (keys(%{$$states[$stateno]{ACTIONS}})) { |
|
|
0
|
|
|
|
|
0
|
|
|
142
|
0
|
|
|
|
|
0
|
my($term,$action)=($_,$$states[$stateno]{ACTIONS}{$_}); |
|
143
|
|
|
|
|
|
|
|
|
144
|
0
|
0
|
|
|
|
0
|
$term eq chr(0) |
|
145
|
|
|
|
|
|
|
and $term = '$end'; |
|
146
|
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
not defined($action) |
|
148
|
0
|
0
|
|
|
|
0
|
and do { |
|
149
|
0
|
|
|
|
|
0
|
push(@errors,$term); |
|
150
|
0
|
|
|
|
|
0
|
next; |
|
151
|
|
|
|
|
|
|
}; |
|
152
|
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
$action > 0 |
|
154
|
0
|
0
|
|
|
|
0
|
and do { |
|
155
|
0
|
|
|
|
|
0
|
push(@shifts,[ $term, $action ]); |
|
156
|
0
|
|
|
|
|
0
|
next; |
|
157
|
|
|
|
|
|
|
}; |
|
158
|
|
|
|
|
|
|
|
|
159
|
0
|
|
|
|
|
0
|
$action = -$action; |
|
160
|
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
$term |
|
162
|
0
|
0
|
|
|
|
0
|
or do { |
|
163
|
0
|
|
|
|
|
0
|
$default= [ '$default', $action ]; |
|
164
|
0
|
|
|
|
|
0
|
next; |
|
165
|
|
|
|
|
|
|
}; |
|
166
|
|
|
|
|
|
|
|
|
167
|
0
|
|
|
|
|
0
|
push(@reduces,[ $term, $action ]); |
|
168
|
|
|
|
|
|
|
} |
|
169
|
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
#Dump shifts |
|
171
|
|
|
|
|
|
|
@shifts |
|
172
|
0
|
0
|
|
|
|
0
|
and do { |
|
173
|
0
|
|
|
|
|
0
|
$text.="\n"; |
|
174
|
0
|
|
|
|
|
0
|
for (sort { $$a[0] cmp $$b[0] } @shifts) { |
|
|
0
|
|
|
|
|
0
|
|
|
175
|
0
|
|
|
|
|
0
|
my($term,$shift)=@$_; |
|
176
|
|
|
|
|
|
|
|
|
177
|
0
|
|
|
|
|
0
|
$text.="\t$term\tshift, and go to state $shift\n"; |
|
178
|
|
|
|
|
|
|
} |
|
179
|
|
|
|
|
|
|
}; |
|
180
|
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
#Dump errors |
|
182
|
|
|
|
|
|
|
@errors |
|
183
|
0
|
0
|
|
|
|
0
|
and do { |
|
184
|
0
|
|
|
|
|
0
|
$text.="\n"; |
|
185
|
0
|
|
|
|
|
0
|
for my $term (sort { $a cmp $b } @errors) { |
|
|
0
|
|
|
|
|
0
|
|
|
186
|
0
|
|
|
|
|
0
|
$text.="\t$term\terror (nonassociative)\n"; |
|
187
|
|
|
|
|
|
|
} |
|
188
|
|
|
|
|
|
|
}; |
|
189
|
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
#Prepare reduces |
|
191
|
|
|
|
|
|
|
exists($$self{CONFLICTS}{FORCED}{DETAIL}{$stateno}) |
|
192
|
0
|
0
|
|
|
|
0
|
and push(@reduces,@{$$self{CONFLICTS}{FORCED}{DETAIL}{$stateno}{LIST}}); |
|
|
0
|
|
|
|
|
0
|
|
|
193
|
|
|
|
|
|
|
|
|
194
|
0
|
0
|
|
|
|
0
|
@reduces=sort { $$a[0] cmp $$b[0] or $$a[1] <=> $$b[1] } @reduces; |
|
|
0
|
|
|
|
|
0
|
|
|
195
|
|
|
|
|
|
|
|
|
196
|
0
|
0
|
|
|
|
0
|
defined($default) |
|
197
|
|
|
|
|
|
|
and push(@reduces,$default); |
|
198
|
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
#Dump reduces |
|
200
|
|
|
|
|
|
|
@reduces |
|
201
|
0
|
0
|
|
|
|
0
|
and do { |
|
202
|
0
|
|
|
|
|
0
|
$text.="\n"; |
|
203
|
0
|
|
|
|
|
0
|
for (@reduces) { |
|
204
|
0
|
|
|
|
|
0
|
my($term,$ruleno)=@$_; |
|
205
|
0
|
|
|
|
|
0
|
my($discard); |
|
206
|
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
$ruleno < 0 |
|
208
|
0
|
0
|
|
|
|
0
|
and do { |
|
209
|
0
|
|
|
|
|
0
|
++$discard; |
|
210
|
0
|
|
|
|
|
0
|
$ruleno = -$ruleno; |
|
211
|
|
|
|
|
|
|
}; |
|
212
|
|
|
|
|
|
|
|
|
213
|
0
|
0
|
|
|
|
0
|
$term eq chr(0) |
|
214
|
|
|
|
|
|
|
and $term = '$end'; |
|
215
|
|
|
|
|
|
|
|
|
216
|
0
|
0
|
|
|
|
0
|
$text.= "\t$term\t".($discard ? "[" : ""); |
|
217
|
0
|
0
|
|
|
|
0
|
if($ruleno) { |
|
218
|
0
|
|
|
|
|
0
|
$text.= "reduce using rule $ruleno ". |
|
219
|
|
|
|
|
|
|
"($$grammar{RULES}[$ruleno][0])"; |
|
220
|
|
|
|
|
|
|
} |
|
221
|
|
|
|
|
|
|
else { |
|
222
|
0
|
|
|
|
|
0
|
$text.='accept'; |
|
223
|
|
|
|
|
|
|
} |
|
224
|
0
|
0
|
|
|
|
0
|
$text.=($discard ? "]" : "")."\n"; |
|
225
|
|
|
|
|
|
|
} |
|
226
|
|
|
|
|
|
|
}; |
|
227
|
|
|
|
|
|
|
|
|
228
|
|
|
|
|
|
|
#Dump gotos |
|
229
|
|
|
|
|
|
|
exists($$states[$stateno]{GOTOS}) |
|
230
|
0
|
0
|
|
|
|
0
|
and do { |
|
231
|
0
|
|
|
|
|
0
|
$text.= "\n"; |
|
232
|
0
|
|
|
|
|
0
|
for (keys(%{$$states[$stateno]{GOTOS}})) { |
|
|
0
|
|
|
|
|
0
|
|
|
233
|
0
|
|
|
|
|
0
|
$text.= "\t$_\tgo to state $$states[$stateno]{GOTOS}{$_}\n"; |
|
234
|
|
|
|
|
|
|
} |
|
235
|
|
|
|
|
|
|
}; |
|
236
|
|
|
|
|
|
|
|
|
237
|
0
|
|
|
|
|
0
|
$text.="\n"; |
|
238
|
|
|
|
|
|
|
} |
|
239
|
0
|
|
|
|
|
0
|
$text; |
|
240
|
|
|
|
|
|
|
} |
|
241
|
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
#################################################################### |
|
243
|
|
|
|
|
|
|
# Usage : $parser->outputtables($path, $base) |
|
244
|
|
|
|
|
|
|
# Purpose : Gives support to eyapp option -v |
|
245
|
|
|
|
|
|
|
# Parameters : The parser object plus the $path and $base names for the .output |
|
246
|
|
|
|
|
|
|
# file |
|
247
|
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
sub outputtables { |
|
249
|
0
|
|
|
0
|
0
|
0
|
my ($parser, $path, $base) = @_; |
|
250
|
|
|
|
|
|
|
|
|
251
|
0
|
0
|
|
|
|
0
|
my($output)=$base?"$path$base.output":"STDOUT"; |
|
252
|
0
|
|
|
|
|
0
|
my($tmp); |
|
253
|
|
|
|
|
|
|
|
|
254
|
0
|
0
|
|
|
|
0
|
open(my $OUT,">$output") |
|
255
|
|
|
|
|
|
|
or die "Cannot create $base.output for writing.\n"; |
|
256
|
|
|
|
|
|
|
|
|
257
|
0
|
0
|
|
|
|
0
|
$tmp=$parser->Warnings() |
|
258
|
|
|
|
|
|
|
and print $OUT "Warnings:\n---------\n$tmp\n"; |
|
259
|
0
|
0
|
|
|
|
0
|
$tmp=$parser->Conflicts() |
|
260
|
|
|
|
|
|
|
and print $OUT "Conflicts:\n----------\n$tmp\n"; |
|
261
|
0
|
|
|
|
|
0
|
print $OUT "Rules:\n------\n"; |
|
262
|
0
|
|
|
|
|
0
|
print $OUT $parser->ShowRules()."\n"; |
|
263
|
0
|
|
|
|
|
0
|
print $OUT "States:\n-------\n"; |
|
264
|
0
|
|
|
|
|
0
|
print $OUT $parser->ShowDfa()."\n"; |
|
265
|
0
|
|
|
|
|
0
|
print $OUT "Summary:\n--------\n"; |
|
266
|
0
|
|
|
|
|
0
|
print $OUT $parser->Summary(); |
|
267
|
|
|
|
|
|
|
|
|
268
|
0
|
|
|
|
|
0
|
close($OUT); |
|
269
|
|
|
|
|
|
|
} |
|
270
|
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
sub outputDot { |
|
272
|
0
|
|
|
0
|
0
|
0
|
my ($parser, $path, $base, $labelWithCore) = @_; |
|
273
|
|
|
|
|
|
|
|
|
274
|
0
|
0
|
|
|
|
0
|
my ($output)=$base?"$path$base.dot":"STDOUT"; |
|
275
|
|
|
|
|
|
|
|
|
276
|
0
|
0
|
|
|
|
0
|
open(my $OUT,">$output") |
|
277
|
|
|
|
|
|
|
or die "Cannot create $base.dot for writing.\n"; |
|
278
|
|
|
|
|
|
|
|
|
279
|
0
|
|
|
|
|
0
|
my $graph = ''; |
|
280
|
|
|
|
|
|
|
|
|
281
|
0
|
|
|
|
|
0
|
my $dfa = $parser->ShowDfa(); |
|
282
|
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
#warn "$dfa\n"; |
|
284
|
|
|
|
|
|
|
|
|
285
|
0
|
|
|
|
|
0
|
my $grammar = $parser->ShowRules()."\n"; |
|
286
|
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
#warn "$grammar\n"; |
|
288
|
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
# make an array from the grammar |
|
290
|
|
|
|
|
|
|
|
|
291
|
0
|
|
|
|
|
0
|
my %grammar = $grammar =~ m{(\d+):\s+(.*)}gx; |
|
292
|
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
# escape double quotes inside %grammar |
|
294
|
0
|
|
|
|
|
0
|
$graph .= qq{ "g0" [label="0: $grammar{0}", shape = doubleoctagon, fontcolor=blue, color=blue ]\n}; |
|
295
|
0
|
|
|
|
|
0
|
for (1 .. (keys %grammar)-1) { |
|
296
|
0
|
|
|
|
|
0
|
$grammar{$_} =~ s/\\/\\\\/g; # escape escapes |
|
297
|
0
|
|
|
|
|
0
|
$grammar{$_} =~ s/"/\\"/g; # escape double quotes |
|
298
|
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
#warn "$_ => $grammar{$_}\n"; |
|
300
|
|
|
|
|
|
|
|
|
301
|
0
|
|
|
|
|
0
|
$graph .= qq{ "g$_" [label="$_: $grammar{$_}", shape = box, fontcolor=blue, color=blue ]\n}; |
|
302
|
|
|
|
|
|
|
} |
|
303
|
|
|
|
|
|
|
|
|
304
|
0
|
|
|
|
|
0
|
for (0 .. (keys %grammar)-2) { |
|
305
|
0
|
|
|
|
|
0
|
my $n = $_+1; |
|
306
|
0
|
|
|
|
|
0
|
$graph .= qq{ g$_ ->g$n [style=dotted];\n}; |
|
307
|
|
|
|
|
|
|
} |
|
308
|
|
|
|
|
|
|
|
|
309
|
0
|
|
|
|
|
0
|
my $conflicts = $parser->Conflicts(); |
|
310
|
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
#warn $conflicts; |
|
312
|
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
# State 13 contains 5 shift/reduce conflicts |
|
314
|
|
|
|
|
|
|
# State 23 contains 5 shift/reduce conflicts |
|
315
|
0
|
|
|
|
|
0
|
my @conflictstates = $conflicts =~ m{State\s+(\d+)\s+contains\s+\d+\s+(?:shift|reduce)/reduce\s+conflicts?\s*}gx; |
|
316
|
|
|
|
|
|
|
|
|
317
|
|
|
|
|
|
|
#warn "(@conflictstates)\n"; |
|
318
|
|
|
|
|
|
|
|
|
319
|
0
|
|
|
|
|
0
|
$graph .= qq{$_ [shape = diamond, fontcolor=red, color=red]\n} for @conflictstates; |
|
320
|
|
|
|
|
|
|
|
|
321
|
0
|
|
|
|
|
0
|
my %states = ($dfa =~ m{State\s*(\d+)\s*:\n\s* |
|
322
|
|
|
|
|
|
|
( |
|
323
|
|
|
|
|
|
|
(?: |
|
324
|
|
|
|
|
|
|
.*->.* | # a production line |
|
325
|
|
|
|
|
|
|
.*go\s+to.* | # a shift or a goto line |
|
326
|
|
|
|
|
|
|
.*reduce.* | # a reduce line |
|
327
|
|
|
|
|
|
|
.*accept.* | # an accept line |
|
328
|
|
|
|
|
|
|
\s+ | # white lines |
|
329
|
|
|
|
|
|
|
)+ |
|
330
|
|
|
|
|
|
|
) |
|
331
|
|
|
|
|
|
|
}gx); |
|
332
|
|
|
|
|
|
|
|
|
333
|
0
|
|
|
|
|
0
|
for (sort { $a <=> $b } keys %states) { |
|
|
0
|
|
|
|
|
0
|
|
|
334
|
0
|
|
|
|
|
0
|
my $desc = $states{$_}; |
|
335
|
0
|
|
|
|
|
0
|
my @LRitems = $desc =~ m{(\S.*->.*[^\s.])\s+\(Rule\s+\d+\)}g; # remove productions |
|
336
|
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
# label states with core LR-0 items |
|
338
|
0
|
0
|
|
|
|
0
|
if ($labelWithCore) { # this is optional |
|
339
|
0
|
|
|
|
|
0
|
local $" = "\\n"; |
|
340
|
0
|
|
|
|
|
0
|
$graph .= qq{$_ [ label = "$_\\n@LRitems"}; #shape = plaintext, |
|
341
|
0
|
|
|
|
|
0
|
my $s = $_; |
|
342
|
0
|
0
|
|
|
|
0
|
$graph .= qq{, shape = plaintext} unless (grep { $_ eq $s} @conflictstates); |
|
|
0
|
|
|
|
|
0
|
|
|
343
|
0
|
|
|
|
|
0
|
$graph .= "]\n"; |
|
344
|
|
|
|
|
|
|
} |
|
345
|
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
#warn "LRitems in $_:\n@LRitems\n"; |
|
347
|
|
|
|
|
|
|
|
|
348
|
0
|
|
|
|
|
0
|
$desc =~ s/\n\s*\n/\n/g; # remove white lines |
|
349
|
|
|
|
|
|
|
|
|
350
|
|
|
|
|
|
|
# build digraph |
|
351
|
|
|
|
|
|
|
# ID shift, and go to state 4 |
|
352
|
0
|
|
|
|
|
0
|
while ($desc =~ m{\t(.*)\s+shift,\s+and\s+go\s+to\s+state\s+(\d+)}gx) { |
|
353
|
0
|
|
|
|
|
0
|
my ($label, $state) = ($1, $2); |
|
354
|
0
|
|
|
|
|
0
|
$label =~ s/\\(?!")/\\\\/g; |
|
355
|
0
|
|
|
|
|
0
|
$graph .= qq{$_ -> $state [label = "$label"]\n}; |
|
356
|
|
|
|
|
|
|
} |
|
357
|
|
|
|
|
|
|
|
|
358
|
|
|
|
|
|
|
# decl go to state 1 |
|
359
|
0
|
|
|
|
|
0
|
while ($desc =~ m{\t(\S+)\s+go\s+to\s+state\s+(\d+)}gx) { |
|
360
|
0
|
|
|
|
|
0
|
$graph .= qq{$_ -> $2 [label = "$1", arrowhead = odot, color = "red", fontcolor = "red"]\n}; |
|
361
|
|
|
|
|
|
|
} |
|
362
|
|
|
|
|
|
|
|
|
363
|
|
|
|
|
|
|
# $default reduce using rule 1 (prog) |
|
364
|
|
|
|
|
|
|
# ID reduce using rule 15 (decORexp_explorer) |
|
365
|
0
|
|
|
|
|
0
|
while ($desc =~ m{\t(\S+)\s+reduce\s+using\s+rule\s+(\d+)}gx) { |
|
366
|
0
|
|
|
|
|
0
|
$graph .= qq{$_ -> "g$2" [label = "$1", arrowhead=dot, color = "blue", fontcolor = "blue"]\n}; |
|
367
|
|
|
|
|
|
|
} |
|
368
|
|
|
|
|
|
|
|
|
369
|
|
|
|
|
|
|
# shift-reduce conflicts |
|
370
|
|
|
|
|
|
|
# ';' [reduce using rule 4 (ds)] |
|
371
|
0
|
|
|
|
|
0
|
while ($desc =~ m{\t(\S+)\s+\[\s*reduce\s+using\s+rule\s+(\d+)}gx) { |
|
372
|
0
|
|
|
|
|
0
|
$graph .= |
|
373
|
|
|
|
|
|
|
qq{$_ -> "g$2" [label = "$1", arrowhead=dot, style=dotted, color = "red", fontcolor = "red"]\n}; |
|
374
|
|
|
|
|
|
|
} |
|
375
|
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
# $default accept |
|
377
|
0
|
0
|
|
|
|
0
|
if ($desc =~ m{\t\$default\s+accept\s*}gx) { |
|
378
|
0
|
|
|
|
|
0
|
$graph .= qq{$_ [shape = doublecircle]\n}; |
|
379
|
0
|
|
|
|
|
0
|
$graph .= qq{$_ -> "g0" [arrowhead = dot, color = blue]\n}; |
|
380
|
|
|
|
|
|
|
} |
|
381
|
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
#warn "$_ => $desc\n"; |
|
383
|
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
} |
|
385
|
0
|
|
|
|
|
0
|
print $OUT <<"EOGRAPH"; |
|
386
|
|
|
|
|
|
|
digraph G { |
|
387
|
|
|
|
|
|
|
#concentrate = true |
|
388
|
|
|
|
|
|
|
|
|
389
|
|
|
|
|
|
|
$graph |
|
390
|
|
|
|
|
|
|
} |
|
391
|
|
|
|
|
|
|
EOGRAPH |
|
392
|
0
|
|
|
|
|
0
|
close $OUT; |
|
393
|
|
|
|
|
|
|
} |
|
394
|
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
sub qtables { |
|
396
|
0
|
|
|
0
|
0
|
0
|
my ($parser) = @_; |
|
397
|
|
|
|
|
|
|
|
|
398
|
0
|
|
|
|
|
0
|
my($tmp); |
|
399
|
|
|
|
|
|
|
|
|
400
|
0
|
|
|
|
|
0
|
my $warnings = $parser->Warnings(); |
|
401
|
0
|
|
|
|
|
0
|
my $conflicts = $parser->Conflicts(); |
|
402
|
0
|
|
|
|
|
0
|
my $rules = $parser->ShowRules(); |
|
403
|
0
|
|
|
|
|
0
|
my $states = $parser->ShowDfa(); |
|
404
|
0
|
|
|
|
|
0
|
my $summary = $parser->Summary(); |
|
405
|
|
|
|
|
|
|
|
|
406
|
0
|
|
|
|
|
0
|
my $tables =<<"ENDOFLALAR" |
|
407
|
|
|
|
|
|
|
Warnings: |
|
408
|
|
|
|
|
|
|
--------- |
|
409
|
|
|
|
|
|
|
$warnings |
|
410
|
|
|
|
|
|
|
Conflicts: |
|
411
|
|
|
|
|
|
|
---------- |
|
412
|
|
|
|
|
|
|
$conflicts |
|
413
|
|
|
|
|
|
|
Rules: |
|
414
|
|
|
|
|
|
|
------ |
|
415
|
|
|
|
|
|
|
$rules |
|
416
|
|
|
|
|
|
|
States: |
|
417
|
|
|
|
|
|
|
------ |
|
418
|
|
|
|
|
|
|
$states |
|
419
|
|
|
|
|
|
|
$states |
|
420
|
|
|
|
|
|
|
Summary: |
|
421
|
|
|
|
|
|
|
-------- |
|
422
|
|
|
|
|
|
|
$summary |
|
423
|
|
|
|
|
|
|
ENDOFLALAR |
|
424
|
|
|
|
|
|
|
} |
|
425
|
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
###################################### |
|
427
|
|
|
|
|
|
|
# Method to get summary about parser # |
|
428
|
|
|
|
|
|
|
###################################### |
|
429
|
|
|
|
|
|
|
sub Summary { |
|
430
|
0
|
|
|
0
|
0
|
0
|
my($self)=shift; |
|
431
|
0
|
|
|
|
|
0
|
my($text) = ''; |
|
432
|
|
|
|
|
|
|
|
|
433
|
0
|
|
|
|
|
0
|
$text=$self->SUPER::Summary(); |
|
434
|
|
|
|
|
|
|
$text.="Number of states : ". |
|
435
|
0
|
|
|
|
|
0
|
scalar(@{$$self{STATES}})."\n"; |
|
|
0
|
|
|
|
|
0
|
|
|
436
|
0
|
|
|
|
|
0
|
$text; |
|
437
|
|
|
|
|
|
|
} |
|
438
|
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
####################################### |
|
440
|
|
|
|
|
|
|
# Method To Get Infos about conflicts # |
|
441
|
|
|
|
|
|
|
####################################### |
|
442
|
|
|
|
|
|
|
sub Conflicts { |
|
443
|
0
|
|
|
0
|
0
|
0
|
my($self)=shift; |
|
444
|
0
|
|
|
|
|
0
|
my($states)=$$self{STATES}; |
|
445
|
0
|
|
|
|
|
0
|
my($conflicts)=$$self{CONFLICTS}; |
|
446
|
0
|
|
|
|
|
0
|
my($text) = ''; |
|
447
|
|
|
|
|
|
|
|
|
448
|
0
|
|
|
|
|
0
|
for my $stateno ( sort { $a <=> $b } keys(%{$$conflicts{SOLVED}})) { |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
449
|
|
|
|
|
|
|
|
|
450
|
0
|
|
|
|
|
0
|
for (@{$$conflicts{SOLVED}{$stateno}}) { |
|
|
0
|
|
|
|
|
0
|
|
|
451
|
0
|
|
|
|
|
0
|
my($ruleno,$token,$how)=@$_; |
|
452
|
|
|
|
|
|
|
|
|
453
|
0
|
0
|
|
|
|
0
|
$token eq chr(0) |
|
454
|
|
|
|
|
|
|
and $token = '$end'; |
|
455
|
|
|
|
|
|
|
|
|
456
|
0
|
|
|
|
|
0
|
$text.="Conflict in state $stateno between rule ". |
|
457
|
|
|
|
|
|
|
"$ruleno and token $token resolved as $how.\n"; |
|
458
|
|
|
|
|
|
|
} |
|
459
|
|
|
|
|
|
|
}; |
|
460
|
|
|
|
|
|
|
|
|
461
|
0
|
|
|
|
|
0
|
for my $stateno ( sort { $a <=> $b } keys(%{$$conflicts{FORCED}{DETAIL}})) { |
|
|
0
|
|
|
|
|
0
|
|
|
|
0
|
|
|
|
|
0
|
|
|
462
|
0
|
|
|
|
|
0
|
my($nbsr,$nbrr)=@{$$conflicts{FORCED}{DETAIL}{$stateno}{TOTAL}}; |
|
|
0
|
|
|
|
|
0
|
|
|
463
|
|
|
|
|
|
|
|
|
464
|
0
|
|
|
|
|
0
|
$text.="State $stateno contains "; |
|
465
|
|
|
|
|
|
|
|
|
466
|
0
|
0
|
|
|
|
0
|
$nbsr |
|
|
|
0
|
|
|
|
|
|
|
467
|
|
|
|
|
|
|
and $text.="$nbsr shift/reduce conflict". |
|
468
|
|
|
|
|
|
|
($nbsr > 1 ? "s" : ""); |
|
469
|
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
$nbrr |
|
471
|
0
|
0
|
|
|
|
0
|
and do { |
|
472
|
0
|
0
|
|
|
|
0
|
$nbsr |
|
473
|
|
|
|
|
|
|
and $text.=" and "; |
|
474
|
|
|
|
|
|
|
|
|
475
|
0
|
0
|
|
|
|
0
|
$text.="$nbrr reduce/reduce conflict". |
|
476
|
|
|
|
|
|
|
($nbrr > 1 ? "s" : ""); |
|
477
|
|
|
|
|
|
|
}; |
|
478
|
0
|
|
|
|
|
0
|
$text.="\n"; |
|
479
|
|
|
|
|
|
|
}; |
|
480
|
|
|
|
|
|
|
|
|
481
|
0
|
|
|
|
|
0
|
$text; |
|
482
|
|
|
|
|
|
|
} |
|
483
|
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
################################# |
|
485
|
|
|
|
|
|
|
# Method to dump parsing tables # |
|
486
|
|
|
|
|
|
|
################################# |
|
487
|
|
|
|
|
|
|
sub DfaTable { |
|
488
|
54
|
|
|
54
|
0
|
183
|
my($self)=shift; |
|
489
|
54
|
|
|
|
|
159
|
my($states)=$$self{STATES}; |
|
490
|
54
|
|
|
|
|
208
|
my($stateno); |
|
491
|
|
|
|
|
|
|
my($text); |
|
492
|
|
|
|
|
|
|
|
|
493
|
54
|
|
|
|
|
156
|
$text="[\n\t{"; |
|
494
|
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
$text.=join("\n\t},\n\t{", |
|
496
|
|
|
|
|
|
|
map { |
|
497
|
54
|
|
|
|
|
181
|
my($state)=$_; |
|
|
1289
|
|
|
|
|
1965
|
|
|
498
|
1289
|
|
|
|
|
1718
|
my($text); |
|
499
|
|
|
|
|
|
|
|
|
500
|
1289
|
|
|
|
|
2344
|
$text="#State ".$stateno++."\n\t\t"; |
|
501
|
|
|
|
|
|
|
|
|
502
|
|
|
|
|
|
|
( not exists($$state{ACTIONS}{''}) |
|
503
|
694
|
|
|
|
|
2360
|
or keys(%{$$state{ACTIONS}}) > 1) |
|
504
|
1289
|
100
|
100
|
|
|
3547
|
and do { |
|
505
|
|
|
|
|
|
|
|
|
506
|
877
|
|
|
|
|
1503
|
$text.="ACTIONS => {\n\t\t\t"; |
|
507
|
|
|
|
|
|
|
|
|
508
|
|
|
|
|
|
|
$text.=join(",\n\t\t\t", |
|
509
|
|
|
|
|
|
|
map { |
|
510
|
3101
|
|
|
|
|
5991
|
my($term,$action)=($_,$$state{ACTIONS}{$_}); |
|
511
|
3101
|
|
|
|
|
4117
|
my($text); |
|
512
|
|
|
|
|
|
|
|
|
513
|
3101
|
100
|
|
|
|
5964
|
if(substr($term,0,1) eq "'") { |
|
514
|
2247
|
|
|
|
|
4036
|
$term=~s/([\@\$\"])/\\$1/g; |
|
515
|
2247
|
|
|
|
|
6444
|
$term=~s/^'|'$/"/g; |
|
516
|
|
|
|
|
|
|
} |
|
517
|
|
|
|
|
|
|
else { |
|
518
|
854
|
100
|
|
|
|
1929
|
$term= $term eq chr(0) |
|
519
|
|
|
|
|
|
|
? "''" |
|
520
|
|
|
|
|
|
|
: "'$term'"; |
|
521
|
|
|
|
|
|
|
} |
|
522
|
|
|
|
|
|
|
|
|
523
|
3101
|
50
|
|
|
|
6174
|
if(defined($action)) { |
|
524
|
3101
|
|
|
|
|
4246
|
$action=int($action); |
|
525
|
|
|
|
|
|
|
} |
|
526
|
|
|
|
|
|
|
else { |
|
527
|
0
|
|
|
|
|
0
|
$action='undef'; |
|
528
|
|
|
|
|
|
|
} |
|
529
|
|
|
|
|
|
|
|
|
530
|
3101
|
|
|
|
|
7361
|
"$term => $action"; |
|
531
|
|
|
|
|
|
|
|
|
532
|
877
|
|
|
|
|
1319
|
} grep { $_ } keys(%{$$state{ACTIONS}})); |
|
|
3383
|
|
|
|
|
5513
|
|
|
|
877
|
|
|
|
|
2032
|
|
|
533
|
|
|
|
|
|
|
|
|
534
|
877
|
|
|
|
|
1748
|
$text.="\n\t\t}"; |
|
535
|
|
|
|
|
|
|
}; |
|
536
|
|
|
|
|
|
|
|
|
537
|
|
|
|
|
|
|
exists($$state{ACTIONS}{''}) |
|
538
|
1289
|
100
|
|
|
|
2997
|
and do { |
|
539
|
694
|
100
|
|
|
|
958
|
keys(%{$$state{ACTIONS}}) > 1 |
|
|
694
|
|
|
|
|
1727
|
|
|
540
|
|
|
|
|
|
|
and $text.=",\n\t\t"; |
|
541
|
|
|
|
|
|
|
|
|
542
|
694
|
|
|
|
|
1440
|
$text.="DEFAULT => $$state{ACTIONS}{''}"; |
|
543
|
|
|
|
|
|
|
}; |
|
544
|
|
|
|
|
|
|
|
|
545
|
|
|
|
|
|
|
exists($$state{GOTOS}) |
|
546
|
1289
|
100
|
|
|
|
2734
|
and do { |
|
547
|
481
|
|
|
|
|
831
|
$text.=",\n\t\tGOTOS => {\n\t\t\t"; |
|
548
|
|
|
|
|
|
|
$text.=join(",\n\t\t\t", |
|
549
|
|
|
|
|
|
|
map { |
|
550
|
909
|
|
|
|
|
1776
|
my($nterm,$stateno)=($_,$$state{GOTOS}{$_}); |
|
551
|
909
|
|
|
|
|
1252
|
my($text); |
|
552
|
|
|
|
|
|
|
|
|
553
|
909
|
|
|
|
|
2177
|
"'$nterm' => $stateno"; |
|
554
|
|
|
|
|
|
|
|
|
555
|
481
|
|
|
|
|
701
|
} keys(%{$$state{GOTOS}})); |
|
|
481
|
|
|
|
|
1085
|
|
|
556
|
481
|
|
|
|
|
965
|
$text.="\n\t\t}"; |
|
557
|
|
|
|
|
|
|
}; |
|
558
|
|
|
|
|
|
|
|
|
559
|
1289
|
|
|
|
|
2903
|
$text; |
|
560
|
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
}@$states); |
|
562
|
|
|
|
|
|
|
|
|
563
|
54
|
|
|
|
|
296
|
$text.="\n\t}\n]"; |
|
564
|
|
|
|
|
|
|
|
|
565
|
54
|
|
|
|
|
318
|
$text; |
|
566
|
|
|
|
|
|
|
|
|
567
|
|
|
|
|
|
|
} |
|
568
|
|
|
|
|
|
|
|
|
569
|
|
|
|
|
|
|
sub _DynamicConflicts { |
|
570
|
54
|
|
|
54
|
|
147
|
my $self = shift; |
|
571
|
54
|
|
|
|
|
170
|
my $ch = $self->{GRAMMAR}{CONFLICTHANDLERS}; |
|
572
|
|
|
|
|
|
|
|
|
573
|
54
|
50
|
|
|
|
233
|
return unless %$ch; |
|
574
|
|
|
|
|
|
|
|
|
575
|
0
|
|
|
|
|
0
|
my $co = $self->{CONFLICTS}{FORCED}{DETAIL}; |
|
576
|
|
|
|
|
|
|
|
|
577
|
0
|
|
|
|
|
0
|
my %C; # keys: |
|
578
|
|
|
|
|
|
|
# conflictive grammar productions. |
|
579
|
|
|
|
|
|
|
# Values: |
|
580
|
|
|
|
|
|
|
# tokens for which there is a conflict with this production |
|
581
|
0
|
|
|
|
|
0
|
for my $state (keys %$co) { |
|
582
|
0
|
|
|
|
|
0
|
my @conList = @{$co->{$state}{LIST}}; |
|
|
0
|
|
|
|
|
0
|
|
|
583
|
|
|
|
|
|
|
|
|
584
|
0
|
|
|
|
|
0
|
for my $c (@conList) { |
|
585
|
0
|
|
|
|
|
0
|
my ($token, $production) = @$c; |
|
586
|
|
|
|
|
|
|
|
|
587
|
|
|
|
|
|
|
# the action chosen is in: $self->{STATES}[$state]{ACTIONS}{$token} |
|
588
|
0
|
|
|
|
|
0
|
push @{$C{($production)}{$state}}, $token; |
|
|
0
|
|
|
|
|
0
|
|
|
589
|
|
|
|
|
|
|
} |
|
590
|
|
|
|
|
|
|
} |
|
591
|
|
|
|
|
|
|
|
|
592
|
0
|
|
|
|
|
0
|
for my $c (keys %$ch) { # for each conflict handler |
|
593
|
0
|
|
|
|
|
0
|
my $d = $ch->{$c}{production}; # hash ref of productions managed by this handler |
|
594
|
0
|
|
|
|
|
0
|
for my $p (keys %$d) { # for each production |
|
595
|
|
|
|
|
|
|
# # if $p reduce or shift? |
|
596
|
|
|
|
|
|
|
# # find the conflictive states where $p appears |
|
597
|
|
|
|
|
|
|
# # if $p is reduce and appears in state $s as -$p it is a state of conflict (the other is in the action table) |
|
598
|
|
|
|
|
|
|
|
|
599
|
0
|
0
|
|
|
|
0
|
if ($C{$p}) { |
|
600
|
0
|
|
|
|
|
0
|
push @{$ch->{$c}{states}}, $C{$p} |
|
|
0
|
|
|
|
|
0
|
|
|
601
|
|
|
|
|
|
|
} |
|
602
|
|
|
|
|
|
|
else { |
|
603
|
|
|
|
|
|
|
# check that it is a shift with this production. |
|
604
|
|
|
|
|
|
|
} |
|
605
|
|
|
|
|
|
|
} |
|
606
|
|
|
|
|
|
|
} |
|
607
|
|
|
|
|
|
|
} |
|
608
|
|
|
|
|
|
|
|
|
609
|
|
|
|
|
|
|
#################################### |
|
610
|
|
|
|
|
|
|
# Method to build Dfa from Grammar # |
|
611
|
|
|
|
|
|
|
#################################### |
|
612
|
|
|
|
|
|
|
sub _Compile { |
|
613
|
54
|
|
|
54
|
|
152
|
my($self)=shift; |
|
614
|
54
|
|
|
|
|
134
|
my($grammar,$states); |
|
615
|
|
|
|
|
|
|
|
|
616
|
54
|
|
|
|
|
146
|
$grammar=$self->{GRAMMAR}; |
|
617
|
|
|
|
|
|
|
|
|
618
|
54
|
|
|
|
|
272
|
$states = _LR0($grammar); |
|
619
|
|
|
|
|
|
|
|
|
620
|
54
|
|
|
|
|
333
|
$self->{CONFLICTS} = _LALR($grammar,$states); |
|
621
|
|
|
|
|
|
|
|
|
622
|
54
|
|
|
|
|
176
|
$self->{STATES}=$states; |
|
623
|
|
|
|
|
|
|
} |
|
624
|
|
|
|
|
|
|
|
|
625
|
|
|
|
|
|
|
######################### |
|
626
|
|
|
|
|
|
|
# LR0 States Generation # |
|
627
|
|
|
|
|
|
|
######################### |
|
628
|
|
|
|
|
|
|
# |
|
629
|
|
|
|
|
|
|
########################### |
|
630
|
|
|
|
|
|
|
# General digraph routine # |
|
631
|
|
|
|
|
|
|
########################### |
|
632
|
|
|
|
|
|
|
sub _Digraph { |
|
633
|
162
|
|
|
162
|
|
1240
|
my($rel,$F)=@_; |
|
634
|
162
|
|
|
|
|
322
|
my(%N,@S); |
|
635
|
162
|
|
|
|
|
309
|
my($infinity)=(~(1<<31)); |
|
636
|
162
|
|
|
|
|
279
|
my($Traverse); |
|
637
|
|
|
|
|
|
|
|
|
638
|
|
|
|
|
|
|
$Traverse = sub { |
|
639
|
1747
|
|
|
1747
|
|
3081
|
my($x,$d)=@_; |
|
640
|
1747
|
|
|
|
|
2356
|
my($y); |
|
641
|
|
|
|
|
|
|
|
|
642
|
1747
|
|
|
|
|
2692
|
push(@S,$x); |
|
643
|
1747
|
|
|
|
|
2888
|
$N{$x}=$d; |
|
644
|
|
|
|
|
|
|
|
|
645
|
|
|
|
|
|
|
exists($$rel{$x}) |
|
646
|
1747
|
100
|
|
|
|
3951
|
and do { |
|
647
|
1487
|
|
|
|
|
2116
|
for $y (keys(%{$$rel{$x}})) { |
|
|
1487
|
|
|
|
|
4465
|
|
|
648
|
7959
|
100
|
|
|
|
16987
|
exists($N{$y}) |
|
649
|
|
|
|
|
|
|
or &$Traverse($y,$d+1); |
|
650
|
|
|
|
|
|
|
|
|
651
|
|
|
|
|
|
|
$N{$y} < $N{$x} |
|
652
|
7959
|
100
|
|
|
|
16241
|
and $N{$x} = $N{$y}; |
|
653
|
|
|
|
|
|
|
|
|
654
|
7959
|
|
|
|
|
13182
|
$$F{$x}|=$$F{$y}; |
|
655
|
|
|
|
|
|
|
} |
|
656
|
|
|
|
|
|
|
}; |
|
657
|
|
|
|
|
|
|
|
|
658
|
|
|
|
|
|
|
$N{$x} == $d |
|
659
|
1747
|
100
|
|
|
|
4202
|
and do { |
|
660
|
1538
|
|
|
|
|
2144
|
for(;;) { |
|
661
|
1747
|
|
|
|
|
2701
|
$y=pop(@S); |
|
662
|
1747
|
|
|
|
|
3240
|
$N{$y}=$infinity; |
|
663
|
1747
|
100
|
|
|
|
4744
|
$y eq $x |
|
664
|
|
|
|
|
|
|
and last; |
|
665
|
209
|
|
|
|
|
388
|
$$F{$y}=$$F{$x}; |
|
666
|
|
|
|
|
|
|
} |
|
667
|
|
|
|
|
|
|
}; |
|
668
|
162
|
|
|
|
|
984
|
}; |
|
669
|
|
|
|
|
|
|
|
|
670
|
162
|
|
|
|
|
750
|
for (keys(%$rel)) { |
|
671
|
1487
|
100
|
|
|
|
3895
|
exists($N{$_}) |
|
672
|
|
|
|
|
|
|
or &$Traverse($_,1); |
|
673
|
|
|
|
|
|
|
} |
|
674
|
|
|
|
|
|
|
} |
|
675
|
|
|
|
|
|
|
####################### |
|
676
|
|
|
|
|
|
|
# Generate LR0 states # |
|
677
|
|
|
|
|
|
|
####################### |
|
678
|
|
|
|
|
|
|
# Formula used for closures: |
|
679
|
|
|
|
|
|
|
# |
|
680
|
|
|
|
|
|
|
# CLOSE(A) = DCLOSE(A) u U (CLOSE(B) | A close B) |
|
681
|
|
|
|
|
|
|
# |
|
682
|
|
|
|
|
|
|
# where: |
|
683
|
|
|
|
|
|
|
# |
|
684
|
|
|
|
|
|
|
# DCLOSE(A) = { [ A -> alpha ] in P } |
|
685
|
|
|
|
|
|
|
# |
|
686
|
|
|
|
|
|
|
# A close B iff [ A -> B gamma ] in P |
|
687
|
|
|
|
|
|
|
|
|
688
|
|
|
|
|
|
|
sub _SetClosures { |
|
689
|
54
|
|
|
54
|
|
136
|
my($grammar)=@_; |
|
690
|
54
|
|
|
|
|
130
|
my($rel,$closures); |
|
691
|
|
|
|
|
|
|
|
|
692
|
54
|
|
|
|
|
141
|
for my $symbol (keys(%{$$grammar{NTERM}})) { |
|
|
54
|
|
|
|
|
345
|
|
|
693
|
277
|
|
|
|
|
462
|
$closures->{$symbol}=pack('b'.@{$$grammar{RULES}}); |
|
|
277
|
|
|
|
|
1016
|
|
|
694
|
|
|
|
|
|
|
|
|
695
|
277
|
|
|
|
|
484
|
for my $ruleno (@{$$grammar{NTERM}{$symbol}}) { |
|
|
277
|
|
|
|
|
643
|
|
|
696
|
691
|
|
|
|
|
1184
|
my($rhs)=$$grammar{RULES}[$ruleno][1]; |
|
697
|
|
|
|
|
|
|
|
|
698
|
691
|
|
|
|
|
1409
|
vec($closures->{$symbol},$ruleno,1)=1; |
|
699
|
|
|
|
|
|
|
|
|
700
|
|
|
|
|
|
|
@$rhs > 0 |
|
701
|
|
|
|
|
|
|
and exists($$grammar{NTERM}{$$rhs[0]}) |
|
702
|
691
|
100
|
100
|
|
|
3433
|
and ++$rel->{$symbol}{$$rhs[0]}; |
|
703
|
|
|
|
|
|
|
} |
|
704
|
|
|
|
|
|
|
} |
|
705
|
54
|
|
|
|
|
690
|
_Digraph($rel,$closures); |
|
706
|
|
|
|
|
|
|
|
|
707
|
54
|
|
|
|
|
136
|
$closures |
|
708
|
|
|
|
|
|
|
} |
|
709
|
|
|
|
|
|
|
|
|
710
|
|
|
|
|
|
|
sub _Closures { |
|
711
|
1289
|
|
|
1289
|
|
2127
|
my($grammar,$core,$closures)=@_; |
|
712
|
1289
|
|
|
|
|
1864
|
my($ruleset)=pack('b'.@{$$grammar{RULES}}); |
|
|
1289
|
|
|
|
|
3515
|
|
|
713
|
|
|
|
|
|
|
|
|
714
|
1289
|
|
|
|
|
2467
|
for (@$core) { |
|
715
|
3265
|
|
|
|
|
5951
|
my($ruleno,$pos)=@$_; |
|
716
|
3265
|
|
|
|
|
5208
|
my($rhs)=$$grammar{RULES}[$ruleno][1]; |
|
717
|
|
|
|
|
|
|
|
|
718
|
|
|
|
|
|
|
$pos < @$rhs |
|
719
|
|
|
|
|
|
|
and exists($closures->{$$rhs[$pos]}) |
|
720
|
3265
|
100
|
100
|
|
|
13020
|
and $ruleset|=$closures->{$$rhs[$pos]}; |
|
721
|
|
|
|
|
|
|
} |
|
722
|
5201
|
|
|
|
|
10133
|
[ @$core, map { [ $_, 0 ] } |
|
723
|
34895
|
|
|
|
|
50720
|
grep { vec($ruleset,$_,1) } |
|
724
|
1289
|
|
|
|
|
2174
|
0..$#{$$grammar{RULES}} ]; |
|
|
1289
|
|
|
|
|
2944
|
|
|
725
|
|
|
|
|
|
|
} |
|
726
|
|
|
|
|
|
|
|
|
727
|
|
|
|
|
|
|
sub _Transitions { |
|
728
|
1289
|
|
|
1289
|
|
2355
|
my($grammar,$cores,$closures,$states,$stateno)=@_; |
|
729
|
1289
|
|
|
|
|
2331
|
my($core)=$$states[$stateno]{'CORE'}; |
|
730
|
1289
|
|
|
|
|
1839
|
my(%transitions); |
|
731
|
|
|
|
|
|
|
|
|
732
|
1289
|
|
|
|
|
1820
|
for (@{_Closures($grammar,$core,$closures)}) { |
|
|
1289
|
|
|
|
|
2355
|
|
|
733
|
8466
|
|
|
|
|
15194
|
my($ruleno,$pos)=@$_; |
|
734
|
8466
|
|
|
|
|
13432
|
my($rhs)=$$grammar{RULES}[$ruleno][1]; |
|
735
|
|
|
|
|
|
|
|
|
736
|
|
|
|
|
|
|
$pos == @$rhs |
|
737
|
8466
|
100
|
|
|
|
17235
|
and do { |
|
738
|
717
|
|
|
|
|
1087
|
push(@{$$states[$stateno]{ACTIONS}{''}},$ruleno); |
|
|
717
|
|
|
|
|
2068
|
|
|
739
|
717
|
|
|
|
|
1472
|
next; |
|
740
|
|
|
|
|
|
|
}; |
|
741
|
7749
|
|
|
|
|
10717
|
push(@{$transitions{$$rhs[$pos]}},[ $ruleno, $pos+1 ]); |
|
|
7749
|
|
|
|
|
20738
|
|
|
742
|
|
|
|
|
|
|
} |
|
743
|
|
|
|
|
|
|
|
|
744
|
1289
|
|
|
|
|
4416
|
for (keys(%transitions)) { |
|
745
|
4777
|
|
|
|
|
8645
|
my($symbol,$core)=($_,$transitions{$_}); |
|
746
|
7749
|
|
|
|
|
20094
|
my($corekey)=join(',',map { join('.',@$_) } |
|
747
|
4777
|
50
|
|
|
|
10120
|
sort { $$a[0] <=> $$b[0] |
|
|
5988
|
|
|
|
|
13158
|
|
|
748
|
|
|
|
|
|
|
or $$a[1] <=> $$b[1] } |
|
749
|
|
|
|
|
|
|
@$core); |
|
750
|
4777
|
|
|
|
|
7826
|
my($tostateno); |
|
751
|
|
|
|
|
|
|
|
|
752
|
|
|
|
|
|
|
exists($cores->{$corekey}) |
|
753
|
4777
|
100
|
|
|
|
10583
|
or do { |
|
754
|
1235
|
|
|
|
|
2933
|
push(@$states,{ 'CORE' => $core }); |
|
755
|
1235
|
|
|
|
|
2992
|
$cores->{$corekey}=$#$states; |
|
756
|
|
|
|
|
|
|
}; |
|
757
|
|
|
|
|
|
|
|
|
758
|
4777
|
|
|
|
|
7171
|
$tostateno=$cores->{$corekey}; |
|
759
|
4777
|
|
|
|
|
6518
|
push(@{$$states[$tostateno]{FROM}},$stateno); |
|
|
4777
|
|
|
|
|
9391
|
|
|
760
|
|
|
|
|
|
|
|
|
761
|
|
|
|
|
|
|
exists($$grammar{TERM}{$_}) |
|
762
|
4777
|
100
|
|
|
|
10696
|
and do { |
|
763
|
3868
|
|
|
|
|
7973
|
$$states[$stateno]{ACTIONS}{$_} = [ $tostateno ]; |
|
764
|
3868
|
|
|
|
|
9505
|
next; |
|
765
|
|
|
|
|
|
|
}; |
|
766
|
909
|
|
|
|
|
2925
|
$$states[$stateno]{GOTOS}{$_} = $tostateno; |
|
767
|
|
|
|
|
|
|
} |
|
768
|
|
|
|
|
|
|
} |
|
769
|
|
|
|
|
|
|
|
|
770
|
|
|
|
|
|
|
sub _LR0 { |
|
771
|
54
|
|
|
54
|
|
157
|
my($grammar)=@_; |
|
772
|
54
|
|
|
|
|
153
|
my($states) = []; |
|
773
|
54
|
|
|
|
|
136
|
my($stateno); |
|
774
|
|
|
|
|
|
|
my($closures); #$closures={ nterm => ruleset,... } |
|
775
|
54
|
|
|
|
|
145
|
my($cores)={}; # { "itemlist" => stateno, ... } |
|
776
|
|
|
|
|
|
|
# where "itemlist" has the form: |
|
777
|
|
|
|
|
|
|
# "ruleno.pos,ruleno.pos" ordered by ruleno,pos |
|
778
|
|
|
|
|
|
|
|
|
779
|
54
|
|
|
|
|
225
|
$closures = _SetClosures($grammar); |
|
780
|
54
|
|
|
|
|
257
|
push(@$states,{ 'CORE' => [ [ 0, 0 ] ] }); |
|
781
|
54
|
|
|
|
|
252
|
for($stateno=0;$stateno<@$states;++$stateno) { |
|
782
|
1289
|
|
|
|
|
2880
|
_Transitions($grammar,$cores,$closures,$states,$stateno); |
|
783
|
|
|
|
|
|
|
} |
|
784
|
|
|
|
|
|
|
|
|
785
|
54
|
|
|
|
|
446
|
$states |
|
786
|
|
|
|
|
|
|
} |
|
787
|
|
|
|
|
|
|
|
|
788
|
|
|
|
|
|
|
######################################################### |
|
789
|
|
|
|
|
|
|
# Add Lookahead tokens where needed to make LALR states # |
|
790
|
|
|
|
|
|
|
######################################################### |
|
791
|
|
|
|
|
|
|
# Compute First sets for non-terminal using the following formula: |
|
792
|
|
|
|
|
|
|
# |
|
793
|
|
|
|
|
|
|
# FIRST(A) = { a in T u { epsilon } | A l a } |
|
794
|
|
|
|
|
|
|
# u |
|
795
|
|
|
|
|
|
|
# U { FIRST(B) | B in V and A l B } |
|
796
|
|
|
|
|
|
|
# |
|
797
|
|
|
|
|
|
|
# where: |
|
798
|
|
|
|
|
|
|
# |
|
799
|
|
|
|
|
|
|
# A l x iff [ A -> X1 X2 .. Xn x alpha ] in P and Xi =>* epsilon, 1 <= i <= n |
|
800
|
|
|
|
|
|
|
|
|
801
|
|
|
|
|
|
|
sub _SetFirst { |
|
802
|
54
|
|
|
54
|
|
155
|
my($grammar,$termlst,$terminx)=@_; |
|
803
|
54
|
|
|
|
|
164
|
my($rel,$first)=( {}, {} ); |
|
804
|
|
|
|
|
|
|
|
|
805
|
54
|
|
|
|
|
126
|
for my $symbol (keys(%{$$grammar{NTERM}})) { |
|
|
54
|
|
|
|
|
288
|
|
|
806
|
277
|
|
|
|
|
857
|
$first->{$symbol}=pack('b'.@$termlst); |
|
807
|
|
|
|
|
|
|
|
|
808
|
|
|
|
|
|
|
RULE: |
|
809
|
277
|
|
|
|
|
442
|
for my $ruleno (@{$$grammar{NTERM}{$symbol}}) { |
|
|
277
|
|
|
|
|
605
|
|
|
810
|
691
|
|
|
|
|
1199
|
my($rhs)=$$grammar{RULES}[$ruleno][1]; |
|
811
|
|
|
|
|
|
|
|
|
812
|
691
|
|
|
|
|
1120
|
for (@$rhs) { |
|
813
|
|
|
|
|
|
|
exists($terminx->{$_}) |
|
814
|
680
|
100
|
|
|
|
1580
|
and do { |
|
815
|
269
|
|
|
|
|
726
|
vec($first->{$symbol},$terminx->{$_},1)=1; |
|
816
|
269
|
|
|
|
|
606
|
next RULE; |
|
817
|
|
|
|
|
|
|
}; |
|
818
|
411
|
|
|
|
|
749
|
++$rel->{$symbol}{$_}; |
|
819
|
411
|
100
|
|
|
|
1124
|
exists($$grammar{NULLABLE}{$_}) |
|
820
|
|
|
|
|
|
|
or next RULE; |
|
821
|
|
|
|
|
|
|
} |
|
822
|
28
|
|
|
|
|
88
|
vec($first->{$symbol},0,1)=1; |
|
823
|
|
|
|
|
|
|
} |
|
824
|
|
|
|
|
|
|
} |
|
825
|
54
|
|
|
|
|
318
|
_Digraph($rel,$first); |
|
826
|
|
|
|
|
|
|
|
|
827
|
54
|
|
|
|
|
159
|
$first |
|
828
|
|
|
|
|
|
|
} |
|
829
|
|
|
|
|
|
|
|
|
830
|
|
|
|
|
|
|
sub _Preds { |
|
831
|
1073
|
|
|
1073
|
|
1906
|
my($states,$stateno,$len)=@_; |
|
832
|
1073
|
|
|
|
|
1520
|
my($queue, $preds); |
|
833
|
|
|
|
|
|
|
|
|
834
|
1073
|
100
|
|
|
|
2767
|
$len |
|
835
|
|
|
|
|
|
|
or return [ $stateno ]; |
|
836
|
|
|
|
|
|
|
|
|
837
|
696
|
|
|
|
|
1591
|
$queue=[ [ $stateno, $len ] ]; |
|
838
|
696
|
|
|
|
|
1891
|
while(@$queue) { |
|
839
|
4898
|
|
|
|
|
7500
|
my($pred) = shift(@$queue); |
|
840
|
4898
|
|
|
|
|
7709
|
my($stateno, $len) = @$pred; |
|
841
|
|
|
|
|
|
|
|
|
842
|
|
|
|
|
|
|
$len == 1 |
|
843
|
4898
|
100
|
|
|
|
9497
|
and do { |
|
844
|
4136
|
|
|
|
|
5659
|
push(@$preds,@{$states->[$stateno]{FROM}}); |
|
|
4136
|
|
|
|
|
7305
|
|
|
845
|
4136
|
|
|
|
|
9353
|
next; |
|
846
|
|
|
|
|
|
|
}; |
|
847
|
|
|
|
|
|
|
|
|
848
|
4202
|
|
|
|
|
8927
|
push(@$queue, map { [ $_, $len - 1 ] } |
|
849
|
762
|
|
|
|
|
1125
|
@{$states->[$stateno]{FROM}}); |
|
|
762
|
|
|
|
|
1562
|
|
|
850
|
|
|
|
|
|
|
} |
|
851
|
|
|
|
|
|
|
|
|
852
|
|
|
|
|
|
|
# Pass @$preds through a hash to ensure unicity |
|
853
|
696
|
|
|
|
|
1010
|
[ keys( %{ +{ map { ($_,1) } @$preds } } ) ]; |
|
|
696
|
|
|
|
|
1180
|
|
|
|
7052
|
|
|
|
|
17557
|
|
|
854
|
|
|
|
|
|
|
} |
|
855
|
|
|
|
|
|
|
|
|
856
|
|
|
|
|
|
|
sub _FirstSfx { |
|
857
|
825
|
|
|
825
|
|
1646
|
my($grammar,$firstset,$termlst,$terminx,$ruleno,$pos,$key)=@_; |
|
858
|
825
|
|
|
|
|
1690
|
my($first)=pack('b'.@$termlst); |
|
859
|
825
|
|
|
|
|
1491
|
my($rhs)=$$grammar{RULES}[$ruleno][1]; |
|
860
|
|
|
|
|
|
|
|
|
861
|
825
|
|
|
|
|
1950
|
for (;$pos < @$rhs;++$pos) { |
|
862
|
|
|
|
|
|
|
exists($terminx->{$$rhs[$pos]}) |
|
863
|
414
|
100
|
|
|
|
1061
|
and do { |
|
864
|
344
|
|
|
|
|
882
|
vec($first,$terminx->{$$rhs[$pos]},1)=1; |
|
865
|
344
|
|
|
|
|
1131
|
return($first); |
|
866
|
|
|
|
|
|
|
}; |
|
867
|
70
|
|
|
|
|
145
|
$first|=$firstset->{$$rhs[$pos]}; |
|
868
|
|
|
|
|
|
|
|
|
869
|
70
|
100
|
|
|
|
265
|
vec($first,0,1) |
|
870
|
|
|
|
|
|
|
and vec($first,0,1)=0; |
|
871
|
|
|
|
|
|
|
|
|
872
|
70
|
100
|
|
|
|
291
|
exists($$grammar{NULLABLE}{$$rhs[$pos]}) |
|
873
|
|
|
|
|
|
|
or return($first); |
|
874
|
|
|
|
|
|
|
|
|
875
|
|
|
|
|
|
|
} |
|
876
|
417
|
|
|
|
|
1038
|
vec($first,0,1)=1; |
|
877
|
417
|
|
|
|
|
1298
|
$first; |
|
878
|
|
|
|
|
|
|
} |
|
879
|
|
|
|
|
|
|
|
|
880
|
|
|
|
|
|
|
# Compute Follow sets using following formula: |
|
881
|
|
|
|
|
|
|
# |
|
882
|
|
|
|
|
|
|
# FOLLOW(p,A) = READ(p,A) |
|
883
|
|
|
|
|
|
|
# u |
|
884
|
|
|
|
|
|
|
# U { FOLLOW(q,B) | (p,A) include (q,B) |
|
885
|
|
|
|
|
|
|
# |
|
886
|
|
|
|
|
|
|
# where: |
|
887
|
|
|
|
|
|
|
# |
|
888
|
|
|
|
|
|
|
# READ(p,A) = U { FIRST(beta) | [ A -> alpha A . beta ] in KERNEL(GOTO(p,A)) |
|
889
|
|
|
|
|
|
|
# } - { epsilon } |
|
890
|
|
|
|
|
|
|
# |
|
891
|
|
|
|
|
|
|
# (p,a) include (q,B) iff [ B -> alpha A . beta ] in KERNEL(GOTO(p,A), |
|
892
|
|
|
|
|
|
|
# epsilon in FIRST(beta) and |
|
893
|
|
|
|
|
|
|
# q in PRED(p,alpha) |
|
894
|
|
|
|
|
|
|
|
|
895
|
|
|
|
|
|
|
# >> x $firstset |
|
896
|
|
|
|
|
|
|
# 0 HASH(0x1f7af60) |
|
897
|
|
|
|
|
|
|
# '$start' => "\cG" |
|
898
|
|
|
|
|
|
|
# 'a' => "\cB" |
|
899
|
|
|
|
|
|
|
# 'b' => "\cH" |
|
900
|
|
|
|
|
|
|
# 's' => "\cC" |
|
901
|
|
|
|
|
|
|
# >> x $firstset->{'a'} # firstset es una string compactada de 0 y 1 que es trratada como un conjunto |
|
902
|
|
|
|
|
|
|
# 0 "\cB" |
|
903
|
|
|
|
|
|
|
# >> x unpack ("b*", $firstset->{'a'}) |
|
904
|
|
|
|
|
|
|
# 0 01000000 |
|
905
|
|
|
|
|
|
|
# >> x unpack ("b*", $firstset->{'b'}) |
|
906
|
|
|
|
|
|
|
# 0 00010000 |
|
907
|
|
|
|
|
|
|
# >> x unpack ("b*", $firstset->{'s'}) |
|
908
|
|
|
|
|
|
|
# 0 11000000 |
|
909
|
|
|
|
|
|
|
|
|
910
|
|
|
|
|
|
|
sub _ComputeFollows { |
|
911
|
54
|
|
|
54
|
|
159
|
my($grammar,$states,$termlst)=@_; |
|
912
|
54
|
|
|
|
|
228
|
my($firstset,$terminx); |
|
913
|
54
|
|
|
|
|
211
|
my($inconsistent, $rel, $follows, $sfx)= ( {}, {}, {}, {} ); |
|
914
|
|
|
|
|
|
|
|
|
915
|
54
|
|
|
|
|
198
|
%$terminx= map { ($termlst->[$_],$_) } 0..$#$termlst; |
|
|
624
|
|
|
|
|
1240
|
|
|
916
|
|
|
|
|
|
|
|
|
917
|
54
|
|
|
|
|
336
|
$firstset=_SetFirst($grammar,$termlst,$terminx); |
|
918
|
|
|
|
|
|
|
|
|
919
|
54
|
|
|
|
|
226
|
for my $stateno (0..$#$states) { |
|
920
|
1289
|
|
|
|
|
2334
|
my($state)=$$states[$stateno]; |
|
921
|
|
|
|
|
|
|
|
|
922
|
|
|
|
|
|
|
exists($$state{ACTIONS}{''}) |
|
923
|
|
|
|
|
|
|
and ( @{$$state{ACTIONS}{''}} > 1 |
|
924
|
|
|
|
|
|
|
or keys(%{$$state{ACTIONS}}) > 1 ) |
|
925
|
1289
|
100
|
100
|
|
|
3200
|
and do { |
|
|
|
|
100
|
|
|
|
|
|
926
|
393
|
|
|
|
|
895
|
++$inconsistent->{$stateno}; |
|
927
|
|
|
|
|
|
|
|
|
928
|
393
|
|
|
|
|
579
|
for my $ruleno (@{$$state{ACTIONS}{''}}) { |
|
|
393
|
|
|
|
|
764
|
|
|
929
|
400
|
|
|
|
|
604
|
my($lhs,$rhs)=@{$$grammar{RULES}[$ruleno]}[0,1]; |
|
|
400
|
|
|
|
|
980
|
|
|
930
|
|
|
|
|
|
|
|
|
931
|
400
|
|
|
|
|
639
|
for my $predno (@{_Preds($states,$stateno,scalar(@$rhs))}) { |
|
|
400
|
|
|
|
|
871
|
|
|
932
|
3693
|
|
|
|
|
8104
|
++$rel->{"$stateno.$ruleno"}{"$predno.$lhs"}; |
|
933
|
|
|
|
|
|
|
} |
|
934
|
|
|
|
|
|
|
} |
|
935
|
|
|
|
|
|
|
}; |
|
936
|
|
|
|
|
|
|
|
|
937
|
|
|
|
|
|
|
exists($$state{GOTOS}) |
|
938
|
1289
|
100
|
|
|
|
3233
|
or next; |
|
939
|
|
|
|
|
|
|
|
|
940
|
481
|
|
|
|
|
710
|
for my $symbol (keys(%{$$state{GOTOS}})) { |
|
|
481
|
|
|
|
|
1344
|
|
|
941
|
909
|
|
|
|
|
1839
|
my($tostate)=$$states[$$state{GOTOS}{$symbol}]; |
|
942
|
909
|
|
|
|
|
1756
|
my($goto)="$stateno.$symbol"; |
|
943
|
|
|
|
|
|
|
|
|
944
|
909
|
|
|
|
|
2635
|
$follows->{$goto}=pack('b'.@$termlst); |
|
945
|
|
|
|
|
|
|
|
|
946
|
909
|
|
|
|
|
1327
|
for my $item (@{$$tostate{'CORE'}}) { |
|
|
909
|
|
|
|
|
1744
|
|
|
947
|
3497
|
|
|
|
|
6625
|
my($ruleno,$pos)=@$item; |
|
948
|
3497
|
|
|
|
|
5809
|
my($key)="$ruleno.$pos"; |
|
949
|
|
|
|
|
|
|
|
|
950
|
|
|
|
|
|
|
exists($sfx->{$key}) |
|
951
|
3497
|
100
|
|
|
|
7877
|
or $sfx->{$key} = _FirstSfx($grammar,$firstset, |
|
952
|
|
|
|
|
|
|
$termlst,$terminx, |
|
953
|
|
|
|
|
|
|
$ruleno,$pos,$key); |
|
954
|
|
|
|
|
|
|
|
|
955
|
3497
|
|
|
|
|
6035
|
$follows->{$goto}|=$sfx->{$key}; |
|
956
|
|
|
|
|
|
|
|
|
957
|
|
|
|
|
|
|
vec($follows->{$goto},0,1) |
|
958
|
3497
|
100
|
|
|
|
8548
|
and do { |
|
959
|
673
|
|
|
|
|
1328
|
my($lhs)=$$grammar{RULES}[$ruleno][0]; |
|
960
|
|
|
|
|
|
|
|
|
961
|
673
|
|
|
|
|
1482
|
vec($follows->{$goto},0,1)=0; |
|
962
|
|
|
|
|
|
|
|
|
963
|
673
|
|
|
|
|
1171
|
for my $predno (@{_Preds($states,$stateno,$pos-1)}) { |
|
|
673
|
|
|
|
|
1551
|
|
|
964
|
3736
|
|
|
|
|
8675
|
++$rel->{$goto}{"$predno.$lhs"}; |
|
965
|
|
|
|
|
|
|
} |
|
966
|
|
|
|
|
|
|
}; |
|
967
|
|
|
|
|
|
|
} |
|
968
|
|
|
|
|
|
|
} |
|
969
|
|
|
|
|
|
|
} |
|
970
|
54
|
|
|
|
|
232
|
_Digraph($rel,$follows); |
|
971
|
|
|
|
|
|
|
|
|
972
|
54
|
|
|
|
|
520
|
($follows,$inconsistent) |
|
973
|
|
|
|
|
|
|
} |
|
974
|
|
|
|
|
|
|
|
|
975
|
|
|
|
|
|
|
sub _ComputeLA { |
|
976
|
54
|
|
|
54
|
|
679
|
my($grammar,$states)=@_; |
|
977
|
54
|
|
|
|
|
147
|
my($termlst)= [ '',keys(%{$$grammar{TERM}}) ]; |
|
|
54
|
|
|
|
|
438
|
|
|
978
|
|
|
|
|
|
|
|
|
979
|
54
|
|
|
|
|
307
|
my($follows,$inconsistent) = _ComputeFollows($grammar,$states,$termlst); |
|
980
|
|
|
|
|
|
|
|
|
981
|
54
|
|
|
|
|
248
|
for my $stateno ( keys(%$inconsistent ) ) { |
|
982
|
393
|
|
|
|
|
878
|
my($state)=$$states[$stateno]; |
|
983
|
393
|
|
|
|
|
623
|
my($conflict); |
|
984
|
|
|
|
|
|
|
|
|
985
|
|
|
|
|
|
|
#NB the sort is VERY important for conflicts resolution order |
|
986
|
393
|
|
|
|
|
565
|
for my $ruleno (sort { $a <=> $b } |
|
|
7
|
|
|
|
|
22
|
|
|
987
|
393
|
|
|
|
|
977
|
@{$$state{ACTIONS}{''}}) { |
|
988
|
400
|
|
|
|
|
870
|
for my $term ( map { $termlst->[$_] } grep { |
|
|
2715
|
|
|
|
|
4491
|
|
|
989
|
7450
|
|
|
|
|
12909
|
vec($follows->{"$stateno.$ruleno"},$_,1) } |
|
990
|
|
|
|
|
|
|
0..$#$termlst) { |
|
991
|
2715
|
100
|
|
|
|
5859
|
exists($$state{ACTIONS}{$term}) |
|
992
|
|
|
|
|
|
|
and ++$conflict; |
|
993
|
2715
|
|
|
|
|
3673
|
push(@{$$state{ACTIONS}{$term}},-$ruleno); |
|
|
2715
|
|
|
|
|
6226
|
|
|
994
|
|
|
|
|
|
|
} |
|
995
|
|
|
|
|
|
|
} |
|
996
|
393
|
|
|
|
|
772
|
delete($$state{ACTIONS}{''}); |
|
997
|
|
|
|
|
|
|
$conflict |
|
998
|
393
|
100
|
|
|
|
1033
|
or delete($inconsistent->{$stateno}); |
|
999
|
|
|
|
|
|
|
} |
|
1000
|
|
|
|
|
|
|
|
|
1001
|
|
|
|
|
|
|
$inconsistent |
|
1002
|
54
|
|
|
|
|
261
|
} |
|
1003
|
|
|
|
|
|
|
|
|
1004
|
|
|
|
|
|
|
############################# |
|
1005
|
|
|
|
|
|
|
# Solve remaining conflicts # |
|
1006
|
|
|
|
|
|
|
############################# |
|
1007
|
|
|
|
|
|
|
|
|
1008
|
|
|
|
|
|
|
sub _SolveConflicts { |
|
1009
|
54
|
|
|
54
|
|
153
|
my($grammar,$states,$inconsistent)=@_; |
|
1010
|
54
|
|
|
|
|
128
|
my(%rulesprec,$RulePrec); |
|
1011
|
54
|
|
|
|
|
371
|
my($conflicts)={ SOLVED => {}, |
|
1012
|
|
|
|
|
|
|
FORCED => { TOTAL => [ 0, 0 ], |
|
1013
|
|
|
|
|
|
|
DETAIL => {} |
|
1014
|
|
|
|
|
|
|
} |
|
1015
|
|
|
|
|
|
|
}; |
|
1016
|
|
|
|
|
|
|
|
|
1017
|
|
|
|
|
|
|
$RulePrec = sub { |
|
1018
|
1377
|
|
|
1377
|
|
2174
|
my($ruleno)=@_; |
|
1019
|
1377
|
|
|
|
|
1983
|
my($rhs,$rprec)=@{$$grammar{RULES}[$ruleno]}[1,2]; |
|
|
1377
|
|
|
|
|
2742
|
|
|
1020
|
1377
|
|
|
|
|
2018
|
my($lastterm); |
|
1021
|
|
|
|
|
|
|
|
|
1022
|
1377
|
100
|
|
|
|
2874
|
defined($rprec) |
|
1023
|
|
|
|
|
|
|
and return($rprec); |
|
1024
|
|
|
|
|
|
|
|
|
1025
|
|
|
|
|
|
|
exists($rulesprec{$ruleno}) |
|
1026
|
1244
|
100
|
|
|
|
3189
|
and return($rulesprec{$ruleno}); |
|
1027
|
|
|
|
|
|
|
|
|
1028
|
210
|
|
|
|
|
438
|
$lastterm=(grep { exists($$grammar{TERM}{$_}) } @$rhs)[-1]; |
|
|
632
|
|
|
|
|
1437
|
|
|
1029
|
|
|
|
|
|
|
|
|
1030
|
|
|
|
|
|
|
defined($lastterm) |
|
1031
|
|
|
|
|
|
|
and ref($$grammar{TERM}{$lastterm}) |
|
1032
|
210
|
100
|
66
|
|
|
1003
|
and do { |
|
1033
|
209
|
|
|
|
|
512
|
$rulesprec{$ruleno}=$$grammar{TERM}{$lastterm}[1]; |
|
1034
|
209
|
|
|
|
|
472
|
return($rulesprec{$ruleno}); |
|
1035
|
|
|
|
|
|
|
}; |
|
1036
|
|
|
|
|
|
|
|
|
1037
|
1
|
|
|
|
|
4
|
undef; |
|
1038
|
54
|
|
|
|
|
383
|
}; |
|
1039
|
|
|
|
|
|
|
|
|
1040
|
54
|
|
|
|
|
223
|
for my $stateno (keys(%$inconsistent)) { |
|
1041
|
263
|
|
|
|
|
586
|
my($state)=$$states[$stateno]; |
|
1042
|
263
|
|
|
|
|
483
|
my($actions)=$$state{ACTIONS}; |
|
1043
|
263
|
|
|
|
|
448
|
my($nbsr,$nbrr); |
|
1044
|
|
|
|
|
|
|
|
|
1045
|
263
|
|
|
|
|
745
|
for my $term ( keys(%$actions) ) { |
|
1046
|
2252
|
|
|
|
|
3570
|
my($act)=$$actions{$term}; |
|
1047
|
|
|
|
|
|
|
|
|
1048
|
2252
|
100
|
|
|
|
4646
|
@$act > 1 |
|
1049
|
|
|
|
|
|
|
or next; |
|
1050
|
|
|
|
|
|
|
|
|
1051
|
|
|
|
|
|
|
$$act[0] > 0 |
|
1052
|
|
|
|
|
|
|
and ref($$grammar{TERM}{$term}) |
|
1053
|
1393
|
100
|
66
|
|
|
5641
|
and do { |
|
1054
|
1377
|
|
|
|
|
2037
|
my($assoc,$tprec)=@{$$grammar{TERM}{$term}}; |
|
|
1377
|
|
|
|
|
2612
|
|
|
1055
|
1377
|
|
|
|
|
2156
|
my($k,$error); |
|
1056
|
|
|
|
|
|
|
|
|
1057
|
1377
|
|
|
|
|
2975
|
for ($k=1;$k<@$act;++$k) { |
|
1058
|
1377
|
|
|
|
|
2165
|
my($ruleno)=-$$act[$k]; |
|
1059
|
1377
|
|
|
|
|
2478
|
my($rprec)=&$RulePrec($ruleno); |
|
1060
|
|
|
|
|
|
|
|
|
1061
|
1377
|
100
|
|
|
|
3110
|
defined($rprec) |
|
1062
|
|
|
|
|
|
|
or next; |
|
1063
|
|
|
|
|
|
|
|
|
1064
|
|
|
|
|
|
|
( $tprec > $rprec |
|
1065
|
|
|
|
|
|
|
or ( $tprec == $rprec and $assoc eq 'RIGHT')) |
|
1066
|
1376
|
100
|
100
|
|
|
4641
|
and do { |
|
|
|
|
100
|
|
|
|
|
|
1067
|
602
|
|
|
|
|
866
|
push(@{$$conflicts{SOLVED}{$stateno}}, |
|
|
602
|
|
|
|
|
1751
|
|
|
1068
|
|
|
|
|
|
|
[ $ruleno, $term, 'shift' ]); |
|
1069
|
602
|
|
|
|
|
1107
|
splice(@$act,$k--,1); |
|
1070
|
602
|
|
|
|
|
1437
|
next; |
|
1071
|
|
|
|
|
|
|
}; |
|
1072
|
|
|
|
|
|
|
( $tprec < $rprec |
|
1073
|
|
|
|
|
|
|
or $assoc eq 'LEFT') |
|
1074
|
774
|
50
|
66
|
|
|
2328
|
and do { |
|
1075
|
774
|
|
|
|
|
1107
|
push(@{$$conflicts{SOLVED}{$stateno}}, |
|
|
774
|
|
|
|
|
2024
|
|
|
1076
|
|
|
|
|
|
|
[ $ruleno, $term, 'reduce' ]); |
|
1077
|
|
|
|
|
|
|
$$act[0] > 0 |
|
1078
|
774
|
50
|
|
|
|
1749
|
and do { |
|
1079
|
774
|
|
|
|
|
1171
|
splice(@$act,0,1); |
|
1080
|
774
|
|
|
|
|
1115
|
--$k; |
|
1081
|
|
|
|
|
|
|
}; |
|
1082
|
774
|
|
|
|
|
1809
|
next; |
|
1083
|
|
|
|
|
|
|
}; |
|
1084
|
0
|
|
|
|
|
0
|
push(@{$$conflicts{SOLVED}{$stateno}}, |
|
|
0
|
|
|
|
|
0
|
|
|
1085
|
|
|
|
|
|
|
[ $ruleno, $term, 'error' ]); |
|
1086
|
0
|
|
|
|
|
0
|
splice(@$act,$k--,1); |
|
1087
|
|
|
|
|
|
|
$$act[0] > 0 |
|
1088
|
0
|
0
|
|
|
|
0
|
and do { |
|
1089
|
0
|
|
|
|
|
0
|
splice(@$act,0,1); |
|
1090
|
0
|
|
|
|
|
0
|
++$error; |
|
1091
|
0
|
|
|
|
|
0
|
--$k; |
|
1092
|
|
|
|
|
|
|
}; |
|
1093
|
|
|
|
|
|
|
} |
|
1094
|
1377
|
50
|
|
|
|
2806
|
$error |
|
1095
|
|
|
|
|
|
|
and unshift(@$act,undef); |
|
1096
|
|
|
|
|
|
|
}; |
|
1097
|
|
|
|
|
|
|
|
|
1098
|
|
|
|
|
|
|
@$act > 1 |
|
1099
|
1393
|
100
|
|
|
|
3155
|
and do { |
|
1100
|
17
|
|
|
|
|
29
|
$nbrr += @$act - 2; |
|
1101
|
17
|
50
|
|
|
|
45
|
($$act[0] > 0 ? $nbsr : $nbrr) += 1; |
|
1102
|
17
|
|
|
|
|
62
|
push(@{$$conflicts{FORCED}{DETAIL}{$stateno}{LIST}}, |
|
1103
|
17
|
|
|
|
|
25
|
map { [ $term, $_ ] } splice(@$act,1)); |
|
|
17
|
|
|
|
|
52
|
|
|
1104
|
|
|
|
|
|
|
}; |
|
1105
|
|
|
|
|
|
|
} |
|
1106
|
|
|
|
|
|
|
|
|
1107
|
|
|
|
|
|
|
$nbsr |
|
1108
|
263
|
100
|
|
|
|
709
|
and do { |
|
1109
|
17
|
|
|
|
|
35
|
$$conflicts{FORCED}{TOTAL}[0]+=$nbsr; |
|
1110
|
17
|
|
|
|
|
38
|
$$conflicts{FORCED}{DETAIL}{$stateno}{TOTAL}[0]+=$nbsr; |
|
1111
|
|
|
|
|
|
|
}; |
|
1112
|
|
|
|
|
|
|
|
|
1113
|
|
|
|
|
|
|
$nbrr |
|
1114
|
263
|
50
|
|
|
|
688
|
and do { |
|
1115
|
0
|
|
|
|
|
0
|
$$conflicts{FORCED}{TOTAL}[1]+=$nbrr; |
|
1116
|
0
|
|
|
|
|
0
|
$$conflicts{FORCED}{DETAIL}{$stateno}{TOTAL}[1]+=$nbrr; |
|
1117
|
|
|
|
|
|
|
}; |
|
1118
|
|
|
|
|
|
|
|
|
1119
|
|
|
|
|
|
|
} |
|
1120
|
|
|
|
|
|
|
|
|
1121
|
|
|
|
|
|
|
$conflicts |
|
1122
|
54
|
|
|
|
|
517
|
} |
|
1123
|
|
|
|
|
|
|
|
|
1124
|
|
|
|
|
|
|
############################### |
|
1125
|
|
|
|
|
|
|
# Make default reduce actions # |
|
1126
|
|
|
|
|
|
|
############################### |
|
1127
|
|
|
|
|
|
|
sub _SetDefaults { |
|
1128
|
54
|
|
|
54
|
|
152
|
my($states)=@_; |
|
1129
|
|
|
|
|
|
|
|
|
1130
|
54
|
|
|
|
|
171
|
for my $state (@$states) { |
|
1131
|
1289
|
|
|
|
|
2120
|
my($actions)=$$state{ACTIONS}; |
|
1132
|
|
|
|
|
|
|
|
|
1133
|
|
|
|
|
|
|
# %reduces: - rule number => array of tokens to reduce |
|
1134
|
|
|
|
|
|
|
# $nodefault is true if no default can be derived |
|
1135
|
1289
|
|
|
|
|
1910
|
my(%reduces,$default,$nodefault); |
|
1136
|
|
|
|
|
|
|
|
|
1137
|
|
|
|
|
|
|
#If action with ''=> no default |
|
1138
|
|
|
|
|
|
|
exists($$actions{''}) |
|
1139
|
1289
|
100
|
|
|
|
2731
|
and do { |
|
1140
|
317
|
|
|
|
|
581
|
$$actions{''}[0] = -$$actions{''}[0]; |
|
1141
|
317
|
|
|
|
|
496
|
++$nodefault; |
|
1142
|
|
|
|
|
|
|
}; |
|
1143
|
|
|
|
|
|
|
|
|
1144
|
|
|
|
|
|
|
#shift error token => no default |
|
1145
|
|
|
|
|
|
|
exists($$actions{error}) |
|
1146
|
1289
|
100
|
66
|
|
|
2933
|
and $$actions{error}[0] > 0 |
|
1147
|
|
|
|
|
|
|
and ++$nodefault; |
|
1148
|
|
|
|
|
|
|
|
|
1149
|
1289
|
|
|
|
|
2909
|
for my $term (keys(%$actions)) { |
|
1150
|
|
|
|
|
|
|
|
|
1151
|
5507
|
|
|
|
|
8749
|
$$actions{$term}=$$actions{$term}[0]; |
|
1152
|
|
|
|
|
|
|
|
|
1153
|
5507
|
100
|
66
|
|
|
23986
|
(not defined($$actions{$term}) or $$actions{$term} > 0 or $nodefault) |
|
|
|
|
100
|
|
|
|
|
|
1154
|
|
|
|
|
|
|
and next; |
|
1155
|
|
|
|
|
|
|
|
|
1156
|
2096
|
|
|
|
|
2918
|
push(@{$reduces{$$actions{$term}}},$term); |
|
|
2096
|
|
|
|
|
4837
|
|
|
1157
|
|
|
|
|
|
|
} |
|
1158
|
|
|
|
|
|
|
|
|
1159
|
1289
|
100
|
|
|
|
3366
|
keys(%reduces) > 0 or next; |
|
1160
|
|
|
|
|
|
|
|
|
1161
|
|
|
|
|
|
|
# Find the production rule with the largest reduce set, i.e. |
|
1162
|
|
|
|
|
|
|
# the largest number of tokens |
|
1163
|
|
|
|
|
|
|
|
|
1164
|
|
|
|
|
|
|
# OLD CODE: |
|
1165
|
|
|
|
|
|
|
# $default=( |
|
1166
|
|
|
|
|
|
|
# # take the largest ... |
|
1167
|
|
|
|
|
|
|
# map { $$_[0] } |
|
1168
|
|
|
|
|
|
|
# # sort them by cardinal (in reverse) |
|
1169
|
|
|
|
|
|
|
# sort { $$b[1] <=> $$a[1] or $$b[0] <=> $$a[0] } |
|
1170
|
|
|
|
|
|
|
# # list of [ - rule number, number of tokens for that rule ] |
|
1171
|
|
|
|
|
|
|
# map { [ $_, scalar(@{$reduces{$_}}) ] } |
|
1172
|
|
|
|
|
|
|
# keys(%reduces) # list of - rule numbers |
|
1173
|
|
|
|
|
|
|
# )[0]; |
|
1174
|
|
|
|
|
|
|
|
|
1175
|
377
|
|
|
|
|
593
|
my $max = 0; |
|
1176
|
377
|
|
|
|
|
816
|
for (keys(%reduces)) { |
|
1177
|
384
|
|
|
|
|
552
|
my $t = @{$reduces{$_}}; |
|
|
384
|
|
|
|
|
648
|
|
|
1178
|
384
|
100
|
|
|
|
1025
|
($max, $default) = ($t, $_) if $t > $max; |
|
1179
|
|
|
|
|
|
|
} |
|
1180
|
|
|
|
|
|
|
|
|
1181
|
377
|
|
|
|
|
588
|
delete(@$actions{ @{$reduces{$default}} }); |
|
|
377
|
|
|
|
|
924
|
|
|
1182
|
377
|
|
|
|
|
1081
|
$$state{ACTIONS}{''}=$default; |
|
1183
|
|
|
|
|
|
|
} |
|
1184
|
|
|
|
|
|
|
} |
|
1185
|
|
|
|
|
|
|
|
|
1186
|
|
|
|
|
|
|
sub _dereference { |
|
1187
|
0
|
|
|
0
|
|
0
|
my($states)=@_; |
|
1188
|
|
|
|
|
|
|
|
|
1189
|
0
|
|
|
|
|
0
|
for my $state (@$states) { |
|
1190
|
0
|
|
|
|
|
0
|
my($actions)=$$state{ACTIONS}; |
|
1191
|
|
|
|
|
|
|
|
|
1192
|
|
|
|
|
|
|
exists($$actions{''}) |
|
1193
|
0
|
0
|
|
|
|
0
|
and do { |
|
1194
|
0
|
|
|
|
|
0
|
$$actions{''}[0] = -$$actions{''}[0]; |
|
1195
|
|
|
|
|
|
|
}; |
|
1196
|
|
|
|
|
|
|
|
|
1197
|
0
|
|
|
|
|
0
|
for my $term (keys(%$actions)) { |
|
1198
|
0
|
|
|
|
|
0
|
$$actions{$term}=$$actions{$term}[0]; |
|
1199
|
|
|
|
|
|
|
} |
|
1200
|
|
|
|
|
|
|
|
|
1201
|
|
|
|
|
|
|
} |
|
1202
|
|
|
|
|
|
|
} |
|
1203
|
|
|
|
|
|
|
|
|
1204
|
|
|
|
|
|
|
sub _LALR { |
|
1205
|
54
|
|
|
54
|
|
174
|
my($grammar,$states) = @_; |
|
1206
|
54
|
|
|
|
|
186
|
my($conflicts,$inconsistent); |
|
1207
|
|
|
|
|
|
|
|
|
1208
|
54
|
|
|
|
|
408
|
$inconsistent = _ComputeLA($grammar,$states); |
|
1209
|
|
|
|
|
|
|
|
|
1210
|
54
|
|
|
|
|
255
|
$conflicts = _SolveConflicts($grammar,$states,$inconsistent); |
|
1211
|
|
|
|
|
|
|
|
|
1212
|
54
|
50
|
|
|
|
265
|
if ($grammar->{NOCOMPACT}) { |
|
1213
|
0
|
|
|
|
|
0
|
_dereference($states); |
|
1214
|
|
|
|
|
|
|
} |
|
1215
|
|
|
|
|
|
|
else { |
|
1216
|
54
|
|
|
|
|
238
|
_SetDefaults($states); |
|
1217
|
|
|
|
|
|
|
} |
|
1218
|
|
|
|
|
|
|
|
|
1219
|
54
|
|
|
|
|
267
|
$conflicts |
|
1220
|
|
|
|
|
|
|
} |
|
1221
|
|
|
|
|
|
|
|
|
1222
|
|
|
|
|
|
|
|
|
1223
|
|
|
|
|
|
|
1; |
|
1224
|
|
|
|
|
|
|
|