/** * @override * invoke lazy creation of follow sets */ function follow_set($s) { if (!isset($this->follows)) { $this->follows = $this->build_follow_sets(); } return parent::follow_set($s); }
/** * Start recursive collection of transtions to stations and states * @param Grammar * @param int number of symbols to look ahead, currently only 0 or 1 * @return Void */ function collect_non_deterministic(Grammar $Grammar, $k) { // avoid recursion by testing if already collected if (isset($this->transitions)) { return; } $this->transitions = array(); $this->etransitions = array(); $s = $this->Item->current_symbol(); $la = $this->Item->next_symbol(); #1. accept if end of rule if (is_null($s)) { return; } #2. e-transition to station if symbol is non-terminal if ($Grammar->non_terminal($s)) { // LR(0) has no lookahead if ($k === 0) { $las = array(null); } else { if (is_null($la)) { // use current look ahead $las = array($this->Item->lookahead()); } else { if ($Grammar->is_terminal($la)) { // use terminal as next lookahead $las = array($la); } else { // -- FOLLOW method ------- $las = $Grammar->follow_set($s); // -- FIRST method ------- //$ss = $Item->next_symbols(); //$ss[] = $Item->lookahead(); //$las = $Grammar->first_set( $ss ); } } } // create a station for each lookahead symbol foreach ($las as $la) { $Station = LRStation::make($s, $la); $Station->collect_non_deterministic($Grammar, $k); $this->etransitions[] = $Station; } } #3. Branch advanced item to a new state $nextItem = $this->Item->make_next(); $State = LRState::make($nextItem); $State->collect_non_deterministic($Grammar, $k); $this->transitions[$s] = $State; }