PageRenderTime 47ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/ParserGenerator/PHP/ParserGenerator/Symbol.php

https://gitlab.com/oytunistrator/coffeescript-php
PHP | 288 lines | 78 code | 6 blank | 204 comment | 12 complexity | 45740f2626eb12ff32f8a77307e30b71 MD5 | raw file
  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: Symbol.php 302382 2010-08-17 06:08:09Z jespino $
  46. * @link http://pear.php.net/package/PHP_ParserGenerator
  47. * @since File available since Release 0.1.0
  48. */
  49. /**
  50. * Symbols (terminals and nonterminals) of the grammar are stored in this class
  51. *
  52. * @category PHP
  53. * @package PHP_ParserGenerator
  54. * @author Gregory Beaver <cellog@php.net>
  55. * @copyright 2006 Gregory Beaver
  56. * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
  57. * @version Release: @package_version@
  58. * @link http://pear.php.net/package/PHP_ParserGenerator
  59. * @since Class available since Release 0.1.0
  60. */
  61. class PHP_ParserGenerator_Symbol
  62. {
  63. /**
  64. * Symbols that start with a capital letter like FOO.
  65. *
  66. * These are tokens directly from the lexer
  67. */
  68. const TERMINAL = 1;
  69. /**
  70. * Symbols that start with a lower-case letter like foo.
  71. *
  72. * These are grammar rules like "foo ::= BLAH."
  73. */
  74. const NONTERMINAL = 2;
  75. /**
  76. * Multiple terminal symbols.
  77. *
  78. * These are a grammar rule that consists of several terminals like
  79. * FOO|BAR|BAZ. Note that non-terminals cannot be in a multi-terminal,
  80. * and a multi-terminal acts like a single terminal.
  81. *
  82. * "FOO|BAR FOO|BAZ" is actually two multi-terminals, FOO|BAR and FOO|BAZ.
  83. */
  84. const MULTITERMINAL = 3;
  85. const LEFT = 1;
  86. const RIGHT = 2;
  87. const NONE = 3;
  88. const UNK = 4;
  89. /**
  90. * Name of the symbol
  91. *
  92. * @var string
  93. */
  94. public $name;
  95. /**
  96. * Index of this symbol.
  97. *
  98. * This will ultimately end up representing the symbol in the generated
  99. * parser
  100. * @var int
  101. */
  102. public $index;
  103. /**
  104. * Symbol type
  105. *
  106. * One of PHP_ParserGenerator_Symbol::TERMINAL,
  107. * PHP_ParserGenerator_Symbol::NONTERMINAL or
  108. * PHP_ParserGenerator_Symbol::MULTITERMINAL
  109. * @var int
  110. */
  111. public $type;
  112. /**
  113. * Linked list of rules that use this symbol, if it is a non-terminal.
  114. * @var PHP_ParserGenerator_Rule
  115. */
  116. public $rule;
  117. /**
  118. * Fallback token in case this token doesn't parse
  119. * @var PHP_ParserGenerator_Symbol
  120. */
  121. public $fallback;
  122. /**
  123. * Precendence, if defined.
  124. *
  125. * -1 if no unusual precedence
  126. * @var int
  127. */
  128. public $prec = -1;
  129. /**
  130. * Associativity if precedence is defined.
  131. *
  132. * One of PHP_ParserGenerator_Symbol::LEFT,
  133. * PHP_ParserGenerator_Symbol::RIGHT, PHP_ParserGenerator_Symbol::NONE
  134. * or PHP_ParserGenerator_Symbol::UNK
  135. * @var unknown_type
  136. */
  137. public $assoc;
  138. /**
  139. * First-set for all rules of this symbol
  140. *
  141. * @var array
  142. */
  143. public $firstset;
  144. /**
  145. * True if this symbol is a non-terminal and can generate an empty
  146. * result.
  147. *
  148. * For instance "foo ::= ."
  149. * @var boolean
  150. */
  151. public $lambda;
  152. /**
  153. * Code that executes whenever this symbol is popped from the stack during
  154. * error processing.
  155. *
  156. * @var string|0
  157. */
  158. public $destructor = 0;
  159. /**
  160. * Line number of destructor code
  161. * @var int
  162. */
  163. public $destructorln;
  164. /**
  165. * Unused relic of the C version of Lemon.
  166. *
  167. * The data type of information held by this object. Only used
  168. * if this is a non-terminal
  169. * @var string
  170. */
  171. public $datatype;
  172. /**
  173. * Unused relic of the C version of Lemon.
  174. *
  175. * The data type number. In the parser, the value
  176. * stack is a union. The .yy%d element of this
  177. * union is the correct data type for this object
  178. * @var string
  179. */
  180. public $dtnum;
  181. /**#@+
  182. * The following fields are used by MULTITERMINALs only
  183. */
  184. /**
  185. * Number of terminal symbols in the MULTITERMINAL
  186. *
  187. * This is of course the same as count($this->subsym)
  188. * @var int
  189. */
  190. public $nsubsym;
  191. /**
  192. * Array of terminal symbols in the MULTITERMINAL
  193. * @var array an array of {@link PHP_ParserGenerator_Symbol} objects
  194. */
  195. public $subsym = array();
  196. /**#@-*/
  197. /**
  198. * Singleton storage of symbols
  199. *
  200. * @var array an array of PHP_ParserGenerator_Symbol objects
  201. */
  202. private static $_symbol_table = array();
  203. /**
  204. * Return a pointer to the (terminal or nonterminal) symbol "x".
  205. * Create a new symbol if this is the first time "x" has been seen.
  206. * (this is a singleton)
  207. * @param string
  208. * @return PHP_ParserGenerator_Symbol
  209. */
  210. public static function Symbol_new($x)
  211. {
  212. if (isset(self::$_symbol_table[$x])) {
  213. return self::$_symbol_table[$x];
  214. }
  215. $sp = new PHP_ParserGenerator_Symbol;
  216. $sp->name = $x;
  217. $sp->type = preg_match('/[A-Z]/', $x[0]) ? self::TERMINAL : self::NONTERMINAL;
  218. $sp->rule = 0;
  219. $sp->fallback = 0;
  220. $sp->prec = -1;
  221. $sp->assoc = self::UNK;
  222. $sp->firstset = array();
  223. $sp->lambda = false;
  224. $sp->destructor = 0;
  225. $sp->datatype = 0;
  226. self::$_symbol_table[$sp->name] = $sp;
  227. return $sp;
  228. }
  229. /**
  230. * Return the number of unique symbols
  231. *
  232. * @return int
  233. */
  234. public static function Symbol_count()
  235. {
  236. return count(self::$_symbol_table);
  237. }
  238. public static function Symbol_arrayof()
  239. {
  240. return array_values(self::$_symbol_table);
  241. }
  242. public static function Symbol_find($x)
  243. {
  244. if (isset(self::$_symbol_table[$x])) {
  245. return self::$_symbol_table[$x];
  246. }
  247. return 0;
  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. * Return true if two symbols are the same.
  270. */
  271. public static function same_symbol(PHP_ParserGenerator_Symbol $a, PHP_ParserGenerator_Symbol $b)
  272. {
  273. if ($a === $b) return 1;
  274. if ($a->type != self::MULTITERMINAL) return 0;
  275. if ($b->type != self::MULTITERMINAL) return 0;
  276. if ($a->nsubsym != $b->nsubsym) return 0;
  277. for ($i = 0; $i < $a->nsubsym; $i++) {
  278. if ($a->subsym[$i] != $b->subsym[$i]) return 0;
  279. }
  280. return 1;
  281. }
  282. }