1: <?php
2: /**
3: * Smarty Internal Plugin Smarty Template Compiler Base
4: * This file contains the basic classes and methods for compiling Smarty templates with lexer/parser
5: *
6: * @package Smarty
7: * @subpackage Compiler
8: * @author Uwe Tews
9: */
10:
11: /**
12: * @ignore
13: */
14: include 'smarty_internal_parsetree.php';
15:
16: /**
17: * Class SmartyTemplateCompiler
18: *
19: * @package Smarty
20: * @subpackage Compiler
21: */
22: class Smarty_Internal_SmartyTemplateCompiler extends Smarty_Internal_TemplateCompilerBase
23: {
24: /**
25: * Lexer class name
26: *
27: * @var string
28: */
29: public $lexer_class;
30:
31: /**
32: * Parser class name
33: *
34: * @var string
35: */
36: public $parser_class;
37:
38: /**
39: * Lexer object
40: *
41: * @var object
42: */
43: public $lex;
44:
45: /**
46: * Parser object
47: *
48: * @var object
49: */
50: public $parser;
51:
52: /**
53: * Smarty object
54: *
55: * @var object
56: */
57: public $smarty;
58:
59: /**
60: * array of vars which can be compiled in local scope
61: *
62: * @var array
63: */
64: public $local_var = array();
65:
66: /**
67: * Initialize compiler
68: *
69: * @param string $lexer_class class name
70: * @param string $parser_class class name
71: * @param Smarty $smarty global instance
72: */
73: public function __construct($lexer_class, $parser_class, $smarty)
74: {
75: $this->smarty = $smarty;
76: parent::__construct();
77: // get required plugins
78: $this->lexer_class = $lexer_class;
79: $this->parser_class = $parser_class;
80: }
81:
82: /**
83: * method to compile a Smarty template
84: *
85: * @param mixed $_content template source
86: *
87: * @return bool true if compiling succeeded, false if it failed
88: */
89: protected function doCompile($_content)
90: {
91: /* here is where the compiling takes place. Smarty
92: tags in the templates are replaces with PHP code,
93: then written to compiled files. */
94: // init the lexer/parser to compile the template
95: $this->lex = new $this->lexer_class($_content, $this);
96: $this->parser = new $this->parser_class($this->lex, $this);
97: if ($this->inheritance_child) {
98: // start state on child templates
99: $this->lex->yypushstate(Smarty_Internal_Templatelexer::CHILDBODY);
100: }
101: if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
102: $mbEncoding = mb_internal_encoding();
103: mb_internal_encoding('ASCII');
104: } else {
105: $mbEncoding = null;
106: }
107:
108: if ($this->smarty->_parserdebug) {
109: $this->parser->PrintTrace();
110: $this->lex->PrintTrace();
111: }
112: // get tokens from lexer and parse them
113: while ($this->lex->yylex() && !$this->abort_and_recompile) {
114: if ($this->smarty->_parserdebug) {
115: echo "<pre>Line {$this->lex->line} Parsing {$this->parser->yyTokenName[$this->lex->token]} Token " .
116: htmlentities($this->lex->value) . "</pre>";
117: }
118: $this->parser->doParse($this->lex->token, $this->lex->value);
119: }
120:
121: if ($this->abort_and_recompile) {
122: // exit here on abort
123: return false;
124: }
125: // finish parsing process
126: $this->parser->doParse(0, 0);
127: if ($mbEncoding) {
128: mb_internal_encoding($mbEncoding);
129: }
130: // check for unclosed tags
131: if (count($this->_tag_stack) > 0) {
132: // get stacked info
133: list($openTag, $_data) = array_pop($this->_tag_stack);
134: $this->trigger_template_error("unclosed {$this->smarty->left_delimiter}" . $openTag . "{$this->smarty->right_delimiter} tag");
135: }
136: // return compiled code
137: // return str_replace(array("? >\n<?php","? ><?php"), array('',''), $this->parser->retvalue);
138: return $this->parser->retvalue;
139: }
140: }
141: