| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | # | 
| 2 |  |  |  |  |  |  | # Module Parse::Yapp::Lalr | 
| 3 |  |  |  |  |  |  | # | 
| 4 |  |  |  |  |  |  | # Copyright © 1998, 1999, 2000, 2001, Francois Desarmenien. | 
| 5 |  |  |  |  |  |  | # Copyright © 2017 William N. Braswell, Jr. | 
| 6 |  |  |  |  |  |  | # (see the pod text in Parse::Yapp module for use and distribution rights) | 
| 7 |  |  |  |  |  |  | # | 
| 8 |  |  |  |  |  |  | package Parse::Yapp::Lalr; | 
| 9 |  |  |  |  |  |  | @ISA=qw( Parse::Yapp::Grammar ); | 
| 10 |  |  |  |  |  |  |  | 
| 11 |  |  |  |  |  |  | require 5.004; | 
| 12 |  |  |  |  |  |  |  | 
| 13 | 3 |  |  | 3 |  | 1197 | use Parse::Yapp::Grammar; | 
|  | 3 |  |  |  |  | 9 |  | 
|  | 3 |  |  |  |  | 95 |  | 
| 14 |  |  |  |  |  |  |  | 
| 15 |  |  |  |  |  |  | =for nobody | 
| 16 |  |  |  |  |  |  |  | 
| 17 |  |  |  |  |  |  | Parse::Yapp::Compile Object Structure: | 
| 18 |  |  |  |  |  |  | -------------------------------------- | 
| 19 |  |  |  |  |  |  | { | 
| 20 |  |  |  |  |  |  | GRAMMAR =>    Parse::Yapp::Grammar, | 
| 21 |  |  |  |  |  |  | STATES  =>    [ { CORE    => [ items... ], | 
| 22 |  |  |  |  |  |  | ACTIONS  => { term => action } | 
| 23 |  |  |  |  |  |  | GOTOS   => { nterm => stateno } | 
| 24 |  |  |  |  |  |  | }... ] | 
| 25 |  |  |  |  |  |  | CONFLICTS=>{ SOLVED => { stateno  => [ ruleno, token, solved ] }, | 
| 26 |  |  |  |  |  |  | FORCED => { TOTAL => [ nbsr, nbrr ], | 
| 27 |  |  |  |  |  |  | DETAIL => { stateno => { TOTAL => [ nbsr, nbrr ] } | 
| 28 |  |  |  |  |  |  | LIST => [ ruleno, token ] | 
| 29 |  |  |  |  |  |  | } | 
| 30 |  |  |  |  |  |  | } | 
| 31 |  |  |  |  |  |  | } | 
| 32 |  |  |  |  |  |  | } | 
| 33 |  |  |  |  |  |  |  | 
| 34 |  |  |  |  |  |  | 'items' are of form: [ ruleno, dotpos ] | 
| 35 |  |  |  |  |  |  | 'term' in ACTIONS is '' means default action | 
| 36 |  |  |  |  |  |  | 'action' may be: | 
| 37 |  |  |  |  |  |  | undef:  explicit error (nonassociativity) | 
| 38 |  |  |  |  |  |  | 0    :  accept | 
| 39 |  |  |  |  |  |  | >0   :  shift and go to state 'action' | 
| 40 |  |  |  |  |  |  | <0   :  reduce using rule -'action' | 
| 41 |  |  |  |  |  |  | 'solved' may have values of: | 
| 42 |  |  |  |  |  |  | 'shift'  if solved as Shift | 
| 43 |  |  |  |  |  |  | 'reduce' if solved as Reduce | 
| 44 |  |  |  |  |  |  | 'error'  if solved by discarding both Shift and Reduce (nonassoc) | 
| 45 |  |  |  |  |  |  |  | 
| 46 |  |  |  |  |  |  | SOLVED is a set of states containing Solved conflicts | 
| 47 |  |  |  |  |  |  | FORCED are forced conflict resolutions | 
| 48 |  |  |  |  |  |  |  | 
| 49 |  |  |  |  |  |  | nbsr and nbrr are number of shift/reduce and reduce/reduce conflicts | 
| 50 |  |  |  |  |  |  |  | 
| 51 |  |  |  |  |  |  | TOTAL is the total number of SR/RR conflicts for the parser | 
| 52 |  |  |  |  |  |  |  | 
| 53 |  |  |  |  |  |  | DETAIL is the detail of conflicts for each state | 
| 54 |  |  |  |  |  |  | TOTAL is the total number of SR/RR conflicts for a state | 
| 55 |  |  |  |  |  |  | LIST is the list of discarded reductions (for display purpose only) | 
| 56 |  |  |  |  |  |  |  | 
| 57 |  |  |  |  |  |  |  | 
| 58 |  |  |  |  |  |  | =cut | 
| 59 |  |  |  |  |  |  |  | 
| 60 | 3 |  |  | 3 |  | 16 | use strict; | 
|  | 3 |  |  |  |  | 6 |  | 
|  | 3 |  |  |  |  | 50 |  | 
| 61 |  |  |  |  |  |  |  | 
| 62 | 3 |  |  | 3 |  | 14 | use Carp; | 
|  | 3 |  |  |  |  | 5 |  | 
|  | 3 |  |  |  |  | 10409 |  | 
| 63 |  |  |  |  |  |  |  | 
| 64 |  |  |  |  |  |  | ############### | 
| 65 |  |  |  |  |  |  | # Constructor # | 
| 66 |  |  |  |  |  |  | ############### | 
| 67 |  |  |  |  |  |  | sub new { | 
| 68 | 10 |  |  | 10 | 0 | 1858 | my($class)=shift; | 
| 69 |  |  |  |  |  |  |  | 
| 70 | 10 | 50 |  |  |  | 32 | ref($class) | 
| 71 |  |  |  |  |  |  | and	$class=ref($class); | 
| 72 |  |  |  |  |  |  |  | 
| 73 | 10 |  |  |  |  | 60 | my($self)=$class->SUPER::new(@_); | 
| 74 | 10 |  |  |  |  | 65 | $self->_Compile(); | 
| 75 | 10 |  |  |  |  | 44 | bless($self,$class); | 
| 76 |  |  |  |  |  |  | } | 
| 77 |  |  |  |  |  |  | ########### | 
| 78 |  |  |  |  |  |  | # Methods # | 
| 79 |  |  |  |  |  |  | ########### | 
| 80 |  |  |  |  |  |  |  | 
| 81 |  |  |  |  |  |  | ########################### | 
| 82 |  |  |  |  |  |  | # Method To View Warnings # | 
| 83 |  |  |  |  |  |  | ########################### | 
| 84 |  |  |  |  |  |  | sub Warnings { | 
| 85 | 0 |  |  | 0 | 0 | 0 | my($self)=shift; | 
| 86 | 0 |  |  |  |  | 0 | my($text); | 
| 87 | 0 |  |  |  |  | 0 | my($nbsr,$nbrr)=@{$$self{CONFLICTS}{FORCED}{TOTAL}}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 88 |  |  |  |  |  |  |  | 
| 89 | 0 |  |  |  |  | 0 | $text=$self->SUPER::Warnings(); | 
| 90 |  |  |  |  |  |  |  | 
| 91 |  |  |  |  |  |  | $nbsr != $$self{GRAMMAR}{EXPECT} | 
| 92 | 0 | 0 |  |  |  | 0 | and $text.="$nbsr shift/reduce conflict".($nbsr > 1 ? "s" : ""); | 
|  |  | 0 |  |  |  |  |  | 
| 93 |  |  |  |  |  |  |  | 
| 94 |  |  |  |  |  |  | $nbrr | 
| 95 | 0 | 0 |  |  |  | 0 | and do { | 
| 96 | 0 | 0 |  |  |  | 0 | $nbsr | 
| 97 |  |  |  |  |  |  | and $text.=" and "; | 
| 98 | 0 | 0 |  |  |  | 0 | $text.="$nbrr reduce/reduce conflict".($nbrr > 1 ? "s" : ""); | 
| 99 |  |  |  |  |  |  | }; | 
| 100 |  |  |  |  |  |  |  | 
| 101 |  |  |  |  |  |  | (    $nbsr != $$self{GRAMMAR}{EXPECT} | 
| 102 | 0 | 0 | 0 |  |  | 0 | or  $nbrr) | 
| 103 |  |  |  |  |  |  | and $text.="\n"; | 
| 104 |  |  |  |  |  |  |  | 
| 105 | 0 |  |  |  |  | 0 | $text; | 
| 106 |  |  |  |  |  |  | } | 
| 107 |  |  |  |  |  |  | ############################# | 
| 108 |  |  |  |  |  |  | # Method To View DFA States # | 
| 109 |  |  |  |  |  |  | ############################# | 
| 110 |  |  |  |  |  |  | sub ShowDfa { | 
| 111 | 0 |  |  | 0 | 0 | 0 | my($self)=shift; | 
| 112 | 0 |  |  |  |  | 0 | my($text); | 
| 113 | 0 |  |  |  |  | 0 | my($grammar,$states)=($$self{GRAMMAR}, $$self{STATES}); | 
| 114 |  |  |  |  |  |  |  | 
| 115 | 0 |  |  |  |  | 0 | for my $stateno (0..$#$states) { | 
| 116 | 0 |  |  |  |  | 0 | my(@shifts,@reduces,@errors,$default); | 
| 117 |  |  |  |  |  |  |  | 
| 118 | 0 |  |  |  |  | 0 | $text.="State $stateno:\n\n"; | 
| 119 |  |  |  |  |  |  |  | 
| 120 |  |  |  |  |  |  | #Dump Kernel Items | 
| 121 | 0 | 0 |  |  |  | 0 | for (sort {     $$a[0] <=> $$b[0] | 
|  | 0 |  |  |  |  | 0 |  | 
| 122 | 0 |  |  |  |  | 0 | or  $$a[1] <=> $$b[1] } @{$$states[$stateno]{'CORE'}}) { | 
| 123 | 0 |  |  |  |  | 0 | my($ruleno,$pos)=@$_; | 
| 124 | 0 |  |  |  |  | 0 | my($lhs,$rhs)=@{$$grammar{RULES}[$ruleno]}[0,1]; | 
|  | 0 |  |  |  |  | 0 |  | 
| 125 | 0 |  |  |  |  | 0 | my(@rhscopy)=@$rhs; | 
| 126 |  |  |  |  |  |  |  | 
| 127 | 0 | 0 |  |  |  | 0 | $ruleno | 
| 128 |  |  |  |  |  |  | or  $rhscopy[-1] = '$end'; | 
| 129 |  |  |  |  |  |  |  | 
| 130 | 0 |  |  |  |  | 0 | splice(@rhscopy,$pos,0,'.'); | 
| 131 | 0 |  |  |  |  | 0 | $text.= "\t$lhs -> ".join(' ',@rhscopy)."\t(Rule $ruleno)\n"; | 
| 132 |  |  |  |  |  |  | } | 
| 133 |  |  |  |  |  |  |  | 
| 134 |  |  |  |  |  |  | #Prepare Actions | 
| 135 | 0 |  |  |  |  | 0 | for (keys(%{$$states[$stateno]{ACTIONS}})) { | 
|  | 0 |  |  |  |  | 0 |  | 
| 136 | 0 |  |  |  |  | 0 | my($term,$action)=($_,$$states[$stateno]{ACTIONS}{$_}); | 
| 137 |  |  |  |  |  |  |  | 
| 138 | 0 | 0 |  |  |  | 0 | $term eq chr(0) | 
| 139 |  |  |  |  |  |  | and $term = '$end'; | 
| 140 |  |  |  |  |  |  |  | 
| 141 |  |  |  |  |  |  | not defined($action) | 
| 142 | 0 | 0 |  |  |  | 0 | and do { | 
| 143 | 0 |  |  |  |  | 0 | push(@errors,$term); | 
| 144 | 0 |  |  |  |  | 0 | next; | 
| 145 |  |  |  |  |  |  | }; | 
| 146 |  |  |  |  |  |  |  | 
| 147 |  |  |  |  |  |  | $action > 0 | 
| 148 | 0 | 0 |  |  |  | 0 | and do { | 
| 149 | 0 |  |  |  |  | 0 | push(@shifts,[ $term, $action ]); | 
| 150 | 0 |  |  |  |  | 0 | next; | 
| 151 |  |  |  |  |  |  | }; | 
| 152 |  |  |  |  |  |  |  | 
| 153 | 0 |  |  |  |  | 0 | $action = -$action; | 
| 154 |  |  |  |  |  |  |  | 
| 155 |  |  |  |  |  |  | $term | 
| 156 | 0 | 0 |  |  |  | 0 | or  do { | 
| 157 | 0 |  |  |  |  | 0 | $default= [ '$default', $action ]; | 
| 158 | 0 |  |  |  |  | 0 | next; | 
| 159 |  |  |  |  |  |  | }; | 
| 160 |  |  |  |  |  |  |  | 
| 161 | 0 |  |  |  |  | 0 | push(@reduces,[ $term, $action ]); | 
| 162 |  |  |  |  |  |  | } | 
| 163 |  |  |  |  |  |  |  | 
| 164 |  |  |  |  |  |  | #Dump shifts | 
| 165 |  |  |  |  |  |  | @shifts | 
| 166 | 0 | 0 |  |  |  | 0 | and do { | 
| 167 | 0 |  |  |  |  | 0 | $text.="\n"; | 
| 168 | 0 |  |  |  |  | 0 | for (sort { $$a[0] cmp $$b[0] } @shifts) { | 
|  | 0 |  |  |  |  | 0 |  | 
| 169 | 0 |  |  |  |  | 0 | my($term,$shift)=@$_; | 
| 170 |  |  |  |  |  |  |  | 
| 171 | 0 |  |  |  |  | 0 | $text.="\t$term\tshift, and go to state $shift\n"; | 
| 172 |  |  |  |  |  |  | } | 
| 173 |  |  |  |  |  |  | }; | 
| 174 |  |  |  |  |  |  |  | 
| 175 |  |  |  |  |  |  | #Dump errors | 
| 176 |  |  |  |  |  |  | @errors | 
| 177 | 0 | 0 |  |  |  | 0 | and do { | 
| 178 | 0 |  |  |  |  | 0 | $text.="\n"; | 
| 179 | 0 |  |  |  |  | 0 | for my $term (sort { $a cmp $b } @errors) { | 
|  | 0 |  |  |  |  | 0 |  | 
| 180 | 0 |  |  |  |  | 0 | $text.="\t$term\terror (nonassociative)\n"; | 
| 181 |  |  |  |  |  |  | } | 
| 182 |  |  |  |  |  |  | }; | 
| 183 |  |  |  |  |  |  |  | 
| 184 |  |  |  |  |  |  | #Prepare reduces | 
| 185 |  |  |  |  |  |  | exists($$self{CONFLICTS}{FORCED}{DETAIL}{$stateno}) | 
| 186 | 0 | 0 |  |  |  | 0 | and push(@reduces,@{$$self{CONFLICTS}{FORCED}{DETAIL}{$stateno}{LIST}}); | 
|  | 0 |  |  |  |  | 0 |  | 
| 187 |  |  |  |  |  |  |  | 
| 188 | 0 | 0 |  |  |  | 0 | @reduces=sort { $$a[0] cmp $$b[0] or $$a[1] <=> $$b[1] } @reduces; | 
|  | 0 |  |  |  |  | 0 |  | 
| 189 |  |  |  |  |  |  |  | 
| 190 | 0 | 0 |  |  |  | 0 | defined($default) | 
| 191 |  |  |  |  |  |  | and push(@reduces,$default); | 
| 192 |  |  |  |  |  |  |  | 
| 193 |  |  |  |  |  |  | #Dump reduces | 
| 194 |  |  |  |  |  |  | @reduces | 
| 195 | 0 | 0 |  |  |  | 0 | and do { | 
| 196 | 0 |  |  |  |  | 0 | $text.="\n"; | 
| 197 | 0 |  |  |  |  | 0 | for (@reduces) { | 
| 198 | 0 |  |  |  |  | 0 | my($term,$ruleno)=@$_; | 
| 199 | 0 |  |  |  |  | 0 | my($discard); | 
| 200 |  |  |  |  |  |  |  | 
| 201 |  |  |  |  |  |  | $ruleno < 0 | 
| 202 | 0 | 0 |  |  |  | 0 | and do { | 
| 203 | 0 |  |  |  |  | 0 | ++$discard; | 
| 204 | 0 |  |  |  |  | 0 | $ruleno = -$ruleno; | 
| 205 |  |  |  |  |  |  | }; | 
| 206 |  |  |  |  |  |  |  | 
| 207 | 0 | 0 |  |  |  | 0 | $text.= "\t$term\t".($discard  ? "[" : ""); | 
| 208 | 0 | 0 |  |  |  | 0 | if($ruleno) { | 
| 209 | 0 |  |  |  |  | 0 | $text.= "reduce using rule $ruleno ". | 
| 210 |  |  |  |  |  |  | "($$grammar{RULES}[$ruleno][0])"; | 
| 211 |  |  |  |  |  |  | } | 
| 212 |  |  |  |  |  |  | else { | 
| 213 | 0 |  |  |  |  | 0 | $text.='accept'; | 
| 214 |  |  |  |  |  |  | } | 
| 215 | 0 | 0 |  |  |  | 0 | $text.=($discard  ? "]" : "")."\n"; | 
| 216 |  |  |  |  |  |  | } | 
| 217 |  |  |  |  |  |  | }; | 
| 218 |  |  |  |  |  |  |  | 
| 219 |  |  |  |  |  |  | #Dump gotos | 
| 220 |  |  |  |  |  |  | exists($$states[$stateno]{GOTOS}) | 
| 221 | 0 | 0 |  |  |  | 0 | and    do { | 
| 222 | 0 |  |  |  |  | 0 | $text.= "\n"; | 
| 223 | 0 |  |  |  |  | 0 | for (keys(%{$$states[$stateno]{GOTOS}})) { | 
|  | 0 |  |  |  |  | 0 |  | 
| 224 | 0 |  |  |  |  | 0 | $text.= "\t$_\tgo to state $$states[$stateno]{GOTOS}{$_}\n"; | 
| 225 |  |  |  |  |  |  | } | 
| 226 |  |  |  |  |  |  | }; | 
| 227 |  |  |  |  |  |  |  | 
| 228 | 0 |  |  |  |  | 0 | $text.="\n"; | 
| 229 |  |  |  |  |  |  | } | 
| 230 | 0 |  |  |  |  | 0 | $text; | 
| 231 |  |  |  |  |  |  | } | 
| 232 |  |  |  |  |  |  |  | 
| 233 |  |  |  |  |  |  | ###################################### | 
| 234 |  |  |  |  |  |  | # Method to get summary about parser # | 
| 235 |  |  |  |  |  |  | ###################################### | 
| 236 |  |  |  |  |  |  | sub Summary { | 
| 237 | 0 |  |  | 0 | 0 | 0 | my($self)=shift; | 
| 238 | 0 |  |  |  |  | 0 | my($text); | 
| 239 |  |  |  |  |  |  |  | 
| 240 | 0 |  |  |  |  | 0 | $text=$self->SUPER::Summary(); | 
| 241 |  |  |  |  |  |  | $text.="Number of states        : ". | 
| 242 | 0 |  |  |  |  | 0 | scalar(@{$$self{STATES}})."\n"; | 
|  | 0 |  |  |  |  | 0 |  | 
| 243 | 0 |  |  |  |  | 0 | $text; | 
| 244 |  |  |  |  |  |  | } | 
| 245 |  |  |  |  |  |  |  | 
| 246 |  |  |  |  |  |  | ####################################### | 
| 247 |  |  |  |  |  |  | # Method To Get Infos about conflicts # | 
| 248 |  |  |  |  |  |  | ####################################### | 
| 249 |  |  |  |  |  |  | sub Conflicts { | 
| 250 | 0 |  |  | 0 | 0 | 0 | my($self)=shift; | 
| 251 | 0 |  |  |  |  | 0 | my($states)=$$self{STATES}; | 
| 252 | 0 |  |  |  |  | 0 | my($conflicts)=$$self{CONFLICTS}; | 
| 253 | 0 |  |  |  |  | 0 | my($text); | 
| 254 |  |  |  |  |  |  |  | 
| 255 | 0 |  |  |  |  | 0 | for my $stateno ( sort { $a <=> $b } keys(%{$$conflicts{SOLVED}})) { | 
|  | 0 |  |  |  |  | 0 |  | 
|  | 0 |  |  |  |  | 0 |  | 
| 256 |  |  |  |  |  |  |  | 
| 257 | 0 |  |  |  |  | 0 | for (@{$$conflicts{SOLVED}{$stateno}}) { | 
|  | 0 |  |  |  |  | 0 |  | 
| 258 | 0 |  |  |  |  | 0 | my($ruleno,$token,$how)=@$_; | 
| 259 |  |  |  |  |  |  |  | 
| 260 | 0 | 0 |  |  |  | 0 | $token eq chr(0) | 
| 261 |  |  |  |  |  |  | and $token = '$end'; | 
| 262 |  |  |  |  |  |  |  | 
| 263 | 0 |  |  |  |  | 0 | $text.="Conflict in state $stateno between rule ". | 
| 264 |  |  |  |  |  |  | "$ruleno and token $token resolved as $how.\n"; | 
| 265 |  |  |  |  |  |  | } | 
| 266 |  |  |  |  |  |  | }; | 
| 267 |  |  |  |  |  |  |  | 
| 268 | 0 |  |  |  |  | 0 | for my $stateno ( sort { $a <=> $b } keys(%{$$conflicts{FORCED}{DETAIL}})) { | 
|  | 0 |  |  |  |  | 0 |  | 
|  | 0 |  |  |  |  | 0 |  | 
| 269 | 0 |  |  |  |  | 0 | my($nbsr,$nbrr)=@{$$conflicts{FORCED}{DETAIL}{$stateno}{TOTAL}}; | 
|  | 0 |  |  |  |  | 0 |  | 
| 270 |  |  |  |  |  |  |  | 
| 271 | 0 |  |  |  |  | 0 | $text.="State $stateno contains "; | 
| 272 |  |  |  |  |  |  |  | 
| 273 | 0 | 0 |  |  |  | 0 | $nbsr | 
|  |  | 0 |  |  |  |  |  | 
| 274 |  |  |  |  |  |  | and $text.="$nbsr shift/reduce conflict". | 
| 275 |  |  |  |  |  |  | ($nbsr > 1 ? "s" : ""); | 
| 276 |  |  |  |  |  |  |  | 
| 277 |  |  |  |  |  |  | $nbrr | 
| 278 | 0 | 0 |  |  |  | 0 | and do { | 
| 279 | 0 | 0 |  |  |  | 0 | $nbsr | 
| 280 |  |  |  |  |  |  | and $text.=" and "; | 
| 281 |  |  |  |  |  |  |  | 
| 282 | 0 | 0 |  |  |  | 0 | $text.="$nbrr reduce/reduce conflict". | 
| 283 |  |  |  |  |  |  | ($nbrr > 1 ? "s" : ""); | 
| 284 |  |  |  |  |  |  | }; | 
| 285 | 0 |  |  |  |  | 0 | $text.="\n"; | 
| 286 |  |  |  |  |  |  | }; | 
| 287 |  |  |  |  |  |  |  | 
| 288 | 0 |  |  |  |  | 0 | $text; | 
| 289 |  |  |  |  |  |  | } | 
| 290 |  |  |  |  |  |  |  | 
| 291 |  |  |  |  |  |  | ################################# | 
| 292 |  |  |  |  |  |  | # Method to dump parsing tables # | 
| 293 |  |  |  |  |  |  | ################################# | 
| 294 |  |  |  |  |  |  | sub DfaTable { | 
| 295 | 9 |  |  | 9 | 0 | 18 | my($self)=shift; | 
| 296 | 9 |  |  |  |  | 17 | my($states)=$$self{STATES}; | 
| 297 | 9 |  |  |  |  | 16 | my($stateno); | 
| 298 |  |  |  |  |  |  | my($text); | 
| 299 |  |  |  |  |  |  |  | 
| 300 | 9 |  |  |  |  | 17 | $text="[\n\t{"; | 
| 301 |  |  |  |  |  |  |  | 
| 302 |  |  |  |  |  |  | $text.=join("\n\t},\n\t{", | 
| 303 |  |  |  |  |  |  | map { | 
| 304 | 9 |  |  |  |  | 16 | my($state)=$_; | 
|  | 107 |  |  |  |  | 147 |  | 
| 305 | 107 |  |  |  |  | 144 | my($text); | 
| 306 |  |  |  |  |  |  |  | 
| 307 | 107 |  |  |  |  | 175 | $text="#State ".$stateno++."\n\t\t"; | 
| 308 |  |  |  |  |  |  |  | 
| 309 |  |  |  |  |  |  | (    not exists($$state{ACTIONS}{''}) | 
| 310 | 63 |  |  |  |  | 219 | or  keys(%{$$state{ACTIONS}}) > 1) | 
| 311 | 107 | 100 | 100 |  |  | 250 | and do { | 
| 312 |  |  |  |  |  |  |  | 
| 313 | 57 |  |  |  |  | 85 | $text.="ACTIONS => {\n\t\t\t"; | 
| 314 |  |  |  |  |  |  |  | 
| 315 |  |  |  |  |  |  | $text.=join(",\n\t\t\t", | 
| 316 |  |  |  |  |  |  | map { | 
| 317 | 126 |  |  |  |  | 227 | my($term,$action)=($_,$$state{ACTIONS}{$_}); | 
| 318 | 126 |  |  |  |  | 152 | my($text); | 
| 319 |  |  |  |  |  |  |  | 
| 320 | 126 | 100 |  |  |  | 245 | if(substr($term,0,1) eq "'") { | 
| 321 | 96 |  |  |  |  | 155 | $term=~s/([\@\$\"])/\\$1/g; | 
| 322 | 96 |  |  |  |  | 271 | $term=~s/^'|'$/"/g; | 
| 323 |  |  |  |  |  |  | } | 
| 324 |  |  |  |  |  |  | else { | 
| 325 | 30 | 100 |  |  |  | 65 | $term=      $term eq chr(0) | 
| 326 |  |  |  |  |  |  | ?   "''" | 
| 327 |  |  |  |  |  |  | :   "'$term'"; | 
| 328 |  |  |  |  |  |  | } | 
| 329 |  |  |  |  |  |  |  | 
| 330 | 126 | 100 |  |  |  | 227 | if(defined($action)) { | 
| 331 | 125 |  |  |  |  | 168 | $action=int($action); | 
| 332 |  |  |  |  |  |  | } | 
| 333 |  |  |  |  |  |  | else { | 
| 334 | 1 |  |  |  |  | 3 | $action='undef'; | 
| 335 |  |  |  |  |  |  | } | 
| 336 |  |  |  |  |  |  |  | 
| 337 | 126 |  |  |  |  | 282 | "$term => $action"; | 
| 338 |  |  |  |  |  |  |  | 
| 339 | 57 |  |  |  |  | 75 | } grep { $_ } keys(%{$$state{ACTIONS}})); | 
|  | 139 |  |  |  |  | 248 |  | 
|  | 57 |  |  |  |  | 115 |  | 
| 340 |  |  |  |  |  |  |  | 
| 341 | 57 |  |  |  |  | 102 | $text.="\n\t\t}"; | 
| 342 |  |  |  |  |  |  | }; | 
| 343 |  |  |  |  |  |  |  | 
| 344 |  |  |  |  |  |  | exists($$state{ACTIONS}{''}) | 
| 345 | 107 | 100 |  |  |  | 225 | and do { | 
| 346 | 63 | 100 |  |  |  | 75 | keys(%{$$state{ACTIONS}}) > 1 | 
|  | 63 |  |  |  |  | 143 |  | 
| 347 |  |  |  |  |  |  | and $text.=",\n\t\t"; | 
| 348 |  |  |  |  |  |  |  | 
| 349 | 63 |  |  |  |  | 118 | $text.="DEFAULT => $$state{ACTIONS}{''}"; | 
| 350 |  |  |  |  |  |  | }; | 
| 351 |  |  |  |  |  |  |  | 
| 352 |  |  |  |  |  |  | exists($$state{GOTOS}) | 
| 353 | 107 | 100 |  |  |  | 213 | and do { | 
| 354 | 29 |  |  |  |  | 47 | $text.=",\n\t\tGOTOS => {\n\t\t\t"; | 
| 355 |  |  |  |  |  |  | $text.=join(",\n\t\t\t", | 
| 356 |  |  |  |  |  |  | map { | 
| 357 | 43 |  |  |  |  | 73 | my($nterm,$stateno)=($_,$$state{GOTOS}{$_}); | 
| 358 | 43 |  |  |  |  | 56 | my($text); | 
| 359 |  |  |  |  |  |  |  | 
| 360 | 43 |  |  |  |  | 104 | "'$nterm' => $stateno"; | 
| 361 |  |  |  |  |  |  |  | 
| 362 | 29 |  |  |  |  | 46 | } keys(%{$$state{GOTOS}})); | 
|  | 29 |  |  |  |  | 59 |  | 
| 363 | 29 |  |  |  |  | 48 | $text.="\n\t\t}"; | 
| 364 |  |  |  |  |  |  | }; | 
| 365 |  |  |  |  |  |  |  | 
| 366 | 107 |  |  |  |  | 202 | $text; | 
| 367 |  |  |  |  |  |  |  | 
| 368 |  |  |  |  |  |  | }@$states); | 
| 369 |  |  |  |  |  |  |  | 
| 370 | 9 |  |  |  |  | 33 | $text.="\n\t}\n]"; | 
| 371 |  |  |  |  |  |  |  | 
| 372 | 9 |  |  |  |  | 27 | $text; | 
| 373 |  |  |  |  |  |  |  | 
| 374 |  |  |  |  |  |  | } | 
| 375 |  |  |  |  |  |  |  | 
| 376 |  |  |  |  |  |  |  | 
| 377 |  |  |  |  |  |  | #################################### | 
| 378 |  |  |  |  |  |  | # Method to build Dfa from Grammar # | 
| 379 |  |  |  |  |  |  | #################################### | 
| 380 |  |  |  |  |  |  | sub _Compile { | 
| 381 | 10 |  |  | 10 |  | 20 | my($self)=shift; | 
| 382 | 10 |  |  |  |  | 20 | my($grammar,$states); | 
| 383 |  |  |  |  |  |  |  | 
| 384 | 10 |  |  |  |  | 24 | $grammar=$self->{GRAMMAR}; | 
| 385 |  |  |  |  |  |  |  | 
| 386 | 10 |  |  |  |  | 33 | $states = _LR0($grammar); | 
| 387 |  |  |  |  |  |  |  | 
| 388 | 10 |  |  |  |  | 36 | $self->{CONFLICTS} = _LALR($grammar,$states); | 
| 389 |  |  |  |  |  |  |  | 
| 390 | 10 |  |  |  |  | 25 | $self->{STATES}=$states; | 
| 391 |  |  |  |  |  |  | } | 
| 392 |  |  |  |  |  |  |  | 
| 393 |  |  |  |  |  |  | ######################### | 
| 394 |  |  |  |  |  |  | # LR0 States Generation # | 
| 395 |  |  |  |  |  |  | ######################### | 
| 396 |  |  |  |  |  |  | # | 
| 397 |  |  |  |  |  |  | ########################### | 
| 398 |  |  |  |  |  |  | # General digraph routine # | 
| 399 |  |  |  |  |  |  | ########################### | 
| 400 |  |  |  |  |  |  | sub _Digraph { | 
| 401 | 30 |  |  | 30 |  | 56 | my($rel,$F)=@_; | 
| 402 | 30 |  |  |  |  | 50 | my(%N,@S); | 
| 403 | 30 |  |  |  |  | 48 | my($infinity)=(~(1<<31)); | 
| 404 | 30 |  |  |  |  | 52 | my($Traverse); | 
| 405 |  |  |  |  |  |  |  | 
| 406 |  |  |  |  |  |  | $Traverse = sub { | 
| 407 | 10659 |  |  | 10659 |  | 16523 | my($x,$d)=@_; | 
| 408 | 10659 |  |  |  |  | 13595 | my($y); | 
| 409 |  |  |  |  |  |  |  | 
| 410 | 10659 |  |  |  |  | 14578 | push(@S,$x); | 
| 411 | 10659 |  |  |  |  | 18232 | $N{$x}=$d; | 
| 412 |  |  |  |  |  |  |  | 
| 413 |  |  |  |  |  |  | exists($$rel{$x}) | 
| 414 | 10659 | 100 |  |  |  | 22908 | and do { | 
| 415 | 9183 |  |  |  |  | 11934 | for $y (keys(%{$$rel{$x}})) { | 
|  | 9183 |  |  |  |  | 30201 |  | 
| 416 | 42992 | 100 |  |  |  | 91941 | exists($N{$y}) | 
| 417 |  |  |  |  |  |  | or  &$Traverse($y,$d+1); | 
| 418 |  |  |  |  |  |  |  | 
| 419 |  |  |  |  |  |  | $N{$y} < $N{$x} | 
| 420 | 42992 | 100 |  |  |  | 82489 | and $N{$x} = $N{$y}; | 
| 421 |  |  |  |  |  |  |  | 
| 422 | 42992 |  |  |  |  | 79575 | $$F{$x}|=$$F{$y}; | 
| 423 |  |  |  |  |  |  | } | 
| 424 |  |  |  |  |  |  | }; | 
| 425 |  |  |  |  |  |  |  | 
| 426 |  |  |  |  |  |  | $N{$x} == $d | 
| 427 | 10659 | 100 |  |  |  | 22869 | and do { | 
| 428 | 10322 |  |  |  |  | 13171 | for(;;) { | 
| 429 | 10659 |  |  |  |  | 14525 | $y=pop(@S); | 
| 430 | 10659 |  |  |  |  | 14975 | $N{$y}=$infinity; | 
| 431 | 10659 | 100 |  |  |  | 23137 | $y eq $x | 
| 432 |  |  |  |  |  |  | and last; | 
| 433 | 337 |  |  |  |  | 484 | $$F{$y}=$$F{$x}; | 
| 434 |  |  |  |  |  |  | } | 
| 435 |  |  |  |  |  |  | }; | 
| 436 | 30 |  |  |  |  | 128 | }; | 
| 437 |  |  |  |  |  |  |  | 
| 438 | 30 |  |  |  |  | 3316 | for (keys(%$rel)) { | 
| 439 | 9183 | 100 |  |  |  | 20707 | exists($N{$_}) | 
| 440 |  |  |  |  |  |  | or  &$Traverse($_,1); | 
| 441 |  |  |  |  |  |  | } | 
| 442 |  |  |  |  |  |  | } | 
| 443 |  |  |  |  |  |  | ####################### | 
| 444 |  |  |  |  |  |  | # Generate LR0 states # | 
| 445 |  |  |  |  |  |  | ####################### | 
| 446 |  |  |  |  |  |  | =for nobody | 
| 447 |  |  |  |  |  |  | Formula used for closures: | 
| 448 |  |  |  |  |  |  |  | 
| 449 |  |  |  |  |  |  | CLOSE(A) = DCLOSE(A) u U (CLOSE(B) | A close B) | 
| 450 |  |  |  |  |  |  |  | 
| 451 |  |  |  |  |  |  | where: | 
| 452 |  |  |  |  |  |  |  | 
| 453 |  |  |  |  |  |  | DCLOSE(A) = { [ A -> alpha ] in P } | 
| 454 |  |  |  |  |  |  |  | 
| 455 |  |  |  |  |  |  | A close B iff [ A -> B gamma ] in P | 
| 456 |  |  |  |  |  |  |  | 
| 457 |  |  |  |  |  |  | =cut | 
| 458 |  |  |  |  |  |  | sub _SetClosures { | 
| 459 | 10 |  |  | 10 |  | 21 | my($grammar)=@_; | 
| 460 | 10 |  |  |  |  | 19 | my($rel,$closures); | 
| 461 |  |  |  |  |  |  |  | 
| 462 | 10 |  |  |  |  | 18 | for my $symbol (keys(%{$$grammar{NTERM}})) { | 
|  | 10 |  |  |  |  | 68 |  | 
| 463 | 270 |  |  |  |  | 381 | $closures->{$symbol}=pack('b'.@{$$grammar{RULES}}); | 
|  | 270 |  |  |  |  | 644 |  | 
| 464 |  |  |  |  |  |  |  | 
| 465 | 270 |  |  |  |  | 408 | for my $ruleno (@{$$grammar{NTERM}{$symbol}}) { | 
|  | 270 |  |  |  |  | 465 |  | 
| 466 | 888 |  |  |  |  | 1311 | my($rhs)=$$grammar{RULES}[$ruleno][1]; | 
| 467 |  |  |  |  |  |  |  | 
| 468 | 888 |  |  |  |  | 1622 | vec($closures->{$symbol},$ruleno,1)=1; | 
| 469 |  |  |  |  |  |  |  | 
| 470 |  |  |  |  |  |  | @$rhs > 0 | 
| 471 |  |  |  |  |  |  | and exists($$grammar{NTERM}{$$rhs[0]}) | 
| 472 | 888 | 100 | 100 |  |  | 3842 | and ++$rel->{$symbol}{$$rhs[0]}; | 
| 473 |  |  |  |  |  |  | } | 
| 474 |  |  |  |  |  |  | } | 
| 475 | 10 |  |  |  |  | 44 | _Digraph($rel,$closures); | 
| 476 |  |  |  |  |  |  |  | 
| 477 | 10 |  |  |  |  | 27 | $closures | 
| 478 |  |  |  |  |  |  | } | 
| 479 |  |  |  |  |  |  |  | 
| 480 |  |  |  |  |  |  | sub _Closures { | 
| 481 | 1718 |  |  | 1718 |  | 2868 | my($grammar,$core,$closures)=@_; | 
| 482 | 1718 |  |  |  |  | 2574 | my($ruleset)=pack('b'.@{$$grammar{RULES}}); | 
|  | 1718 |  |  |  |  | 5475 |  | 
| 483 |  |  |  |  |  |  |  | 
| 484 | 1718 |  |  |  |  | 3673 | for (@$core) { | 
| 485 | 3895 |  |  |  |  | 8716 | my($ruleno,$pos)=@$_; | 
| 486 | 3895 |  |  |  |  | 6903 | my($rhs)=$$grammar{RULES}[$ruleno][1]; | 
| 487 |  |  |  |  |  |  |  | 
| 488 |  |  |  |  |  |  | $pos < @$rhs | 
| 489 |  |  |  |  |  |  | and exists($closures->{$$rhs[$pos]}) | 
| 490 | 3895 | 100 | 100 |  |  | 17548 | and $ruleset|=$closures->{$$rhs[$pos]}; | 
| 491 |  |  |  |  |  |  | } | 
| 492 | 56069 |  |  |  |  | 101941 | [ @$core, map  { [ $_, 0 ] } | 
| 493 | 1330007 |  |  |  |  | 1749211 | grep { vec($ruleset,$_,1) } | 
| 494 | 1718 |  |  |  |  | 2945 | 0..$#{$$grammar{RULES}} ]; | 
|  | 1718 |  |  |  |  | 18370 |  | 
| 495 |  |  |  |  |  |  | } | 
| 496 |  |  |  |  |  |  |  | 
| 497 |  |  |  |  |  |  | sub _Transitions { | 
| 498 | 1718 |  |  | 1718 |  | 3148 | my($grammar,$cores,$closures,$states,$stateno)=@_; | 
| 499 | 1718 |  |  |  |  | 3787 | my($core)=$$states[$stateno]{'CORE'}; | 
| 500 | 1718 |  |  |  |  | 2440 | my(%transitions); | 
| 501 |  |  |  |  |  |  |  | 
| 502 | 1718 |  |  |  |  | 2638 | for (@{_Closures($grammar,$core,$closures)}) { | 
|  | 1718 |  |  |  |  | 3150 |  | 
| 503 | 59964 |  |  |  |  | 96646 | my($ruleno,$pos)=@$_; | 
| 504 | 59964 |  |  |  |  | 93574 | my($rhs)=$$grammar{RULES}[$ruleno][1]; | 
| 505 |  |  |  |  |  |  |  | 
| 506 |  |  |  |  |  |  | $pos == @$rhs | 
| 507 | 59964 | 100 |  |  |  | 113417 | and do { | 
| 508 | 1187 |  |  |  |  | 1705 | push(@{$$states[$stateno]{ACTIONS}{''}},$ruleno); | 
|  | 1187 |  |  |  |  | 4278 |  | 
| 509 | 1187 |  |  |  |  | 2509 | next; | 
| 510 |  |  |  |  |  |  | }; | 
| 511 | 58777 |  |  |  |  | 75151 | push(@{$transitions{$$rhs[$pos]}},[ $ruleno, $pos+1 ]); | 
|  | 58777 |  |  |  |  | 145947 |  | 
| 512 |  |  |  |  |  |  | } | 
| 513 |  |  |  |  |  |  |  | 
| 514 | 1718 |  |  |  |  | 12581 | for (keys(%transitions)) { | 
| 515 | 23159 |  |  |  |  | 38149 | my($symbol,$core)=($_,$transitions{$_}); | 
| 516 | 58777 |  |  |  |  | 126264 | my($corekey)=join(',',map  { join('.',@$_) } | 
| 517 | 23159 | 50 |  |  |  | 40792 | sort {    $$a[0] <=> $$b[0] | 
|  | 51997 |  |  |  |  | 103737 |  | 
| 518 |  |  |  |  |  |  | or  $$a[1] <=> $$b[1] } | 
| 519 |  |  |  |  |  |  | @$core); | 
| 520 | 23159 |  |  |  |  | 36416 | my($tostateno); | 
| 521 |  |  |  |  |  |  |  | 
| 522 |  |  |  |  |  |  | exists($cores->{$corekey}) | 
| 523 | 23159 | 100 |  |  |  | 53023 | or  do { | 
| 524 | 1708 |  |  |  |  | 3933 | push(@$states,{ 'CORE' => $core }); | 
| 525 | 1708 |  |  |  |  | 4104 | $cores->{$corekey}=$#$states; | 
| 526 |  |  |  |  |  |  | }; | 
| 527 |  |  |  |  |  |  |  | 
| 528 | 23159 |  |  |  |  | 34308 | $tostateno=$cores->{$corekey}; | 
| 529 | 23159 |  |  |  |  | 30124 | push(@{$$states[$tostateno]{FROM}},$stateno); | 
|  | 23159 |  |  |  |  | 44481 |  | 
| 530 |  |  |  |  |  |  |  | 
| 531 |  |  |  |  |  |  | exists($$grammar{TERM}{$_}) | 
| 532 | 23159 | 100 |  |  |  | 48419 | and	do { | 
| 533 | 11824 |  |  |  |  | 23507 | $$states[$stateno]{ACTIONS}{$_} = [ $tostateno ]; | 
| 534 | 11824 |  |  |  |  | 28575 | next; | 
| 535 |  |  |  |  |  |  | }; | 
| 536 | 11335 |  |  |  |  | 29618 | $$states[$stateno]{GOTOS}{$_} = $tostateno; | 
| 537 |  |  |  |  |  |  | } | 
| 538 |  |  |  |  |  |  | } | 
| 539 |  |  |  |  |  |  |  | 
| 540 |  |  |  |  |  |  | sub _LR0 { | 
| 541 | 10 |  |  | 10 |  | 20 | my($grammar)=@_; | 
| 542 | 10 |  |  |  |  | 22 | my($states) = []; | 
| 543 | 10 |  |  |  |  | 20 | my($stateno); | 
| 544 |  |  |  |  |  |  | my($closures);  #$closures={ nterm => ruleset,... } | 
| 545 | 10 |  |  |  |  | 19 | my($cores)={};  # { "itemlist" => stateno, ... } | 
| 546 |  |  |  |  |  |  | # where "itemlist" has the form: | 
| 547 |  |  |  |  |  |  | # "ruleno.pos,ruleno.pos" ordered by ruleno,pos | 
| 548 |  |  |  |  |  |  |  | 
| 549 | 10 |  |  |  |  | 29 | $closures = _SetClosures($grammar); | 
| 550 | 10 |  |  |  |  | 42 | push(@$states,{ 'CORE' => [ [ 0, 0 ] ] }); | 
| 551 | 10 |  |  |  |  | 37 | for($stateno=0;$stateno<@$states;++$stateno) { | 
| 552 | 1718 |  |  |  |  | 4075 | _Transitions($grammar,$cores,$closures,$states,$stateno); | 
| 553 |  |  |  |  |  |  | } | 
| 554 |  |  |  |  |  |  |  | 
| 555 | 10 |  |  |  |  | 691 | $states | 
| 556 |  |  |  |  |  |  | } | 
| 557 |  |  |  |  |  |  |  | 
| 558 |  |  |  |  |  |  | ######################################################### | 
| 559 |  |  |  |  |  |  | # Add Lookahead tokens where needed to make LALR states # | 
| 560 |  |  |  |  |  |  | ######################################################### | 
| 561 |  |  |  |  |  |  | =for nobody | 
| 562 |  |  |  |  |  |  | Compute First sets for non-terminal using the following formula: | 
| 563 |  |  |  |  |  |  |  | 
| 564 |  |  |  |  |  |  | FIRST(A) =      { a in T u { epsilon } | A l a } | 
| 565 |  |  |  |  |  |  | u | 
| 566 |  |  |  |  |  |  | U   { FIRST(B) | B in V and A l B } | 
| 567 |  |  |  |  |  |  |  | 
| 568 |  |  |  |  |  |  | where: | 
| 569 |  |  |  |  |  |  |  | 
| 570 |  |  |  |  |  |  | A l x iff [ A -> X1 X2 .. Xn x alpha ] in P and Xi =>* epsilon, 1 <= i <= n | 
| 571 |  |  |  |  |  |  | =cut | 
| 572 |  |  |  |  |  |  | sub _SetFirst { | 
| 573 | 10 |  |  | 10 |  | 24 | my($grammar,$termlst,$terminx)=@_; | 
| 574 | 10 |  |  |  |  | 22 | my($rel,$first)=( {}, {} ); | 
| 575 |  |  |  |  |  |  |  | 
| 576 | 10 |  |  |  |  | 16 | for my $symbol (keys(%{$$grammar{NTERM}})) { | 
|  | 10 |  |  |  |  | 76 |  | 
| 577 | 270 |  |  |  |  | 734 | $first->{$symbol}=pack('b'.@$termlst); | 
| 578 |  |  |  |  |  |  |  | 
| 579 |  |  |  |  |  |  | RULE: | 
| 580 | 270 |  |  |  |  | 371 | for my $ruleno (@{$$grammar{NTERM}{$symbol}}) { | 
|  | 270 |  |  |  |  | 535 |  | 
| 581 | 888 |  |  |  |  | 1601 | my($rhs)=$$grammar{RULES}[$ruleno][1]; | 
| 582 |  |  |  |  |  |  |  | 
| 583 | 888 |  |  |  |  | 1422 | for (@$rhs) { | 
| 584 |  |  |  |  |  |  | exists($terminx->{$_}) | 
| 585 | 868 | 100 |  |  |  | 1778 | and do { | 
| 586 | 299 |  |  |  |  | 582 | vec($first->{$symbol},$terminx->{$_},1)=1; | 
| 587 | 299 |  |  |  |  | 616 | next RULE; | 
| 588 |  |  |  |  |  |  | }; | 
| 589 | 569 |  |  |  |  | 970 | ++$rel->{$symbol}{$_}; | 
| 590 | 569 | 100 |  |  |  | 1334 | exists($$grammar{NULLABLE}{$_}) | 
| 591 |  |  |  |  |  |  | or  next RULE; | 
| 592 |  |  |  |  |  |  | } | 
| 593 | 47 |  |  |  |  | 400 | vec($first->{$symbol},0,1)=1; | 
| 594 |  |  |  |  |  |  | } | 
| 595 |  |  |  |  |  |  | } | 
| 596 | 10 |  |  |  |  | 60 | _Digraph($rel,$first); | 
| 597 |  |  |  |  |  |  |  | 
| 598 | 10 |  |  |  |  | 35 | $first | 
| 599 |  |  |  |  |  |  | } | 
| 600 |  |  |  |  |  |  |  | 
| 601 |  |  |  |  |  |  | sub _Preds { | 
| 602 | 8974 |  |  | 8974 |  | 14364 | my($states,$stateno,$len)=@_; | 
| 603 | 8974 |  |  |  |  | 12152 | my($queue, $preds); | 
| 604 |  |  |  |  |  |  |  | 
| 605 | 8974 | 100 |  |  |  | 26156 | $len | 
| 606 |  |  |  |  |  |  | or  return [ $stateno ]; | 
| 607 |  |  |  |  |  |  |  | 
| 608 | 1004 |  |  |  |  | 2349 | $queue=[ [ $stateno, $len ] ]; | 
| 609 | 1004 |  |  |  |  | 2429 | while(@$queue) { | 
| 610 | 3862 |  |  |  |  | 5800 | my($pred) = shift(@$queue); | 
| 611 | 3862 |  |  |  |  | 6059 | my($stateno, $len) = @$pred; | 
| 612 |  |  |  |  |  |  |  | 
| 613 |  |  |  |  |  |  | $len == 1 | 
| 614 | 3862 | 100 |  |  |  | 7604 | and do { | 
| 615 | 3169 |  |  |  |  | 4244 | push(@$preds,@{$states->[$stateno]{FROM}}); | 
|  | 3169 |  |  |  |  | 9709 |  | 
| 616 | 3169 |  |  |  |  | 7234 | next; | 
| 617 |  |  |  |  |  |  | }; | 
| 618 |  |  |  |  |  |  |  | 
| 619 | 2858 |  |  |  |  | 6173 | push(@$queue, map { [ $_, $len - 1 ] } | 
| 620 | 693 |  |  |  |  | 1023 | @{$states->[$stateno]{FROM}}); | 
|  | 693 |  |  |  |  | 1699 |  | 
| 621 |  |  |  |  |  |  | } | 
| 622 |  |  |  |  |  |  |  | 
| 623 |  |  |  |  |  |  | # Pass @$preds through a hash to ensure unicity | 
| 624 | 1004 |  |  |  |  | 1456 | [ keys( %{ +{ map { ($_,1) } @$preds } } ) ]; | 
|  | 1004 |  |  |  |  | 1744 |  | 
|  | 34302 |  |  |  |  | 73648 |  | 
| 625 |  |  |  |  |  |  | } | 
| 626 |  |  |  |  |  |  |  | 
| 627 |  |  |  |  |  |  | sub _FirstSfx { | 
| 628 | 1235 |  |  | 1235 |  | 2301 | my($grammar,$firstset,$termlst,$terminx,$ruleno,$pos,$key)=@_; | 
| 629 | 1235 |  |  |  |  | 2703 | my($first)=pack('b'.@$termlst); | 
| 630 | 1235 |  |  |  |  | 2821 | my($rhs)=$$grammar{RULES}[$ruleno][1]; | 
| 631 |  |  |  |  |  |  |  | 
| 632 | 1235 |  |  |  |  | 3070 | for (;$pos < @$rhs;++$pos) { | 
| 633 |  |  |  |  |  |  | exists($terminx->{$$rhs[$pos]}) | 
| 634 | 817 | 100 |  |  |  | 2293 | and do { | 
| 635 | 395 |  |  |  |  | 911 | vec($first,$terminx->{$$rhs[$pos]},1)=1; | 
| 636 | 395 |  |  |  |  | 1325 | return($first); | 
| 637 |  |  |  |  |  |  | }; | 
| 638 | 422 |  |  |  |  | 894 | $first|=$firstset->{$$rhs[$pos]}; | 
| 639 |  |  |  |  |  |  |  | 
| 640 | 422 | 100 |  |  |  | 1084 | vec($first,0,1) | 
| 641 |  |  |  |  |  |  | and vec($first,0,1)=0; | 
| 642 |  |  |  |  |  |  |  | 
| 643 | 422 | 100 |  |  |  | 1639 | exists($$grammar{NULLABLE}{$$rhs[$pos]}) | 
| 644 |  |  |  |  |  |  | or  return($first); | 
| 645 |  |  |  |  |  |  |  | 
| 646 |  |  |  |  |  |  | } | 
| 647 | 597 |  |  |  |  | 1399 | vec($first,0,1)=1; | 
| 648 | 597 |  |  |  |  | 1923 | $first; | 
| 649 |  |  |  |  |  |  | } | 
| 650 |  |  |  |  |  |  |  | 
| 651 |  |  |  |  |  |  | =for noboby | 
| 652 |  |  |  |  |  |  | Compute Follow sets using following formula: | 
| 653 |  |  |  |  |  |  |  | 
| 654 |  |  |  |  |  |  | FOLLOW(p,A) =       READ(p,A) | 
| 655 |  |  |  |  |  |  | u | 
| 656 |  |  |  |  |  |  | U   { FOLLOW(q,B) | (p,A) include (q,B) | 
| 657 |  |  |  |  |  |  |  | 
| 658 |  |  |  |  |  |  | where: | 
| 659 |  |  |  |  |  |  |  | 
| 660 |  |  |  |  |  |  | READ(p,A) = U { FIRST(beta) | [ A -> alpha A . beta ] in KERNEL(GOTO(p,A)) | 
| 661 |  |  |  |  |  |  | } - { epsilon } | 
| 662 |  |  |  |  |  |  |  | 
| 663 |  |  |  |  |  |  | (p,a) include (q,B) iff [ B -> alpha A . beta ] in KERNEL(GOTO(p,A), | 
| 664 |  |  |  |  |  |  | epsilon in FIRST(beta) and | 
| 665 |  |  |  |  |  |  | q in PRED(p,alpha) | 
| 666 |  |  |  |  |  |  | =cut | 
| 667 |  |  |  |  |  |  | sub _ComputeFollows { | 
| 668 | 10 |  |  | 10 |  | 21 | my($grammar,$states,$termlst)=@_; | 
| 669 | 10 |  |  |  |  | 19 | my($firstset,$terminx); | 
| 670 | 10 |  |  |  |  | 27 | my($inconsistent, $rel, $follows, $sfx)= ( {}, {}, {}, {} ); | 
| 671 |  |  |  |  |  |  |  | 
| 672 | 10 |  |  |  |  | 36 | %$terminx= map { ($termlst->[$_],$_) } 0..$#$termlst; | 
|  | 174 |  |  |  |  | 294 |  | 
| 673 |  |  |  |  |  |  |  | 
| 674 | 10 |  |  |  |  | 42 | $firstset=_SetFirst($grammar,$termlst,$terminx); | 
| 675 |  |  |  |  |  |  |  | 
| 676 | 10 |  |  |  |  | 32 | for my $stateno (0..$#$states) { | 
| 677 | 1718 |  |  |  |  | 3021 | my($state)=$$states[$stateno]; | 
| 678 |  |  |  |  |  |  |  | 
| 679 |  |  |  |  |  |  | exists($$state{ACTIONS}{''}) | 
| 680 |  |  |  |  |  |  | and (   @{$$state{ACTIONS}{''}} > 1 | 
| 681 |  |  |  |  |  |  | or keys(%{$$state{ACTIONS}}) > 1 ) | 
| 682 | 1718 | 100 | 100 |  |  | 5298 | and do { | 
|  |  |  | 100 |  |  |  |  | 
| 683 | 397 |  |  |  |  | 1074 | ++$inconsistent->{$stateno}; | 
| 684 |  |  |  |  |  |  |  | 
| 685 | 397 |  |  |  |  | 589 | for my $ruleno (@{$$state{ACTIONS}{''}}) { | 
|  | 397 |  |  |  |  | 879 |  | 
| 686 | 436 |  |  |  |  | 692 | my($lhs,$rhs)=@{$$grammar{RULES}[$ruleno]}[0,1]; | 
|  | 436 |  |  |  |  | 1347 |  | 
| 687 |  |  |  |  |  |  |  | 
| 688 | 436 |  |  |  |  | 810 | for my $predno (@{_Preds($states,$stateno,scalar(@$rhs))}) { | 
|  | 436 |  |  |  |  | 949 |  | 
| 689 | 11975 |  |  |  |  | 24874 | ++$rel->{"$stateno.$ruleno"}{"$predno.$lhs"}; | 
| 690 |  |  |  |  |  |  | } | 
| 691 |  |  |  |  |  |  | } | 
| 692 |  |  |  |  |  |  | }; | 
| 693 |  |  |  |  |  |  |  | 
| 694 |  |  |  |  |  |  | exists($$state{GOTOS}) | 
| 695 | 1718 | 100 |  |  |  | 4213 | or	next; | 
| 696 |  |  |  |  |  |  |  | 
| 697 | 656 |  |  |  |  | 1000 | for my $symbol (keys(%{$$state{GOTOS}})) { | 
|  | 656 |  |  |  |  | 3620 |  | 
| 698 | 11335 |  |  |  |  | 21133 | my($tostate)=$$states[$$state{GOTOS}{$symbol}]; | 
| 699 | 11335 |  |  |  |  | 19056 | my($goto)="$stateno.$symbol"; | 
| 700 |  |  |  |  |  |  |  | 
| 701 | 11335 |  |  |  |  | 33627 | $follows->{$goto}=pack('b'.@$termlst); | 
| 702 |  |  |  |  |  |  |  | 
| 703 | 11335 |  |  |  |  | 15947 | for my $item (@{$$tostate{'CORE'}}) { | 
|  | 11335 |  |  |  |  | 21723 |  | 
| 704 | 39723 |  |  |  |  | 68808 | my($ruleno,$pos)=@$item; | 
| 705 | 39723 |  |  |  |  | 58492 | my($key)="$ruleno.$pos"; | 
| 706 |  |  |  |  |  |  |  | 
| 707 |  |  |  |  |  |  | exists($sfx->{$key}) | 
| 708 | 39723 | 100 |  |  |  | 82748 | or	$sfx->{$key} = _FirstSfx($grammar,$firstset, | 
| 709 |  |  |  |  |  |  | $termlst,$terminx, | 
| 710 |  |  |  |  |  |  | $ruleno,$pos,$key); | 
| 711 |  |  |  |  |  |  |  | 
| 712 | 39723 |  |  |  |  | 64487 | $follows->{$goto}|=$sfx->{$key}; | 
| 713 |  |  |  |  |  |  |  | 
| 714 |  |  |  |  |  |  | vec($follows->{$goto},0,1) | 
| 715 | 39723 | 100 |  |  |  | 86419 | and do { | 
| 716 | 8538 |  |  |  |  | 15527 | my($lhs)=$$grammar{RULES}[$ruleno][0]; | 
| 717 |  |  |  |  |  |  |  | 
| 718 | 8538 |  |  |  |  | 17907 | vec($follows->{$goto},0,1)=0; | 
| 719 |  |  |  |  |  |  |  | 
| 720 | 8538 |  |  |  |  | 14051 | for my $predno (@{_Preds($states,$stateno,$pos-1)}) { | 
|  | 8538 |  |  |  |  | 15834 |  | 
| 721 | 30297 |  |  |  |  | 77522 | ++$rel->{$goto}{"$predno.$lhs"}; | 
| 722 |  |  |  |  |  |  | } | 
| 723 |  |  |  |  |  |  | }; | 
| 724 |  |  |  |  |  |  | } | 
| 725 |  |  |  |  |  |  | } | 
| 726 |  |  |  |  |  |  | } | 
| 727 | 10 |  |  |  |  | 37 | _Digraph($rel,$follows); | 
| 728 |  |  |  |  |  |  |  | 
| 729 | 10 |  |  |  |  | 1610 | ($follows,$inconsistent) | 
| 730 |  |  |  |  |  |  | } | 
| 731 |  |  |  |  |  |  |  | 
| 732 |  |  |  |  |  |  | sub _ComputeLA { | 
| 733 | 10 |  |  | 10 |  | 21 | my($grammar,$states)=@_; | 
| 734 | 10 |  |  |  |  | 18 | my($termlst)= [ '',keys(%{$$grammar{TERM}}) ]; | 
|  | 10 |  |  |  |  | 155 |  | 
| 735 |  |  |  |  |  |  |  | 
| 736 | 10 |  |  |  |  | 42 | my($follows,$inconsistent) = _ComputeFollows($grammar,$states,$termlst); | 
| 737 |  |  |  |  |  |  |  | 
| 738 | 10 |  |  |  |  | 150 | for my $stateno ( keys(%$inconsistent ) ) { | 
| 739 | 397 |  |  |  |  | 947 | my($state)=$$states[$stateno]; | 
| 740 | 397 |  |  |  |  | 523 | my($conflict); | 
| 741 |  |  |  |  |  |  |  | 
| 742 |  |  |  |  |  |  | #NB the sort is VERY important for conflicts resolution order | 
| 743 | 397 |  |  |  |  | 536 | for my $ruleno (sort { $a <=> $b } | 
|  | 41 |  |  |  |  | 107 |  | 
| 744 | 397 |  |  |  |  | 1548 | @{$$state{ACTIONS}{''}}) { | 
| 745 | 436 |  |  |  |  | 1265 | for my $term ( map { $termlst->[$_] } grep { | 
|  | 7755 |  |  |  |  | 11269 |  | 
| 746 | 46056 |  |  |  |  | 69315 | vec($follows->{"$stateno.$ruleno"},$_,1) } | 
| 747 |  |  |  |  |  |  | 0..$#$termlst) { | 
| 748 | 7755 | 100 |  |  |  | 14686 | exists($$state{ACTIONS}{$term}) | 
| 749 |  |  |  |  |  |  | and ++$conflict; | 
| 750 | 7755 |  |  |  |  | 9754 | push(@{$$state{ACTIONS}{$term}},-$ruleno); | 
|  | 7755 |  |  |  |  | 19271 |  | 
| 751 |  |  |  |  |  |  | } | 
| 752 |  |  |  |  |  |  | } | 
| 753 | 397 |  |  |  |  | 816 | delete($$state{ACTIONS}{''}); | 
| 754 |  |  |  |  |  |  | $conflict | 
| 755 | 397 | 100 |  |  |  | 1082 | or  delete($inconsistent->{$stateno}); | 
| 756 |  |  |  |  |  |  | } | 
| 757 |  |  |  |  |  |  |  | 
| 758 |  |  |  |  |  |  | $inconsistent | 
| 759 | 10 |  |  |  |  | 196 | } | 
| 760 |  |  |  |  |  |  |  | 
| 761 |  |  |  |  |  |  | ############################# | 
| 762 |  |  |  |  |  |  | # Solve remaining conflicts # | 
| 763 |  |  |  |  |  |  | ############################# | 
| 764 |  |  |  |  |  |  |  | 
| 765 |  |  |  |  |  |  | sub _SolveConflicts { | 
| 766 | 10 |  |  | 10 |  | 22 | my($grammar,$states,$inconsistent)=@_; | 
| 767 | 10 |  |  |  |  | 21 | my(%rulesprec,$RulePrec); | 
| 768 | 10 |  |  |  |  | 54 | my($conflicts)={    SOLVED  =>  {}, | 
| 769 |  |  |  |  |  |  | FORCED  =>  {   TOTAL   =>  [ 0, 0 ], | 
| 770 |  |  |  |  |  |  | DETAIL  =>  {} | 
| 771 |  |  |  |  |  |  | } | 
| 772 |  |  |  |  |  |  | }; | 
| 773 |  |  |  |  |  |  |  | 
| 774 |  |  |  |  |  |  | $RulePrec = sub { | 
| 775 | 845 |  |  | 845 |  | 1250 | my($ruleno)=@_; | 
| 776 | 845 |  |  |  |  | 1070 | my($rhs,$rprec)=@{$$grammar{RULES}[$ruleno]}[1,2]; | 
|  | 845 |  |  |  |  | 1593 |  | 
| 777 | 845 |  |  |  |  | 1134 | my($lastterm); | 
| 778 |  |  |  |  |  |  |  | 
| 779 | 845 | 100 |  |  |  | 1717 | defined($rprec) | 
| 780 |  |  |  |  |  |  | and return($rprec); | 
| 781 |  |  |  |  |  |  |  | 
| 782 |  |  |  |  |  |  | exists($rulesprec{$ruleno}) | 
| 783 | 612 | 100 |  |  |  | 1483 | and return($rulesprec{$ruleno}); | 
| 784 |  |  |  |  |  |  |  | 
| 785 | 67 |  |  |  |  | 134 | $lastterm=(grep { exists($$grammar{TERM}{$_}) } @$rhs)[-1]; | 
|  | 137 |  |  |  |  | 329 |  | 
| 786 |  |  |  |  |  |  |  | 
| 787 |  |  |  |  |  |  | defined($lastterm) | 
| 788 |  |  |  |  |  |  | and ref($$grammar{TERM}{$lastterm}) | 
| 789 | 67 | 100 | 66 |  |  | 263 | and do { | 
| 790 | 48 |  |  |  |  | 118 | $rulesprec{$ruleno}=$$grammar{TERM}{$lastterm}[1]; | 
| 791 | 48 |  |  |  |  | 99 | return($rulesprec{$ruleno}); | 
| 792 |  |  |  |  |  |  | }; | 
| 793 |  |  |  |  |  |  |  | 
| 794 | 19 |  |  |  |  | 35 | undef; | 
| 795 | 10 |  |  |  |  | 58 | }; | 
| 796 |  |  |  |  |  |  |  | 
| 797 | 10 |  |  |  |  | 67 | for my $stateno (keys(%$inconsistent)) { | 
| 798 | 155 |  |  |  |  | 372 | my($state)=$$states[$stateno]; | 
| 799 | 155 |  |  |  |  | 348 | my($actions)=$$state{ACTIONS}; | 
| 800 | 155 |  |  |  |  | 224 | my($nbsr,$nbrr); | 
| 801 |  |  |  |  |  |  |  | 
| 802 | 155 |  |  |  |  | 1125 | for my $term ( keys(%$actions) ) { | 
| 803 | 5702 |  |  |  |  | 8180 | my($act)=$$actions{$term}; | 
| 804 |  |  |  |  |  |  |  | 
| 805 | 5702 | 100 |  |  |  | 11125 | @$act > 1 | 
| 806 |  |  |  |  |  |  | or  next; | 
| 807 |  |  |  |  |  |  |  | 
| 808 |  |  |  |  |  |  | $$act[0] > 0 | 
| 809 |  |  |  |  |  |  | and ref($$grammar{TERM}{$term}) | 
| 810 | 895 | 100 | 100 |  |  | 3508 | and do { | 
| 811 | 842 |  |  |  |  | 1120 | my($assoc,$tprec)=@{$$grammar{TERM}{$term}}; | 
|  | 842 |  |  |  |  | 1483 |  | 
| 812 | 842 |  |  |  |  | 1188 | my($k,$error); | 
| 813 |  |  |  |  |  |  |  | 
| 814 | 842 |  |  |  |  | 1746 | for ($k=1;$k<@$act;++$k) { | 
| 815 | 845 |  |  |  |  | 1244 | my($ruleno)=-$$act[$k]; | 
| 816 | 845 |  |  |  |  | 1396 | my($rprec)=&$RulePrec($ruleno); | 
| 817 |  |  |  |  |  |  |  | 
| 818 | 845 | 100 |  |  |  | 1660 | defined($rprec) | 
| 819 |  |  |  |  |  |  | or  next; | 
| 820 |  |  |  |  |  |  |  | 
| 821 |  |  |  |  |  |  | (     $tprec > $rprec | 
| 822 |  |  |  |  |  |  | or ( $tprec == $rprec and $assoc eq 'RIGHT')) | 
| 823 | 826 | 100 | 100 |  |  | 2187 | and do { | 
|  |  |  | 100 |  |  |  |  | 
| 824 | 542 |  |  |  |  | 691 | push(@{$$conflicts{SOLVED}{$stateno}}, | 
|  | 542 |  |  |  |  | 1644 |  | 
| 825 |  |  |  |  |  |  | [ $ruleno, $term, 'shift' ]); | 
| 826 | 542 |  |  |  |  | 875 | splice(@$act,$k--,1); | 
| 827 | 542 |  |  |  |  | 1195 | next; | 
| 828 |  |  |  |  |  |  | }; | 
| 829 |  |  |  |  |  |  | (   $tprec < $rprec | 
| 830 |  |  |  |  |  |  | or $assoc eq 'LEFT') | 
| 831 | 284 | 100 | 100 |  |  | 713 | and do { | 
| 832 | 283 |  |  |  |  | 377 | push(@{$$conflicts{SOLVED}{$stateno}}, | 
|  | 283 |  |  |  |  | 819 |  | 
| 833 |  |  |  |  |  |  | [ $ruleno, $term, 'reduce' ]); | 
| 834 |  |  |  |  |  |  | $$act[0] > 0 | 
| 835 | 283 | 50 |  |  |  | 899 | and do { | 
| 836 | 283 |  |  |  |  | 408 | splice(@$act,0,1); | 
| 837 | 283 |  |  |  |  | 365 | --$k; | 
| 838 |  |  |  |  |  |  | }; | 
| 839 | 283 |  |  |  |  | 649 | next; | 
| 840 |  |  |  |  |  |  | }; | 
| 841 | 1 |  |  |  |  | 2 | push(@{$$conflicts{SOLVED}{$stateno}}, | 
|  | 1 |  |  |  |  | 4 |  | 
| 842 |  |  |  |  |  |  | [ $ruleno, $term, 'error' ]); | 
| 843 | 1 |  |  |  |  | 4 | splice(@$act,$k--,1); | 
| 844 |  |  |  |  |  |  | $$act[0] > 0 | 
| 845 | 1 | 50 |  |  |  | 3 | and do { | 
| 846 | 1 |  |  |  |  | 2 | splice(@$act,0,1); | 
| 847 | 1 |  |  |  |  | 2 | ++$error; | 
| 848 | 1 |  |  |  |  | 3 | --$k; | 
| 849 |  |  |  |  |  |  | }; | 
| 850 |  |  |  |  |  |  | } | 
| 851 | 842 | 100 |  |  |  | 1649 | $error | 
| 852 |  |  |  |  |  |  | and unshift(@$act,undef); | 
| 853 |  |  |  |  |  |  | }; | 
| 854 |  |  |  |  |  |  |  | 
| 855 |  |  |  |  |  |  | @$act > 1 | 
| 856 | 895 | 100 |  |  |  | 1856 | and do { | 
| 857 | 72 |  |  |  |  | 113 | $nbrr += @$act - 2; | 
| 858 | 72 | 100 |  |  |  | 126 | ($$act[0] > 0 ? $nbsr : $nbrr) += 1; | 
| 859 | 72 |  |  |  |  | 222 | push(@{$$conflicts{FORCED}{DETAIL}{$stateno}{LIST}}, | 
| 860 | 72 |  |  |  |  | 102 | map { [ $term, $_ ] } splice(@$act,1)); | 
|  | 72 |  |  |  |  | 222 |  | 
| 861 |  |  |  |  |  |  | }; | 
| 862 |  |  |  |  |  |  | } | 
| 863 |  |  |  |  |  |  |  | 
| 864 |  |  |  |  |  |  | $nbsr | 
| 865 | 155 | 100 |  |  |  | 495 | and do { | 
| 866 | 27 |  |  |  |  | 52 | $$conflicts{FORCED}{TOTAL}[0]+=$nbsr; | 
| 867 | 27 |  |  |  |  | 63 | $$conflicts{FORCED}{DETAIL}{$stateno}{TOTAL}[0]+=$nbsr; | 
| 868 |  |  |  |  |  |  | }; | 
| 869 |  |  |  |  |  |  |  | 
| 870 |  |  |  |  |  |  | $nbrr | 
| 871 | 155 | 100 |  |  |  | 355 | and do { | 
| 872 | 11 |  |  |  |  | 21 | $$conflicts{FORCED}{TOTAL}[1]+=$nbrr; | 
| 873 | 11 |  |  |  |  | 26 | $$conflicts{FORCED}{DETAIL}{$stateno}{TOTAL}[1]+=$nbrr; | 
| 874 |  |  |  |  |  |  | }; | 
| 875 |  |  |  |  |  |  |  | 
| 876 |  |  |  |  |  |  | } | 
| 877 |  |  |  |  |  |  |  | 
| 878 |  |  |  |  |  |  | $conflicts | 
| 879 | 10 |  |  |  |  | 115 | } | 
| 880 |  |  |  |  |  |  |  | 
| 881 |  |  |  |  |  |  | ############################### | 
| 882 |  |  |  |  |  |  | # Make default reduce actions # | 
| 883 |  |  |  |  |  |  | ############################### | 
| 884 |  |  |  |  |  |  | sub _SetDefaults { | 
| 885 | 10 |  |  | 10 |  | 20 | my($states)=@_; | 
| 886 |  |  |  |  |  |  |  | 
| 887 | 10 |  |  |  |  | 25 | for my $state (@$states) { | 
| 888 | 1718 |  |  |  |  | 3030 | my($actions)=$$state{ACTIONS}; | 
| 889 | 1718 |  |  |  |  | 2301 | my(%reduces,$default,$nodefault); | 
| 890 |  |  |  |  |  |  |  | 
| 891 |  |  |  |  |  |  | exists($$actions{''}) | 
| 892 | 1718 | 100 |  |  |  | 3793 | and do { | 
| 893 | 751 |  |  |  |  | 1313 | $$actions{''}[0] = -$$actions{''}[0]; | 
| 894 | 751 |  |  |  |  | 1035 | ++$nodefault; | 
| 895 |  |  |  |  |  |  | }; | 
| 896 |  |  |  |  |  |  |  | 
| 897 |  |  |  |  |  |  | #shift error token => no default | 
| 898 |  |  |  |  |  |  | exists($$actions{error}) | 
| 899 | 1718 | 100 | 100 |  |  | 4119 | and $$actions{error}[0] > 0 | 
| 900 |  |  |  |  |  |  | and ++$nodefault; | 
| 901 |  |  |  |  |  |  |  | 
| 902 | 1718 |  |  |  |  | 6710 | for my $term (keys(%$actions)) { | 
| 903 |  |  |  |  |  |  |  | 
| 904 | 19432 |  |  |  |  | 31184 | $$actions{$term}=$$actions{$term}[0]; | 
| 905 |  |  |  |  |  |  |  | 
| 906 |  |  |  |  |  |  | (   not defined($$actions{$term}) | 
| 907 | 19432 | 100 | 100 |  |  | 79688 | or $$actions{$term} > 0 | 
|  |  |  | 100 |  |  |  |  | 
| 908 |  |  |  |  |  |  | or $nodefault) | 
| 909 |  |  |  |  |  |  | and next; | 
| 910 |  |  |  |  |  |  |  | 
| 911 | 7059 |  |  |  |  | 9255 | push(@{$reduces{$$actions{$term}}},$term); | 
|  | 7059 |  |  |  |  | 13852 |  | 
| 912 |  |  |  |  |  |  | } | 
| 913 |  |  |  |  |  |  |  | 
| 914 | 1718 | 100 |  |  |  | 4559 | keys(%reduces) > 0 | 
| 915 |  |  |  |  |  |  | or	next; | 
| 916 |  |  |  |  |  |  |  | 
| 917 | 416 |  |  |  |  | 792 | $default=( map { $$_[0] } | 
| 918 | 41 | 50 |  |  |  | 137 | sort { $$b[1] <=> $$a[1] or $$b[0] <=> $$a[0] } | 
| 919 | 377 |  |  |  |  | 731 | map { [ $_, scalar(@{$reduces{$_}}) ] } | 
|  | 416 |  |  |  |  | 546 |  | 
|  | 416 |  |  |  |  | 1072 |  | 
| 920 |  |  |  |  |  |  | keys(%reduces))[0]; | 
| 921 |  |  |  |  |  |  |  | 
| 922 | 377 |  |  |  |  | 599 | delete(@$actions{ @{$reduces{$default}} }); | 
|  | 377 |  |  |  |  | 1303 |  | 
| 923 | 377 |  |  |  |  | 1110 | $$state{ACTIONS}{''}=$default; | 
| 924 |  |  |  |  |  |  | } | 
| 925 |  |  |  |  |  |  | } | 
| 926 |  |  |  |  |  |  |  | 
| 927 |  |  |  |  |  |  | sub _LALR { | 
| 928 | 10 |  |  | 10 |  | 20 | my($grammar,$states) = @_; | 
| 929 | 10 |  |  |  |  | 19 | my($conflicts,$inconsistent); | 
| 930 |  |  |  |  |  |  |  | 
| 931 | 10 |  |  |  |  | 32 | $inconsistent = _ComputeLA($grammar,$states); | 
| 932 |  |  |  |  |  |  |  | 
| 933 | 10 |  |  |  |  | 35 | $conflicts = _SolveConflicts($grammar,$states,$inconsistent); | 
| 934 | 10 |  |  |  |  | 42 | _SetDefaults($states); | 
| 935 |  |  |  |  |  |  |  | 
| 936 | 10 |  |  |  |  | 79 | $conflicts | 
| 937 |  |  |  |  |  |  | } | 
| 938 |  |  |  |  |  |  |  | 
| 939 |  |  |  |  |  |  |  | 
| 940 |  |  |  |  |  |  | 1; |