Example #1
0
 /**
  * @return PHP_ParserGenerator_State
  */
 private function getstate()
 {
     /* Extract the sorted basis of the new state.  The basis was constructed
      ** by prior calls to "Configlist_addbasis()". */
     PHP_ParserGenerator_Config::Configlist_sortbasis();
     $bp = PHP_ParserGenerator_Config::Configlist_basis();
     /* Get a state with the same basis */
     $stp = PHP_ParserGenerator_State::State_find($bp);
     if ($stp) {
         /* A state with the same basis already exists!  Copy all the follow-set
          ** propagation links from the state under construction into the
          ** preexisting state, then return a pointer to the preexisting state */
         for ($x = $bp, $y = $stp->bp; $x && $y; $x = $x->bp, $y = $y->bp) {
             PHP_ParserGenerator_PropagationLink::Plink_copy($y->bplp, $x->bplp);
             PHP_ParserGenerator_PropagationLink::Plink_delete($x->fplp);
             $x->fplp = $x->bplp = 0;
         }
         $cfp = PHP_ParserGenerator_Config::Configlist_return();
         PHP_ParserGenerator_Config::Configlist_eat($cfp);
     } else {
         /* This really is a new state.  Construct all the details */
         PHP_ParserGenerator_Config::Configlist_closure($this);
         /* Compute the configuration closure */
         PHP_ParserGenerator_Config::Configlist_sort();
         /* Sort the configuration closure */
         $cfp = PHP_ParserGenerator_Config::Configlist_return();
         /* Get a pointer to the config list */
         $stp = new PHP_ParserGenerator_State();
         /* A new state structure */
         $stp->bp = $bp;
         /* Remember the configuration basis */
         $stp->cfp = $cfp;
         /* Remember the configuration closure */
         $stp->statenum = $this->nstate++;
         /* Every state gets a sequence number */
         $stp->ap = 0;
         /* No actions, yet. */
         PHP_ParserGenerator_State::State_insert($stp, $stp->bp);
         /* Add to the state table */
         // this can't work, recursion is too deep, move it into FindStates()
         //$this->buildshifts($stp);       /* Recursively compute successor states */
         return array($stp);
     }
     return $stp;
 }
Example #2
0
 function main()
 {
     $lem = new PHP_ParserGenerator_Data();
     $this->OptInit($_SERVER['argv']);
     if ($this->version) {
         echo "Lemon version 1.0/PHP_ParserGenerator port version 0.1.5\n";
         exit(0);
     }
     if ($this->OptNArgs($_SERVER['argv']) != 1) {
         echo "Exactly one filename argument is required.\n";
         exit(1);
     }
     $lem->errorcnt = 0;
     /* Initialize the machine */
     $lem->argv0 = $_SERVER['argv'][0];
     $lem->filename = $this->OptArg(0, $_SERVER['argv']);
     $a = pathinfo($lem->filename);
     if (isset($a['extension'])) {
         $ext = '.' . $a['extension'];
         $lem->filenosuffix = substr($lem->filename, 0, strlen($lem->filename) - strlen($ext));
     } else {
         $lem->filenosuffix = $lem->filename;
     }
     $lem->basisflag = $this->basisflag;
     $lem->has_fallback = 0;
     $lem->nconflict = 0;
     $lem->name = $lem->include_code = $lem->include_classcode = $lem->arg = $lem->tokentype = $lem->start = 0;
     $lem->vartype = 0;
     $lem->stacksize = 0;
     $lem->error = $lem->overflow = $lem->failure = $lem->accept = $lem->tokendest = $lem->tokenprefix = $lem->outname = $lem->extracode = 0;
     $lem->vardest = 0;
     $lem->tablesize = 0;
     PHP_ParserGenerator_Symbol::Symbol_new("\$");
     $lem->errsym = PHP_ParserGenerator_Symbol::Symbol_new("error");
     /* Parse the input file */
     $parser = new PHP_ParserGenerator_Parser($this);
     $parser->Parse($lem);
     if ($lem->errorcnt) {
         exit($lem->errorcnt);
     }
     if ($lem->rule === 0) {
         printf("Empty grammar.\n");
         exit(1);
     }
     /* Count and index the symbols of the grammar */
     $lem->nsymbol = PHP_ParserGenerator_Symbol::Symbol_count();
     PHP_ParserGenerator_Symbol::Symbol_new("{default}");
     $lem->symbols = PHP_ParserGenerator_Symbol::Symbol_arrayof();
     for ($i = 0; $i <= $lem->nsymbol; $i++) {
         $lem->symbols[$i]->index = $i;
     }
     usort($lem->symbols, array('PHP_ParserGenerator_Symbol', 'sortSymbols'));
     for ($i = 0; $i <= $lem->nsymbol; $i++) {
         $lem->symbols[$i]->index = $i;
     }
     // find the first lower-case symbol
     for ($i = 1; ord($lem->symbols[$i]->name[0]) < ord('Z'); $i++) {
     }
     $lem->nterminal = $i;
     /* Generate a reprint of the grammar, if requested on the command line */
     if ($this->rpflag) {
         $this->Reprint();
     } else {
         /* Initialize the size for all follow and first sets */
         $this->SetSize($lem->nterminal);
         /* Find the precedence for every production rule (that has one) */
         $lem->FindRulePrecedences();
         /* Compute the lambda-nonterminals and the first-sets for every
          ** nonterminal */
         $lem->FindFirstSets();
         /* Compute all LR(0) states.  Also record follow-set propagation
          ** links so that the follow-set can be computed later */
         $lem->nstate = 0;
         $lem->FindStates();
         $lem->sorted = PHP_ParserGenerator_State::State_arrayof();
         /* Tie up loose ends on the propagation links */
         $lem->FindLinks();
         /* Compute the follow set of every reducible configuration */
         $lem->FindFollowSets();
         /* Compute the action tables */
         $lem->FindActions();
         /* Compress the action tables */
         if ($this->compress === 0) {
             $lem->CompressTables();
         }
         /* Reorder and renumber the states so that states with fewer choices
          ** occur at the end. */
         $lem->ResortStates();
         /* Generate a report of the parser generated.  (the "y.output" file) */
         if (!$this->quiet) {
             $lem->ReportOutput();
         }
         /* Generate the source code for the parser */
         $lem->ReportTable($this->mhflag);
         /* Produce a header file for use by the scanner.  (This step is
          ** omitted if the "-m" option is used because makeheaders will
          ** generate the file for us.) */
         //            if (!$this->mhflag) {
         //                $this->ReportHeader();
         //            }
     }
     if ($this->statistics) {
         printf("Parser statistics: %d terminals, %d nonterminals, %d rules\n", $lem->nterminal, $lem->nsymbol - $lem->nterminal, $lem->nrule);
         printf("                   %d states, %d parser table entries, %d conflicts\n", $lem->nstate, $lem->tablesize, $lem->nconflict);
     }
     if ($lem->nconflict) {
         printf("%d parsing conflicts.\n", $lem->nconflict);
     }
     exit($lem->errorcnt + $lem->nconflict);
     return $lem->errorcnt + $lem->nconflict;
 }