smarty_internal_configfilelexer.php 17 KB

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