phpDocumentor PHP_ParserGenerator
[ class tree: PHP_ParserGenerator ] [ index: PHP_ParserGenerator ] [ all elements ]

Source for file Symbol.php

Documentation is available at Symbol.php

  1. <?php
  2. /**
  3.  * PHP_ParserGenerator, a php 5 parser generator.
  4.  * 
  5.  * This is a direct port of the Lemon parser generator, found at
  6.  * {@link http://www.hwaci.com/sw/lemon/}
  7.  *
  8.  * PHP version 5
  9.  *
  10.  * LICENSE:
  11.  * 
  12.  * Copyright (c) 2006, Gregory Beaver <cellog@php.net>
  13.  * All rights reserved.
  14.  *
  15.  * Redistribution and use in source and binary forms, with or without
  16.  * modification, are permitted provided that the following conditions
  17.  * are met:
  18.  *
  19.  *     * Redistributions of source code must retain the above copyright
  20.  *       notice, this list of conditions and the following disclaimer.
  21.  *     * Redistributions in binary form must reproduce the above copyright
  22.  *       notice, this list of conditions and the following disclaimer in
  23.  *       the documentation and/or other materials provided with the distribution.
  24.  *     * Neither the name of the PHP_ParserGenerator nor the names of its
  25.  *       contributors may be used to endorse or promote products derived
  26.  *       from this software without specific prior written permission.
  27.  *
  28.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  29.  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  30.  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  31.  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  32.  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  33.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  34.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  35.  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  36.  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  37.  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  38.  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  39.  *
  40.  * @category   php
  41.  * @package    PHP_ParserGenerator
  42.  * @author     Gregory Beaver <cellog@php.net>
  43.  * @copyright  2006 Gregory Beaver
  44.  * @license    http://www.opensource.org/licenses/bsd-license.php New BSD License
  45.  * @version    CVS: $Id$
  46.  * @since      File available since Release 0.1.0
  47.  */
  48. /**
  49.  * Symbols (terminals and nonterminals) of the grammar are stored in this class
  50.  * 
  51.  * @package    PHP_ParserGenerator
  52.  * @author     Gregory Beaver <cellog@php.net>
  53.  * @copyright  2006 Gregory Beaver
  54.  * @license    http://www.opensource.org/licenses/bsd-license.php New BSD License
  55.  * @version    @package_version@
  56.  * @since      Class available since Release 0.1.0
  57.  */
  58. {
  59.     /**
  60.      * Symbols that start with a capital letter like FOO.
  61.      *
  62.      * These are tokens directly from the lexer
  63.      */
  64.     const TERMINAL 1;
  65.     /**
  66.      * Symbols that start with a lower-case letter like foo.
  67.      *
  68.      * These are grammar rules like "foo ::= BLAH."
  69.      */
  70.     const NONTERMINAL 2;
  71.     /**
  72.      * Multiple terminal symbols.
  73.      *
  74.      * These are a grammar rule that consists of several terminals like
  75.      * FOO|BAR|BAZ.  Note that non-terminals cannot be in a multi-terminal,
  76.      * and a multi-terminal acts like a single terminal.
  77.      * 
  78.      * "FOO|BAR FOO|BAZ" is actually two multi-terminals, FOO|BAR and FOO|BAZ.
  79.      */
  80.     const MULTITERMINAL 3;
  81.     
  82.     const LEFT 1;
  83.     const RIGHT 2;
  84.     const NONE 3;
  85.     const UNK 4;
  86.     /**
  87.      * Name of the symbol
  88.      *
  89.      * @var string 
  90.      */
  91.     public $name;
  92.     /**
  93.      * Index of this symbol.
  94.      *
  95.      * This will ultimately end up representing the symbol in the generated
  96.      * parser
  97.      * @var int 
  98.      */
  99.     public $index;
  100.     /**
  101.      * Symbol type
  102.      *
  103.      * One of PHP_ParserGenerator_Symbol::TERMINAL,
  104.      * PHP_ParserGenerator_Symbol::NONTERMINAL or
  105.      * PHP_ParserGenerator_Symbol::MULTITERMINAL
  106.      * @var int 
  107.      */
  108.     public $type;
  109.     /**
  110.      * Linked list of rules that use this symbol, if it is a non-terminal.
  111.      * @var PHP_ParserGenerator_Rule 
  112.      */
  113.     public $rule;
  114.     /**
  115.      * Fallback token in case this token doesn't parse
  116.      * @var PHP_ParserGenerator_Symbol 
  117.      */
  118.     public $fallback;
  119.     /**
  120.      * Precendence, if defined.
  121.      *
  122.      * -1 if no unusual precedence
  123.      * @var int 
  124.      */
  125.     public $prec = -1;
  126.     /**
  127.      * Associativity if precedence is defined.
  128.      *
  129.      * One of PHP_ParserGenerator_Symbol::LEFT,
  130.      * PHP_ParserGenerator_Symbol::RIGHT, PHP_ParserGenerator_Symbol::NONE
  131.      * or PHP_ParserGenerator_Symbol::UNK
  132.      * @var unknown_type 
  133.      */
  134.     public $assoc;
  135.     /**
  136.      * First-set for all rules of this symbol
  137.      *
  138.      * @var array 
  139.      */
  140.     public $firstset;
  141.     /**
  142.      * True if this symbol is a non-terminal and can generate an empty
  143.      * result.
  144.      * 
  145.      * For instance "foo ::= ."
  146.      * @var boolean 
  147.      */
  148.     public $lambda;
  149.     /**
  150.      * Code that executes whenever this symbol is popped from the stack during
  151.      * error processing.
  152.      *
  153.      * @var string|0
  154.      */
  155.     public $destructor = 0;
  156.     /**
  157.      * Line number of destructor code
  158.      * @var int 
  159.      */
  160.     public $destructorln;
  161.     /**
  162.      * Unused relic of the C version of Lemon.
  163.      *
  164.      * The data type of information held by this object.  Only used
  165.      * if this is a non-terminal
  166.      * @var string 
  167.      */
  168.     public $datatype;
  169.     /**
  170.      * Unused relic of the C version of Lemon.
  171.      *
  172.      * The data type number.  In the parser, the value
  173.      * stack is a union.  The .yy%d element of this
  174.      * union is the correct data type for this object
  175.      * @var string 
  176.      */
  177.     public $dtnum;
  178.     /**#@+
  179.      * The following fields are used by MULTITERMINALs only
  180.      */
  181.     /**
  182.      * Number of terminal symbols in the MULTITERMINAL
  183.      * 
  184.      * This is of course the same as count($this->subsym)
  185.      * @var int 
  186.      */
  187.     public $nsubsym;
  188.     /**
  189.      * Array of terminal symbols in the MULTITERMINAL
  190.      * @var array an array of {@link PHP_ParserGenerator_Symbol} objects
  191.      */
  192.     public $subsym = array();
  193.     /**#@-*/
  194.     /**
  195.      * Singleton storage of symbols
  196.      *
  197.      * @var array an array of PHP_ParserGenerator_Symbol objects
  198.      */
  199.     private static $symbol_table array();
  200.     /**
  201.      * Return a pointer to the (terminal or nonterminal) symbol "x".
  202.      * Create a new symbol if this is the first time "x" has been seen.
  203.      * (this is a singleton)
  204.      * @param string 
  205.      * @return PHP_ParserGenerator_Symbol 
  206.      */
  207.     public static function Symbol_new($x)
  208.     {
  209.         if (isset(self::$symbol_table[$x])) {
  210.             return self::$symbol_table[$x];
  211.         }
  212.         $sp new PHP_ParserGenerator_Symbol;
  213.         $sp->name $x;
  214.         $sp->type preg_match('/[A-Z]/'$x[0]self::TERMINAL self::NONTERMINAL;
  215.         $sp->rule 0;
  216.         $sp->fallback 0;
  217.         $sp->prec = -1;
  218.         $sp->assoc self::UNK;
  219.         $sp->firstset array();
  220.         $sp->lambda false;
  221.         $sp->destructor 0;
  222.         $sp->datatype 0;
  223.         self::$symbol_table[$sp->name$sp;
  224.         return $sp;
  225.     }
  226.  
  227.     /**
  228.      * Return the number of unique symbols
  229.      * @return int 
  230.      */
  231.     public static function Symbol_count()
  232.     {
  233.         return count(self::$symbol_table);
  234.     }
  235.  
  236.     public static function Symbol_arrayof()
  237.     {
  238.         return array_values(self::$symbol_table);
  239.     }
  240.  
  241.     public static function Symbol_find($x)
  242.     {
  243.         if (isset(self::$symbol_table[$x])) {
  244.             return self::$symbol_table[$x];
  245.         }
  246.         return 0;
  247.     }
  248.  
  249.     /**
  250.      * Sort function helper for symbols
  251.      * 
  252.      * Symbols that begin with upper case letters (terminals or tokens)
  253.      * must sort before symbols that begin with lower case letters
  254.      * (non-terminals).  Other than that, the order does not matter.
  255.      * 
  256.      * We find experimentally that leaving the symbols in their original
  257.      * order (the order they appeared in the grammar file) gives the
  258.      * smallest parser tables in SQLite.
  259.      * @param PHP_ParserGenerator_Symbol 
  260.      * @param PHP_ParserGenerator_Symbol 
  261.      */
  262.     public static function sortSymbols($a$b)
  263.     {
  264.         $i1 $a->index 10000000*(ord($a->name[0]ord('Z'));
  265.         $i2 $b->index 10000000*(ord($b->name[0]ord('Z'));
  266.         return $i1 $i2;
  267.     }
  268.  
  269.     /**
  270.      * Return true if two symbols are the same.
  271.      */
  272.     public static function same_symbol(PHP_ParserGenerator_Symbol $aPHP_ParserGenerator_Symbol $b)
  273.     {
  274.         if ($a === $breturn 1;
  275.         if ($a->type != self::MULTITERMINALreturn 0;
  276.         if ($b->type != self::MULTITERMINALreturn 0;
  277.         if ($a->nsubsym != $b->nsubsymreturn 0;
  278.         for ($i 0$i $a->nsubsym$i++{
  279.             if ($a->subsym[$i!= $b->subsym[$i]return 0;
  280.         }
  281.         return 1;
  282.     }
  283. }

Documentation generated on Sun, 02 Jul 2006 09:11:12 -0400 by phpDocumentor 1.3.0