smarty_internal_configfilelexer.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  1. <?php
  2. /**
  3. * Smarty Internal Plugin Configfilelexer
  4. *
  5. * This is the lexer to break the config file source into tokens
  6. * @package Smarty
  7. * @subpackage Config
  8. * @author Uwe Tews
  9. */
  10. /**
  11. * Smarty Internal Plugin Configfilelexer
  12. */
  13. class Smarty_Internal_Configfilelexer
  14. {
  15. public $data;
  16. public $counter;
  17. public $token;
  18. public $value;
  19. public $node;
  20. public $line;
  21. private $state = 1;
  22. public $smarty_token_names = array ( // Text for parser error messages
  23. );
  24. function __construct($data, $smarty)
  25. {
  26. // set instance object
  27. self::instance($this);
  28. $this->data = $data . "\n"; //now all lines are \n-terminated
  29. $this->counter = 0;
  30. $this->line = 1;
  31. $this->smarty = $smarty;
  32. $this->mbstring_overload = ini_get('mbstring.func_overload') & 2;
  33. }
  34. public static function &instance($new_instance = null)
  35. {
  36. static $instance = null;
  37. if (isset($new_instance) && is_object($new_instance))
  38. $instance = $new_instance;
  39. return $instance;
  40. }
  41. private $_yy_state = 1;
  42. private $_yy_stack = array();
  43. function yylex()
  44. {
  45. return $this->{'yylex' . $this->_yy_state}();
  46. }
  47. function yypushstate($state)
  48. {
  49. array_push($this->_yy_stack, $this->_yy_state);
  50. $this->_yy_state = $state;
  51. }
  52. function yypopstate()
  53. {
  54. $this->_yy_state = array_pop($this->_yy_stack);
  55. }
  56. function yybegin($state)
  57. {
  58. $this->_yy_state = $state;
  59. }
  60. function yylex1()
  61. {
  62. $tokenMap = array (
  63. 1 => 0,
  64. 2 => 0,
  65. 3 => 0,
  66. 4 => 0,
  67. 5 => 0,
  68. 6 => 0,
  69. 7 => 0,
  70. );
  71. if ($this->counter >= strlen($this->data)) {
  72. return false; // end of input
  73. }
  74. $yy_global_pattern = "/\G(#|;)|\G(\\[)|\G(\\])|\G(=)|\G([ \t\r]+)|\G(\n)|\G([0-9]*[a-zA-Z_]\\w*)/iS";
  75. do {
  76. if ($this->mbstring_overload ? preg_match($yy_global_pattern, substr($this->data, $this->counter), $yymatches) : preg_match($yy_global_pattern,$this->data, $yymatches, null, $this->counter)) {
  77. $yysubmatches = $yymatches;
  78. $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
  79. if (!count($yymatches)) {
  80. throw new Exception('Error: lexing failed because a rule matched' .
  81. ' an empty string. Input "' . substr($this->data,
  82. $this->counter, 5) . '... state START');
  83. }
  84. next($yymatches); // skip global match
  85. $this->token = key($yymatches); // token number
  86. if ($tokenMap[$this->token]) {
  87. // extract sub-patterns for passing to lex function
  88. $yysubmatches = array_slice($yysubmatches, $this->token + 1,
  89. $tokenMap[$this->token]);
  90. } else {
  91. $yysubmatches = array();
  92. }
  93. $this->value = current($yymatches); // token value
  94. $r = $this->{'yy_r1_' . $this->token}($yysubmatches);
  95. if ($r === null) {
  96. $this->counter += strlen($this->value);
  97. $this->line += substr_count($this->value, "\n");
  98. // accept this token
  99. return true;
  100. } elseif ($r === true) {
  101. // we have changed state
  102. // process this token in the new state
  103. return $this->yylex();
  104. } elseif ($r === false) {
  105. $this->counter += strlen($this->value);
  106. $this->line += substr_count($this->value, "\n");
  107. if ($this->counter >= strlen($this->data)) {
  108. return false; // end of input
  109. }
  110. // skip this token
  111. continue;
  112. } } else {
  113. throw new Exception('Unexpected input at line' . $this->line .
  114. ': ' . $this->data[$this->counter]);
  115. }
  116. break;
  117. } while (true);
  118. } // end function
  119. const START = 1;
  120. function yy_r1_1($yy_subpatterns)
  121. {
  122. $this->token = Smarty_Internal_Configfileparser::TPC_COMMENTSTART;
  123. $this->yypushstate(self::COMMENT);
  124. }
  125. function yy_r1_2($yy_subpatterns)
  126. {
  127. $this->token = Smarty_Internal_Configfileparser::TPC_OPENB;
  128. $this->yypushstate(self::SECTION);
  129. }
  130. function yy_r1_3($yy_subpatterns)
  131. {
  132. $this->token = Smarty_Internal_Configfileparser::TPC_CLOSEB;
  133. }
  134. function yy_r1_4($yy_subpatterns)
  135. {
  136. $this->token = Smarty_Internal_Configfileparser::TPC_EQUAL;
  137. $this->yypushstate(self::VALUE);
  138. }
  139. function yy_r1_5($yy_subpatterns)
  140. {
  141. return false;
  142. }
  143. function yy_r1_6($yy_subpatterns)
  144. {
  145. $this->token = Smarty_Internal_Configfileparser::TPC_NEWLINE;
  146. }
  147. function yy_r1_7($yy_subpatterns)
  148. {
  149. $this->token = Smarty_Internal_Configfileparser::TPC_ID;
  150. }
  151. function yylex2()
  152. {
  153. $tokenMap = array (
  154. 1 => 0,
  155. 2 => 0,
  156. 3 => 0,
  157. 4 => 0,
  158. 5 => 0,
  159. 6 => 0,
  160. 7 => 0,
  161. 8 => 0,
  162. 9 => 0,
  163. );
  164. if ($this->counter >= strlen($this->data)) {
  165. return false; // end of input
  166. }
  167. $yy_global_pattern = "/\G([ \t\r]+)|\G(\\d+\\.\\d+(?=[ \t\r]*[\n#;]))|\G(\\d+(?=[ \t\r]*[\n#;]))|\G(\"\"\")|\G('[^'\\\\]*(?:\\\\.[^'\\\\]*)*'(?=[ \t\r]*[\n#;]))|\G(\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\"(?=[ \t\r]*[\n#;]))|\G([a-zA-Z]+(?=[ \t\r]*[\n#;]))|\G([^\n]+?(?=[ \t\r]*\n))|\G(\n)/iS";
  168. do {
  169. if ($this->mbstring_overload ? preg_match($yy_global_pattern, substr($this->data, $this->counter), $yymatches) : preg_match($yy_global_pattern,$this->data, $yymatches, null, $this->counter)) {
  170. $yysubmatches = $yymatches;
  171. $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
  172. if (!count($yymatches)) {
  173. throw new Exception('Error: lexing failed because a rule matched' .
  174. ' an empty string. Input "' . substr($this->data,
  175. $this->counter, 5) . '... state VALUE');
  176. }
  177. next($yymatches); // skip global match
  178. $this->token = key($yymatches); // token number
  179. if ($tokenMap[$this->token]) {
  180. // extract sub-patterns for passing to lex function
  181. $yysubmatches = array_slice($yysubmatches, $this->token + 1,
  182. $tokenMap[$this->token]);
  183. } else {
  184. $yysubmatches = array();
  185. }
  186. $this->value = current($yymatches); // token value
  187. $r = $this->{'yy_r2_' . $this->token}($yysubmatches);
  188. if ($r === null) {
  189. $this->counter += strlen($this->value);
  190. $this->line += substr_count($this->value, "\n");
  191. // accept this token
  192. return true;
  193. } elseif ($r === true) {
  194. // we have changed state
  195. // process this token in the new state
  196. return $this->yylex();
  197. } elseif ($r === false) {
  198. $this->counter += strlen($this->value);
  199. $this->line += substr_count($this->value, "\n");
  200. if ($this->counter >= strlen($this->data)) {
  201. return false; // end of input
  202. }
  203. // skip this token
  204. continue;
  205. } } else {
  206. throw new Exception('Unexpected input at line' . $this->line .
  207. ': ' . $this->data[$this->counter]);
  208. }
  209. break;
  210. } while (true);
  211. } // end function
  212. const VALUE = 2;
  213. function yy_r2_1($yy_subpatterns)
  214. {
  215. return false;
  216. }
  217. function yy_r2_2($yy_subpatterns)
  218. {
  219. $this->token = Smarty_Internal_Configfileparser::TPC_FLOAT;
  220. $this->yypopstate();
  221. }
  222. function yy_r2_3($yy_subpatterns)
  223. {
  224. $this->token = Smarty_Internal_Configfileparser::TPC_INT;
  225. $this->yypopstate();
  226. }
  227. function yy_r2_4($yy_subpatterns)
  228. {
  229. $this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_QUOTES;
  230. $this->yypushstate(self::TRIPPLE);
  231. }
  232. function yy_r2_5($yy_subpatterns)
  233. {
  234. $this->token = Smarty_Internal_Configfileparser::TPC_SINGLE_QUOTED_STRING;
  235. $this->yypopstate();
  236. }
  237. function yy_r2_6($yy_subpatterns)
  238. {
  239. $this->token = Smarty_Internal_Configfileparser::TPC_DOUBLE_QUOTED_STRING;
  240. $this->yypopstate();
  241. }
  242. function yy_r2_7($yy_subpatterns)
  243. {
  244. if (!$this->smarty->config_booleanize || !in_array(strtolower($this->value), Array("true", "false", "on", "off", "yes", "no")) ) {
  245. $this->yypopstate();
  246. $this->yypushstate(self::NAKED_STRING_VALUE);
  247. return true; //reprocess in new state
  248. } else {
  249. $this->token = Smarty_Internal_Configfileparser::TPC_BOOL;
  250. $this->yypopstate();
  251. }
  252. }
  253. function yy_r2_8($yy_subpatterns)
  254. {
  255. $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
  256. $this->yypopstate();
  257. }
  258. function yy_r2_9($yy_subpatterns)
  259. {
  260. $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
  261. $this->value = "";
  262. $this->yypopstate();
  263. }
  264. function yylex3()
  265. {
  266. $tokenMap = array (
  267. 1 => 0,
  268. );
  269. if ($this->counter >= strlen($this->data)) {
  270. return false; // end of input
  271. }
  272. $yy_global_pattern = "/\G([^\n]+?(?=[ \t\r]*\n))/iS";
  273. do {
  274. if ($this->mbstring_overload ? preg_match($yy_global_pattern, substr($this->data, $this->counter), $yymatches) : preg_match($yy_global_pattern,$this->data, $yymatches, null, $this->counter)) {
  275. $yysubmatches = $yymatches;
  276. $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
  277. if (!count($yymatches)) {
  278. throw new Exception('Error: lexing failed because a rule matched' .
  279. ' an empty string. Input "' . substr($this->data,
  280. $this->counter, 5) . '... state NAKED_STRING_VALUE');
  281. }
  282. next($yymatches); // skip global match
  283. $this->token = key($yymatches); // token number
  284. if ($tokenMap[$this->token]) {
  285. // extract sub-patterns for passing to lex function
  286. $yysubmatches = array_slice($yysubmatches, $this->token + 1,
  287. $tokenMap[$this->token]);
  288. } else {
  289. $yysubmatches = array();
  290. }
  291. $this->value = current($yymatches); // token value
  292. $r = $this->{'yy_r3_' . $this->token}($yysubmatches);
  293. if ($r === null) {
  294. $this->counter += strlen($this->value);
  295. $this->line += substr_count($this->value, "\n");
  296. // accept this token
  297. return true;
  298. } elseif ($r === true) {
  299. // we have changed state
  300. // process this token in the new state
  301. return $this->yylex();
  302. } elseif ($r === false) {
  303. $this->counter += strlen($this->value);
  304. $this->line += substr_count($this->value, "\n");
  305. if ($this->counter >= strlen($this->data)) {
  306. return false; // end of input
  307. }
  308. // skip this token
  309. continue;
  310. } } else {
  311. throw new Exception('Unexpected input at line' . $this->line .
  312. ': ' . $this->data[$this->counter]);
  313. }
  314. break;
  315. } while (true);
  316. } // end function
  317. const NAKED_STRING_VALUE = 3;
  318. function yy_r3_1($yy_subpatterns)
  319. {
  320. $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
  321. $this->yypopstate();
  322. }
  323. function yylex4()
  324. {
  325. $tokenMap = array (
  326. 1 => 0,
  327. 2 => 0,
  328. 3 => 0,
  329. );
  330. if ($this->counter >= strlen($this->data)) {
  331. return false; // end of input
  332. }
  333. $yy_global_pattern = "/\G([ \t\r]+)|\G([^\n]+?(?=[ \t\r]*\n))|\G(\n)/iS";
  334. do {
  335. if ($this->mbstring_overload ? preg_match($yy_global_pattern, substr($this->data, $this->counter), $yymatches) : preg_match($yy_global_pattern,$this->data, $yymatches, null, $this->counter)) {
  336. $yysubmatches = $yymatches;
  337. $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
  338. if (!count($yymatches)) {
  339. throw new Exception('Error: lexing failed because a rule matched' .
  340. ' an empty string. Input "' . substr($this->data,
  341. $this->counter, 5) . '... state COMMENT');
  342. }
  343. next($yymatches); // skip global match
  344. $this->token = key($yymatches); // token number
  345. if ($tokenMap[$this->token]) {
  346. // extract sub-patterns for passing to lex function
  347. $yysubmatches = array_slice($yysubmatches, $this->token + 1,
  348. $tokenMap[$this->token]);
  349. } else {
  350. $yysubmatches = array();
  351. }
  352. $this->value = current($yymatches); // token value
  353. $r = $this->{'yy_r4_' . $this->token}($yysubmatches);
  354. if ($r === null) {
  355. $this->counter += strlen($this->value);
  356. $this->line += substr_count($this->value, "\n");
  357. // accept this token
  358. return true;
  359. } elseif ($r === true) {
  360. // we have changed state
  361. // process this token in the new state
  362. return $this->yylex();
  363. } elseif ($r === false) {
  364. $this->counter += strlen($this->value);
  365. $this->line += substr_count($this->value, "\n");
  366. if ($this->counter >= strlen($this->data)) {
  367. return false; // end of input
  368. }
  369. // skip this token
  370. continue;
  371. } } else {
  372. throw new Exception('Unexpected input at line' . $this->line .
  373. ': ' . $this->data[$this->counter]);
  374. }
  375. break;
  376. } while (true);
  377. } // end function
  378. const COMMENT = 4;
  379. function yy_r4_1($yy_subpatterns)
  380. {
  381. return false;
  382. }
  383. function yy_r4_2($yy_subpatterns)
  384. {
  385. $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
  386. }
  387. function yy_r4_3($yy_subpatterns)
  388. {
  389. $this->token = Smarty_Internal_Configfileparser::TPC_NEWLINE;
  390. $this->yypopstate();
  391. }
  392. function yylex5()
  393. {
  394. $tokenMap = array (
  395. 1 => 0,
  396. 2 => 0,
  397. );
  398. if ($this->counter >= strlen($this->data)) {
  399. return false; // end of input
  400. }
  401. $yy_global_pattern = "/\G(\\.)|\G(.*?(?=[\.=[\]\r\n]))/iS";
  402. do {
  403. if ($this->mbstring_overload ? preg_match($yy_global_pattern, substr($this->data, $this->counter), $yymatches) : preg_match($yy_global_pattern,$this->data, $yymatches, null, $this->counter)) {
  404. $yysubmatches = $yymatches;
  405. $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
  406. if (!count($yymatches)) {
  407. throw new Exception('Error: lexing failed because a rule matched' .
  408. ' an empty string. Input "' . substr($this->data,
  409. $this->counter, 5) . '... state SECTION');
  410. }
  411. next($yymatches); // skip global match
  412. $this->token = key($yymatches); // token number
  413. if ($tokenMap[$this->token]) {
  414. // extract sub-patterns for passing to lex function
  415. $yysubmatches = array_slice($yysubmatches, $this->token + 1,
  416. $tokenMap[$this->token]);
  417. } else {
  418. $yysubmatches = array();
  419. }
  420. $this->value = current($yymatches); // token value
  421. $r = $this->{'yy_r5_' . $this->token}($yysubmatches);
  422. if ($r === null) {
  423. $this->counter += strlen($this->value);
  424. $this->line += substr_count($this->value, "\n");
  425. // accept this token
  426. return true;
  427. } elseif ($r === true) {
  428. // we have changed state
  429. // process this token in the new state
  430. return $this->yylex();
  431. } elseif ($r === false) {
  432. $this->counter += strlen($this->value);
  433. $this->line += substr_count($this->value, "\n");
  434. if ($this->counter >= strlen($this->data)) {
  435. return false; // end of input
  436. }
  437. // skip this token
  438. continue;
  439. } } else {
  440. throw new Exception('Unexpected input at line' . $this->line .
  441. ': ' . $this->data[$this->counter]);
  442. }
  443. break;
  444. } while (true);
  445. } // end function
  446. const SECTION = 5;
  447. function yy_r5_1($yy_subpatterns)
  448. {
  449. $this->token = Smarty_Internal_Configfileparser::TPC_DOT;
  450. }
  451. function yy_r5_2($yy_subpatterns)
  452. {
  453. $this->token = Smarty_Internal_Configfileparser::TPC_SECTION;
  454. $this->yypopstate();
  455. }
  456. function yylex6()
  457. {
  458. $tokenMap = array (
  459. 1 => 0,
  460. 2 => 0,
  461. 3 => 2,
  462. );
  463. if ($this->counter >= strlen($this->data)) {
  464. return false; // end of input
  465. }
  466. $yy_global_pattern = "/\G(\"\"\"(?=[ \t\r]*[\n#;]))|\G([ \t\r]*\n)|\G(([\S\s]*?)(?=([ \t\r]*\n|\"\"\")))/iS";
  467. do {
  468. if ($this->mbstring_overload ? preg_match($yy_global_pattern, substr($this->data, $this->counter), $yymatches) : preg_match($yy_global_pattern,$this->data, $yymatches, null, $this->counter)) {
  469. $yysubmatches = $yymatches;
  470. $yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
  471. if (!count($yymatches)) {
  472. throw new Exception('Error: lexing failed because a rule matched' .
  473. ' an empty string. Input "' . substr($this->data,
  474. $this->counter, 5) . '... state TRIPPLE');
  475. }
  476. next($yymatches); // skip global match
  477. $this->token = key($yymatches); // token number
  478. if ($tokenMap[$this->token]) {
  479. // extract sub-patterns for passing to lex function
  480. $yysubmatches = array_slice($yysubmatches, $this->token + 1,
  481. $tokenMap[$this->token]);
  482. } else {
  483. $yysubmatches = array();
  484. }
  485. $this->value = current($yymatches); // token value
  486. $r = $this->{'yy_r6_' . $this->token}($yysubmatches);
  487. if ($r === null) {
  488. $this->counter += strlen($this->value);
  489. $this->line += substr_count($this->value, "\n");
  490. // accept this token
  491. return true;
  492. } elseif ($r === true) {
  493. // we have changed state
  494. // process this token in the new state
  495. return $this->yylex();
  496. } elseif ($r === false) {
  497. $this->counter += strlen($this->value);
  498. $this->line += substr_count($this->value, "\n");
  499. if ($this->counter >= strlen($this->data)) {
  500. return false; // end of input
  501. }
  502. // skip this token
  503. continue;
  504. } } else {
  505. throw new Exception('Unexpected input at line' . $this->line .
  506. ': ' . $this->data[$this->counter]);
  507. }
  508. break;
  509. } while (true);
  510. } // end function
  511. const TRIPPLE = 6;
  512. function yy_r6_1($yy_subpatterns)
  513. {
  514. $this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_QUOTES_END;
  515. $this->yypopstate();
  516. $this->yypushstate(self::START);
  517. }
  518. function yy_r6_2($yy_subpatterns)
  519. {
  520. $this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_CONTENT;
  521. }
  522. function yy_r6_3($yy_subpatterns)
  523. {
  524. $this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_CONTENT;
  525. }
  526. }
  527. ?>