lib/ParserGenerator/PHP/ParserGenerator/Config.php
static function Configlist_closure(PHP_ParserGenerator_Data $lemp)
    {
        for ($cfp = self::$current; $cfp; $cfp = $cfp->next) {
            $rp = $cfp->rp;
            $dot = $cfp->dot;
            if ($dot >= $rp->nrhs) {
                continue;
            }
            $sp = $rp->rhs[$dot];
            if ($sp->type == PHP_ParserGenerator_Symbol::NONTERMINAL) {
                if ($sp->rule === 0 && $sp !== $lemp->errsym) {
                    PHP_ParserGenerator::ErrorMsg($lemp->filename, $rp->line,
                        "Nonterminal \"%s\" has no rules.", $sp->name);
                    $lemp->errorcnt++;
                }
                for ($newrp = $sp->rule; $newrp; $newrp = $newrp->nextlhs) {
                    $newcfp = self::Configlist_add($newrp, 0);
                    for ($i = $dot + 1; $i < $rp->nrhs; $i++) {
                        $xsp = $rp->rhs[$i];
                        if ($xsp->type == PHP_ParserGenerator_Symbol::TERMINAL) {
                            $newcfp->fws[$xsp->index] = 1;
                            break;
                        } elseif ($xsp->type == PHP_ParserGenerator_Symbol::MULTITERMINAL) {
                            for ($k = 0; $k < $xsp->nsubsym; $k++) {
                                $newcfp->fws[$xsp->subsym[$k]->index] = 1;
                            }
                            break;
                        } else {
                            $a = array_diff_key($xsp->firstset, $newcfp->fws);
                            $newcfp->fws += $a;
                            if ($xsp->lambda === false) {
                                break;
                            }
                        }
                    }
                    if ($i == $rp->nrhs) {
                        PHP_ParserGenerator_PropagationLink::Plink_add($cfp->fplp, $newcfp);
                    }
                }
            }
        }
    }
static function Configlist_closure(PHP_ParserGenerator_Data $lemp)
    {
        for ($cfp = self::$current; $cfp; $cfp = $cfp->next) {
            $rp = $cfp->rp;
            $dot = $cfp->dot;
            if ($dot >= $rp->nrhs) {
                continue;
            }
            $sp = $rp->rhs[$dot];
            if ($sp->type == PHP_ParserGenerator_Symbol::NONTERMINAL) {
                if ($sp->rule === 0 && $sp !== $lemp->errsym) {
                    PHP_ParserGenerator::ErrorMsg($lemp->filename, $rp->line,
                        "Nonterminal \"%s\" has no rules.", $sp->name);
                    $lemp->errorcnt++;
                }
                for ($newrp = $sp->rule; $newrp; $newrp = $newrp->nextlhs) {
                    $newcfp = self::Configlist_add($newrp, 0);
                    for ($i = $dot + 1; $i < $rp->nrhs; $i++) {
                        $xsp = $rp->rhs[$i];
                        if ($xsp->type == PHP_ParserGenerator_Symbol::TERMINAL) {
                            $newcfp->fws[$xsp->index] = 1;
                            break;
                        } elseif ($xsp->type == PHP_ParserGenerator_Symbol::MULTITERMINAL) {
                            for ($k = 0; $k < $xsp->nsubsym; $k++) {
                                $newcfp->fws[$xsp->subsym[$k]->index] = 1;
                            }
                            break;
                        } else {
                            $a = array_diff_key($xsp->firstset, $newcfp->fws);
                            $newcfp->fws += $a;
                            if ($xsp->lambda === false) {
                                break;
                            }
                        }
                    }
                    if ($i == $rp->nrhs) {
                        PHP_ParserGenerator_PropagationLink::Plink_add($cfp->fplp, $newcfp);
                    }
                }
            }
        }
    }
static function Configlist_closure ( PHP_ParserGenerator_Data $ lemp ) { for ( $ cfp = self :: $ current ; $ cfp ; $ cfp = $ cfp -> next ) { $ rp = $ cfp -> rp ; $ dot = $ cfp -> dot ; if ( $ dot >= $ rp -> nrhs ) { continue ; } $ sp = $ rp -> rhs [ $ dot ] ; if ( $ sp -> type == PHP_ParserGenerator_Symbol :: NONTERMINAL ) { if ( $ sp -> rule === 0 && $ sp !== $ lemp -> errsym ) { PHP_ParserGenerator :: ErrorMsg ( $ lemp -> filename , $ rp -> line , "Nonterminal \"%s\" has no rules." , $ sp -> name ) ; $ lemp -> errorcnt ++ ; } for ( $ newrp = $ sp -> rule ; $ newrp ; $ newrp = $ newrp -> nextlhs ) { $ newcfp = self :: Configlist_add ( $ newrp , 0 ) ; for ( $ i = $ dot + 1 ; $ i < $ rp -> nrhs ; $ i ++ ) { $ xsp = $ rp -> rhs [ $ i ] ; if ( $ xsp -> type == PHP_ParserGenerator_Symbol :: TERMINAL ) { $ newcfp -> fws [ $ xsp -> index ] = 1 ; break ; } elseif ( $ xsp -> type == PHP_ParserGenerator_Symbol :: MULTITERMINAL ) { for ( $ k = 0 ; $ k < $ xsp -> nsubsym ; $ k ++ ) { $ newcfp -> fws [ $ xsp -> subsym [ $ k ] -> index ] = 1 ; } break ; } else { $ a = array_diff_key ( $ xsp -> firstset , $ newcfp -> fws ) ; $ newcfp -> fws += $ a ; if ( $ xsp -> lambda === false ) { break ; } } } if ( $ i == $ rp -> nrhs ) { PHP_ParserGenerator_PropagationLink :: Plink_add ( $ cfp -> fplp , $ newcfp ) ; } } } } }
Compute the closure of the configuration list.

This calculates all of the possible continuations of
each configuration, ensuring that each state accounts
for every configuration that could arrive at that state.
Compute the closure of the configuration list .