1: <?php
2: /**
3: * Smarty Internal Plugin Configfilelexer
4: *
5: * This is the lexer to break the config file source into tokens
6: *
7: * @package Smarty
8: * @subpackage Config
9: * @author Uwe Tews
10: */
11:
12: /**
13: * Smarty_Internal_Configfilelexer
14: *
15: * This is the config file lexer.
16: * It is generated from the smarty_internal_configfilelexer.plex file
17: *
18: * @package Smarty
19: * @subpackage Compiler
20: * @author Uwe Tews
21: */
22: class Smarty_Internal_Configfilelexer
23: {
24: const START = 1;
25: const VALUE = 2;
26: const NAKED_STRING_VALUE = 3;
27: const COMMENT = 4;
28: const SECTION = 5;
29: const TRIPPLE = 6;
30:
31: /**
32: * Source
33: *
34: * @var string
35: */
36: public $data;
37:
38: /**
39: * Source length
40: *
41: * @var int
42: */
43: public $dataLength = null;
44:
45: /**
46: * byte counter
47: *
48: * @var int
49: */
50: public $counter;
51:
52: /**
53: * token number
54: *
55: * @var int
56: */
57: public $token;
58:
59: /**
60: * token value
61: *
62: * @var string
63: */
64: public $value;
65:
66: /**
67: * current line
68: *
69: * @var int
70: */
71: public $line;
72:
73: /**
74: * state number
75: *
76: * @var int
77: */
78: public $state = 1;
79:
80: /**
81: * Smarty object
82: *
83: * @var Smarty
84: */
85: public $smarty = null;
86:
87: /**
88: * trace file
89: *
90: * @var resource
91: */
92: public $yyTraceFILE;
93:
94: /**
95: * trace prompt
96: *
97: * @var string
98: */
99: public $yyTracePrompt;
100:
101: /**
102: * state names
103: *
104: * @var array
105: */
106: public $state_name = array(
107: 1 => 'START', 2 => 'VALUE', 3 => 'NAKED_STRING_VALUE', 4 => 'COMMENT', 5 => 'SECTION', 6 => 'TRIPPLE'
108: );
109:
110: /**
111: * token names
112: *
113: * @var array
114: */
115: public $smarty_token_names = array( // Text for parser error messages
116: );
117:
118: /**
119: * compiler object
120: *
121: * @var Smarty_Internal_Config_File_Compiler
122: */
123: private $compiler = null;
124:
125: /**
126: * copy of config_booleanize
127: *
128: * @var bool
129: */
130: private $configBooleanize = false;
131:
132: /**
133: * storage for assembled token patterns
134: *
135: * @var string
136: */
137: private $yy_global_pattern1 = null;
138:
139: private $yy_global_pattern2 = null;
140:
141: private $yy_global_pattern3 = null;
142:
143: private $yy_global_pattern4 = null;
144:
145: private $yy_global_pattern5 = null;
146:
147: private $yy_global_pattern6 = null;
148:
149: private $_yy_state = 1;
150:
151: private $_yy_stack = array();
152:
153: /**
154: * constructor
155: *
156: * @param string $data template source
157: * @param Smarty_Internal_Config_File_Compiler $compiler
158: */
159: public function __construct($data, Smarty_Internal_Config_File_Compiler $compiler)
160: {
161: $this->data = $data . "\n"; //now all lines are \n-terminated
162: $this->dataLength = strlen($data);
163: $this->counter = 0;
164: if (preg_match('/^\xEF\xBB\xBF/', $this->data, $match)) {
165: $this->counter += strlen($match[ 0 ]);
166: }
167: $this->line = 1;
168: $this->compiler = $compiler;
169: $this->smarty = $compiler->smarty;
170: $this->configBooleanize = $this->smarty->config_booleanize;
171: }
172:
173: public function replace($input)
174: {
175: return $input;
176: } // end function
177:
178: public function PrintTrace()
179: {
180: $this->yyTraceFILE = fopen('php://output', 'w');
181: $this->yyTracePrompt = '<br>';
182: }
183:
184: public function yylex()
185: {
186: return $this->{'yylex' . $this->_yy_state}();
187: }
188:
189: public function yypushstate($state)
190: {
191: if ($this->yyTraceFILE) {
192: fprintf(
193: $this->yyTraceFILE,
194: "%sState push %s\n",
195: $this->yyTracePrompt,
196: isset($this->state_name[ $this->_yy_state ]) ? $this->state_name[ $this->_yy_state ] : $this->_yy_state
197: );
198: }
199: array_push($this->_yy_stack, $this->_yy_state);
200: $this->_yy_state = $state;
201: if ($this->yyTraceFILE) {
202: fprintf(
203: $this->yyTraceFILE,
204: "%snew State %s\n",
205: $this->yyTracePrompt,
206: isset($this->state_name[ $this->_yy_state ]) ? $this->state_name[ $this->_yy_state ] : $this->_yy_state
207: );
208: }
209: }
210:
211: public function yypopstate()
212: {
213: if ($this->yyTraceFILE) {
214: fprintf(
215: $this->yyTraceFILE,
216: "%sState pop %s\n",
217: $this->yyTracePrompt,
218: isset($this->state_name[ $this->_yy_state ]) ? $this->state_name[ $this->_yy_state ] : $this->_yy_state
219: );
220: }
221: $this->_yy_state = array_pop($this->_yy_stack);
222: if ($this->yyTraceFILE) {
223: fprintf(
224: $this->yyTraceFILE,
225: "%snew State %s\n",
226: $this->yyTracePrompt,
227: isset($this->state_name[ $this->_yy_state ]) ? $this->state_name[ $this->_yy_state ] : $this->_yy_state
228: );
229: }
230: }
231:
232: public function yybegin($state)
233: {
234: $this->_yy_state = $state;
235: if ($this->yyTraceFILE) {
236: fprintf(
237: $this->yyTraceFILE,
238: "%sState set %s\n",
239: $this->yyTracePrompt,
240: isset($this->state_name[ $this->_yy_state ]) ? $this->state_name[ $this->_yy_state ] : $this->_yy_state
241: );
242: }
243: }
244:
245: public function yylex1()
246: {
247: if (!isset($this->yy_global_pattern1)) {
248: $this->yy_global_pattern1 =
249: $this->replace("/\G(#|;)|\G(\\[)|\G(\\])|\G(=)|\G([ \t\r]+)|\G(\n)|\G([0-9]*[a-zA-Z_]\\w*)|\G([\S\s])/isS");
250: }
251: if (!isset($this->dataLength)) {
252: $this->dataLength = strlen($this->data);
253: }
254: if ($this->counter >= $this->dataLength) {
255: return false; // end of input
256: }
257: do {
258: if (preg_match($this->yy_global_pattern1, $this->data, $yymatches, 0, $this->counter)) {
259: if (!isset($yymatches[ 0 ][ 1 ])) {
260: $yymatches = preg_grep("/(.|\s)+/", $yymatches);
261: } else {
262: $yymatches = array_filter($yymatches);
263: }
264: if (empty($yymatches)) {
265: throw new Exception('Error: lexing failed because a rule matched' .
266: ' an empty string. Input "' . substr(
267: $this->data,
268: $this->counter,
269: 5
270: ) . '... state START');
271: }
272: next($yymatches); // skip global match
273: $this->token = key($yymatches); // token number
274: $this->value = current($yymatches); // token value
275: $r = $this->{'yy_r1_' . $this->token}();
276: if ($r === null) {
277: $this->counter += strlen($this->value);
278: $this->line += substr_count($this->value, "\n");
279: // accept this token
280: return true;
281: } elseif ($r === true) {
282: // we have changed state
283: // process this token in the new state
284: return $this->yylex();
285: } elseif ($r === false) {
286: $this->counter += strlen($this->value);
287: $this->line += substr_count($this->value, "\n");
288: if ($this->counter >= $this->dataLength) {
289: return false; // end of input
290: }
291: // skip this token
292: continue;
293: }
294: } else {
295: throw new Exception('Unexpected input at line' . $this->line .
296: ': ' . $this->data[ $this->counter ]);
297: }
298: break;
299: } while (true);
300: }
301:
302: public function yy_r1_1()
303: {
304: $this->token = Smarty_Internal_Configfileparser::TPC_COMMENTSTART;
305: $this->yypushstate(self::COMMENT);
306: }
307:
308: public function yy_r1_2()
309: {
310: $this->token = Smarty_Internal_Configfileparser::TPC_OPENB;
311: $this->yypushstate(self::SECTION);
312: }
313:
314: public function yy_r1_3()
315: {
316: $this->token = Smarty_Internal_Configfileparser::TPC_CLOSEB;
317: }
318:
319: public function yy_r1_4()
320: {
321: $this->token = Smarty_Internal_Configfileparser::TPC_EQUAL;
322: $this->yypushstate(self::VALUE);
323: } // end function
324:
325: public function yy_r1_5()
326: {
327: return false;
328: }
329:
330: public function yy_r1_6()
331: {
332: $this->token = Smarty_Internal_Configfileparser::TPC_NEWLINE;
333: }
334:
335: public function yy_r1_7()
336: {
337: $this->token = Smarty_Internal_Configfileparser::TPC_ID;
338: }
339:
340: public function yy_r1_8()
341: {
342: $this->token = Smarty_Internal_Configfileparser::TPC_OTHER;
343: }
344:
345: public function yylex2()
346: {
347: if (!isset($this->yy_global_pattern2)) {
348: $this->yy_global_pattern2 =
349: $this->replace("/\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)/isS");
350: }
351: if (!isset($this->dataLength)) {
352: $this->dataLength = strlen($this->data);
353: }
354: if ($this->counter >= $this->dataLength) {
355: return false; // end of input
356: }
357: do {
358: if (preg_match($this->yy_global_pattern2, $this->data, $yymatches, 0, $this->counter)) {
359: if (!isset($yymatches[ 0 ][ 1 ])) {
360: $yymatches = preg_grep("/(.|\s)+/", $yymatches);
361: } else {
362: $yymatches = array_filter($yymatches);
363: }
364: if (empty($yymatches)) {
365: throw new Exception('Error: lexing failed because a rule matched' .
366: ' an empty string. Input "' . substr(
367: $this->data,
368: $this->counter,
369: 5
370: ) . '... state VALUE');
371: }
372: next($yymatches); // skip global match
373: $this->token = key($yymatches); // token number
374: $this->value = current($yymatches); // token value
375: $r = $this->{'yy_r2_' . $this->token}();
376: if ($r === null) {
377: $this->counter += strlen($this->value);
378: $this->line += substr_count($this->value, "\n");
379: // accept this token
380: return true;
381: } elseif ($r === true) {
382: // we have changed state
383: // process this token in the new state
384: return $this->yylex();
385: } elseif ($r === false) {
386: $this->counter += strlen($this->value);
387: $this->line += substr_count($this->value, "\n");
388: if ($this->counter >= $this->dataLength) {
389: return false; // end of input
390: }
391: // skip this token
392: continue;
393: }
394: } else {
395: throw new Exception('Unexpected input at line' . $this->line .
396: ': ' . $this->data[ $this->counter ]);
397: }
398: break;
399: } while (true);
400: }
401:
402: public function yy_r2_1()
403: {
404: return false;
405: }
406:
407: public function yy_r2_2()
408: {
409: $this->token = Smarty_Internal_Configfileparser::TPC_FLOAT;
410: $this->yypopstate();
411: }
412:
413: public function yy_r2_3()
414: {
415: $this->token = Smarty_Internal_Configfileparser::TPC_INT;
416: $this->yypopstate();
417: }
418:
419: public function yy_r2_4()
420: {
421: $this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_QUOTES;
422: $this->yypushstate(self::TRIPPLE);
423: }
424:
425: public function yy_r2_5()
426: {
427: $this->token = Smarty_Internal_Configfileparser::TPC_SINGLE_QUOTED_STRING;
428: $this->yypopstate();
429: }
430:
431: public function yy_r2_6()
432: {
433: $this->token = Smarty_Internal_Configfileparser::TPC_DOUBLE_QUOTED_STRING;
434: $this->yypopstate();
435: } // end function
436:
437: public function yy_r2_7()
438: {
439: if (!$this->configBooleanize ||
440: !in_array(strtolower($this->value), array('true', 'false', 'on', 'off', 'yes', 'no'))) {
441: $this->yypopstate();
442: $this->yypushstate(self::NAKED_STRING_VALUE);
443: return true; //reprocess in new state
444: } else {
445: $this->token = Smarty_Internal_Configfileparser::TPC_BOOL;
446: $this->yypopstate();
447: }
448: }
449:
450: public function yy_r2_8()
451: {
452: $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
453: $this->yypopstate();
454: }
455:
456: public function yy_r2_9()
457: {
458: $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
459: $this->value = '';
460: $this->yypopstate();
461: } // end function
462:
463: public function yylex3()
464: {
465: if (!isset($this->yy_global_pattern3)) {
466: $this->yy_global_pattern3 = $this->replace("/\G([^\n]+?(?=[ \t\r]*\n))/isS");
467: }
468: if (!isset($this->dataLength)) {
469: $this->dataLength = strlen($this->data);
470: }
471: if ($this->counter >= $this->dataLength) {
472: return false; // end of input
473: }
474: do {
475: if (preg_match($this->yy_global_pattern3, $this->data, $yymatches, 0, $this->counter)) {
476: if (!isset($yymatches[ 0 ][ 1 ])) {
477: $yymatches = preg_grep("/(.|\s)+/", $yymatches);
478: } else {
479: $yymatches = array_filter($yymatches);
480: }
481: if (empty($yymatches)) {
482: throw new Exception('Error: lexing failed because a rule matched' .
483: ' an empty string. Input "' . substr(
484: $this->data,
485: $this->counter,
486: 5
487: ) . '... state NAKED_STRING_VALUE');
488: }
489: next($yymatches); // skip global match
490: $this->token = key($yymatches); // token number
491: $this->value = current($yymatches); // token value
492: $r = $this->{'yy_r3_' . $this->token}();
493: if ($r === null) {
494: $this->counter += strlen($this->value);
495: $this->line += substr_count($this->value, "\n");
496: // accept this token
497: return true;
498: } elseif ($r === true) {
499: // we have changed state
500: // process this token in the new state
501: return $this->yylex();
502: } elseif ($r === false) {
503: $this->counter += strlen($this->value);
504: $this->line += substr_count($this->value, "\n");
505: if ($this->counter >= $this->dataLength) {
506: return false; // end of input
507: }
508: // skip this token
509: continue;
510: }
511: } else {
512: throw new Exception('Unexpected input at line' . $this->line .
513: ': ' . $this->data[ $this->counter ]);
514: }
515: break;
516: } while (true);
517: }
518:
519: public function yy_r3_1()
520: {
521: $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
522: $this->yypopstate();
523: }
524:
525: public function yylex4()
526: {
527: if (!isset($this->yy_global_pattern4)) {
528: $this->yy_global_pattern4 = $this->replace("/\G([ \t\r]+)|\G([^\n]+?(?=[ \t\r]*\n))|\G(\n)/isS");
529: }
530: if (!isset($this->dataLength)) {
531: $this->dataLength = strlen($this->data);
532: }
533: if ($this->counter >= $this->dataLength) {
534: return false; // end of input
535: }
536: do {
537: if (preg_match($this->yy_global_pattern4, $this->data, $yymatches, 0, $this->counter)) {
538: if (!isset($yymatches[ 0 ][ 1 ])) {
539: $yymatches = preg_grep("/(.|\s)+/", $yymatches);
540: } else {
541: $yymatches = array_filter($yymatches);
542: }
543: if (empty($yymatches)) {
544: throw new Exception('Error: lexing failed because a rule matched' .
545: ' an empty string. Input "' . substr(
546: $this->data,
547: $this->counter,
548: 5
549: ) . '... state COMMENT');
550: }
551: next($yymatches); // skip global match
552: $this->token = key($yymatches); // token number
553: $this->value = current($yymatches); // token value
554: $r = $this->{'yy_r4_' . $this->token}();
555: if ($r === null) {
556: $this->counter += strlen($this->value);
557: $this->line += substr_count($this->value, "\n");
558: // accept this token
559: return true;
560: } elseif ($r === true) {
561: // we have changed state
562: // process this token in the new state
563: return $this->yylex();
564: } elseif ($r === false) {
565: $this->counter += strlen($this->value);
566: $this->line += substr_count($this->value, "\n");
567: if ($this->counter >= $this->dataLength) {
568: return false; // end of input
569: }
570: // skip this token
571: continue;
572: }
573: } else {
574: throw new Exception('Unexpected input at line' . $this->line .
575: ': ' . $this->data[ $this->counter ]);
576: }
577: break;
578: } while (true);
579: }
580:
581: public function yy_r4_1()
582: {
583: return false;
584: }
585:
586: public function yy_r4_2()
587: {
588: $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
589: } // end function
590:
591: public function yy_r4_3()
592: {
593: $this->token = Smarty_Internal_Configfileparser::TPC_NEWLINE;
594: $this->yypopstate();
595: }
596:
597: public function yylex5()
598: {
599: if (!isset($this->yy_global_pattern5)) {
600: $this->yy_global_pattern5 = $this->replace("/\G(\\.)|\G(.*?(?=[\.=[\]\r\n]))/isS");
601: }
602: if (!isset($this->dataLength)) {
603: $this->dataLength = strlen($this->data);
604: }
605: if ($this->counter >= $this->dataLength) {
606: return false; // end of input
607: }
608: do {
609: if (preg_match($this->yy_global_pattern5, $this->data, $yymatches, 0, $this->counter)) {
610: if (!isset($yymatches[ 0 ][ 1 ])) {
611: $yymatches = preg_grep("/(.|\s)+/", $yymatches);
612: } else {
613: $yymatches = array_filter($yymatches);
614: }
615: if (empty($yymatches)) {
616: throw new Exception('Error: lexing failed because a rule matched' .
617: ' an empty string. Input "' . substr(
618: $this->data,
619: $this->counter,
620: 5
621: ) . '... state SECTION');
622: }
623: next($yymatches); // skip global match
624: $this->token = key($yymatches); // token number
625: $this->value = current($yymatches); // token value
626: $r = $this->{'yy_r5_' . $this->token}();
627: if ($r === null) {
628: $this->counter += strlen($this->value);
629: $this->line += substr_count($this->value, "\n");
630: // accept this token
631: return true;
632: } elseif ($r === true) {
633: // we have changed state
634: // process this token in the new state
635: return $this->yylex();
636: } elseif ($r === false) {
637: $this->counter += strlen($this->value);
638: $this->line += substr_count($this->value, "\n");
639: if ($this->counter >= $this->dataLength) {
640: return false; // end of input
641: }
642: // skip this token
643: continue;
644: }
645: } else {
646: throw new Exception('Unexpected input at line' . $this->line .
647: ': ' . $this->data[ $this->counter ]);
648: }
649: break;
650: } while (true);
651: }
652:
653: public function yy_r5_1()
654: {
655: $this->token = Smarty_Internal_Configfileparser::TPC_DOT;
656: }
657:
658: public function yy_r5_2()
659: {
660: $this->token = Smarty_Internal_Configfileparser::TPC_SECTION;
661: $this->yypopstate();
662: } // end function
663:
664: public function yylex6()
665: {
666: if (!isset($this->yy_global_pattern6)) {
667: $this->yy_global_pattern6 = $this->replace("/\G(\"\"\"(?=[ \t\r]*[\n#;]))|\G([\S\s])/isS");
668: }
669: if (!isset($this->dataLength)) {
670: $this->dataLength = strlen($this->data);
671: }
672: if ($this->counter >= $this->dataLength) {
673: return false; // end of input
674: }
675: do {
676: if (preg_match($this->yy_global_pattern6, $this->data, $yymatches, 0, $this->counter)) {
677: if (!isset($yymatches[ 0 ][ 1 ])) {
678: $yymatches = preg_grep("/(.|\s)+/", $yymatches);
679: } else {
680: $yymatches = array_filter($yymatches);
681: }
682: if (empty($yymatches)) {
683: throw new Exception('Error: lexing failed because a rule matched' .
684: ' an empty string. Input "' . substr(
685: $this->data,
686: $this->counter,
687: 5
688: ) . '... state TRIPPLE');
689: }
690: next($yymatches); // skip global match
691: $this->token = key($yymatches); // token number
692: $this->value = current($yymatches); // token value
693: $r = $this->{'yy_r6_' . $this->token}();
694: if ($r === null) {
695: $this->counter += strlen($this->value);
696: $this->line += substr_count($this->value, "\n");
697: // accept this token
698: return true;
699: } elseif ($r === true) {
700: // we have changed state
701: // process this token in the new state
702: return $this->yylex();
703: } elseif ($r === false) {
704: $this->counter += strlen($this->value);
705: $this->line += substr_count($this->value, "\n");
706: if ($this->counter >= $this->dataLength) {
707: return false; // end of input
708: }
709: // skip this token
710: continue;
711: }
712: } else {
713: throw new Exception('Unexpected input at line' . $this->line .
714: ': ' . $this->data[ $this->counter ]);
715: }
716: break;
717: } while (true);
718: }
719:
720: public function yy_r6_1()
721: {
722: $this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_QUOTES_END;
723: $this->yypopstate();
724: $this->yypushstate(self::START);
725: }
726:
727: public function yy_r6_2()
728: {
729: $to = strlen($this->data);
730: preg_match("/\"\"\"[ \t\r]*[\n#;]/", $this->data, $match, PREG_OFFSET_CAPTURE, $this->counter);
731: if (isset($match[ 0 ][ 1 ])) {
732: $to = $match[ 0 ][ 1 ];
733: } else {
734: $this->compiler->trigger_config_file_error('missing or misspelled literal closing tag');
735: }
736: $this->value = substr($this->data, $this->counter, $to - $this->counter);
737: $this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_TEXT;
738: }
739: }
740: