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