summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lexer/smarty_internal_configfilelexer.plex305
-rw-r--r--lexer/smarty_internal_configfileparser.y363
-rw-r--r--lexer/smarty_internal_templatelexer.plex900
-rw-r--r--lexer/smarty_internal_templateparser.y1432
4 files changed, 3000 insertions, 0 deletions
diff --git a/lexer/smarty_internal_configfilelexer.plex b/lexer/smarty_internal_configfilelexer.plex
new file mode 100644
index 00000000..1c001c81
--- /dev/null
+++ b/lexer/smarty_internal_configfilelexer.plex
@@ -0,0 +1,305 @@
+<?php
+/**
+* Smarty Internal Plugin Configfilelexer
+*
+* This is the lexer to break the config file source into tokens
+* @package Smarty
+* @subpackage Config
+* @author Uwe Tews
+*/
+/**
+* Smarty_Internal_Configfilelexer
+*
+* This is the config file lexer.
+* It is generated from the smarty_internal_configfilelexer.plex file
+*
+* @package Smarty
+* @subpackage Compiler
+* @author Uwe Tews
+*/
+class Smarty_Internal_Configfilelexer
+{
+ /**
+ * Source
+ *
+ * @var string
+ */
+ public $data;
+ /**
+ * byte counter
+ *
+ * @var int
+ */
+ public $counter;
+ /**
+ * token number
+ *
+ * @var int
+ */
+ public $token;
+ /**
+ * token value
+ *
+ * @var string
+ */
+ public $value;
+ /**
+ * current line
+ *
+ * @var int
+ */
+ public $line;
+ /**
+ * state number
+ *
+ * @var int
+ */
+ public $state = 1;
+ /**
+ * Smarty object
+ *
+ * @var Smarty
+ */
+ public $smarty = null;
+ /**
+ * compiler object
+ *
+ * @var Smarty_Internal_Config_File_Compiler
+ */
+ private $compiler = null;
+ /**
+ * copy of config_booleanize
+ *
+ * @var bool
+ */
+ private $configBooleanize = false;
+ /**
+ * trace file
+ *
+ * @var resource
+ */
+ public $yyTraceFILE;
+ /**
+ * trace prompt
+ *
+ * @var string
+ */
+ public $yyTracePrompt;
+ /**
+ * state names
+ *
+ * @var array
+ */
+ public $state_name = array(1 => 'START', 2 => 'VALUE', 3 => 'NAKED_STRING_VALUE', 4 => 'COMMENT', 5 => 'SECTION', 6 => 'TRIPPLE');
+ /**
+ * token names
+ *
+ * @var array
+ */
+ public $smarty_token_names = array( // Text for parser error messages
+ );
+
+ /**
+ * constructor
+ *
+ * @param string $data template source
+ * @param Smarty_Internal_Config_File_Compiler $compiler
+ */
+ function __construct($data, Smarty_Internal_Config_File_Compiler $compiler)
+ {
+ // set instance object
+ self::instance($this);
+ $this->data = $data . "\n"; //now all lines are \n-terminated
+ $this->counter = 0;
+ if (preg_match('/^\xEF\xBB\xBF/', $this->data, $match)) {
+ $this->counter += strlen($match[0]);
+ }
+ $this->line = 1;
+ $this->compiler = $compiler;
+ $this->smarty = $compiler->smarty;
+ $this->configBooleanize = $compiler->smarty->config_booleanize;
+ }
+
+ public static function &instance($new_instance = null)
+ {
+ static $instance = null;
+ if (isset($new_instance) && is_object($new_instance)) {
+ $instance = $new_instance;
+ }
+ return $instance;
+ }
+
+ public function PrintTrace()
+ {
+ $this->yyTraceFILE = fopen('php://output', 'w');
+ $this->yyTracePrompt = '<br>';
+ }
+
+
+/*!lex2php
+%input $this->data
+%counter $this->counter
+%token $this->token
+%value $this->value
+%line $this->line
+commentstart = /#|;/
+openB = /\[/
+closeB = /\]/
+section = /.*?(?=[\.=\[\]\r\n])/
+equal = /=/
+whitespace = /[ \t\r]+/
+dot = /\./
+id = /[0-9]*[a-zA-Z_]\w*/
+newline = /\n/
+single_quoted_string = /'[^'\\]*(?:\\.[^'\\]*)*'(?=[ \t\r]*[\n#;])/
+double_quoted_string = /"[^"\\]*(?:\\.[^"\\]*)*"(?=[ \t\r]*[\n#;])/
+tripple_quotes = /"""/
+tripple_quotes_end = /"""(?=[ \t\r]*[\n#;])/
+text = /[\S\s]/
+float = /\d+\.\d+(?=[ \t\r]*[\n#;])/
+int = /\d+(?=[ \t\r]*[\n#;])/
+maybe_bool = /[a-zA-Z]+(?=[ \t\r]*[\n#;])/
+naked_string = /[^\n]+?(?=[ \t\r]*\n)/
+*/
+
+/*!lex2php
+%statename START
+
+commentstart {
+ $this->token = Smarty_Internal_Configfileparser::TPC_COMMENTSTART;
+ $this->yypushstate(self::COMMENT);
+}
+openB {
+ $this->token = Smarty_Internal_Configfileparser::TPC_OPENB;
+ $this->yypushstate(self::SECTION);
+}
+closeB {
+ $this->token = Smarty_Internal_Configfileparser::TPC_CLOSEB;
+}
+equal {
+ $this->token = Smarty_Internal_Configfileparser::TPC_EQUAL;
+ $this->yypushstate(self::VALUE);
+}
+whitespace {
+ return false;
+}
+newline {
+ $this->token = Smarty_Internal_Configfileparser::TPC_NEWLINE;
+}
+id {
+ $this->token = Smarty_Internal_Configfileparser::TPC_ID;
+}
+text {
+ $this->token = Smarty_Internal_Configfileparser::TPC_OTHER;
+}
+
+*/
+
+/*!lex2php
+%statename VALUE
+
+whitespace {
+ return false;
+}
+float {
+ $this->token = Smarty_Internal_Configfileparser::TPC_FLOAT;
+ $this->yypopstate();
+}
+int {
+ $this->token = Smarty_Internal_Configfileparser::TPC_INT;
+ $this->yypopstate();
+}
+tripple_quotes {
+ $this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_QUOTES;
+ $this->yypushstate(self::TRIPPLE);
+}
+single_quoted_string {
+ $this->token = Smarty_Internal_Configfileparser::TPC_SINGLE_QUOTED_STRING;
+ $this->yypopstate();
+}
+double_quoted_string {
+ $this->token = Smarty_Internal_Configfileparser::TPC_DOUBLE_QUOTED_STRING;
+ $this->yypopstate();
+}
+maybe_bool {
+ if (!$this->configBooleanize || !in_array(strtolower($this->value), Array("true", "false", "on", "off", "yes", "no")) ) {
+ $this->yypopstate();
+ $this->yypushstate(self::NAKED_STRING_VALUE);
+ return true; //reprocess in new state
+ } else {
+ $this->token = Smarty_Internal_Configfileparser::TPC_BOOL;
+ $this->yypopstate();
+ }
+}
+naked_string {
+ $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
+ $this->yypopstate();
+}
+newline {
+ $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
+ $this->value = "";
+ $this->yypopstate();
+}
+
+*/
+
+/*!lex2php
+%statename NAKED_STRING_VALUE
+
+naked_string {
+ $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
+ $this->yypopstate();
+}
+
+*/
+
+/*!lex2php
+%statename COMMENT
+
+whitespace {
+ return false;
+}
+naked_string {
+ $this->token = Smarty_Internal_Configfileparser::TPC_NAKED_STRING;
+}
+newline {
+ $this->token = Smarty_Internal_Configfileparser::TPC_NEWLINE;
+ $this->yypopstate();
+}
+
+*/
+
+/*!lex2php
+%statename SECTION
+
+dot {
+ $this->token = Smarty_Internal_Configfileparser::TPC_DOT;
+}
+section {
+ $this->token = Smarty_Internal_Configfileparser::TPC_SECTION;
+ $this->yypopstate();
+}
+
+*/
+/*!lex2php
+%statename TRIPPLE
+
+tripple_quotes_end {
+ $this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_QUOTES_END;
+ $this->yypopstate();
+ $this->yypushstate(self::START);
+}
+text {
+ $to = strlen($this->data);
+ preg_match("/\"\"\"[ \t\r]*[\n#;]/",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter);
+ if (isset($match[0][1])) {
+ $to = $match[0][1];
+ } else {
+ $this->compiler->trigger_template_error ("missing or misspelled literal closing tag");
+ }
+ $this->value = substr($this->data,$this->counter,$to-$this->counter);
+ $this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_TEXT;
+}
+*/
+
+}
diff --git a/lexer/smarty_internal_configfileparser.y b/lexer/smarty_internal_configfileparser.y
new file mode 100644
index 00000000..358c8349
--- /dev/null
+++ b/lexer/smarty_internal_configfileparser.y
@@ -0,0 +1,363 @@
+/**
+* Smarty Internal Plugin Configfileparser
+*
+* This is the config file parser
+*
+*
+* @package Smarty
+* @subpackage Config
+* @author Uwe Tews
+*/
+%name TPC_
+%declare_class {
+/**
+* Smarty Internal Plugin Configfileparse
+*
+* This is the config file parser.
+* It is generated from the smarty_internal_configfileparser.y file
+* @package Smarty
+* @subpackage Compiler
+* @author Uwe Tews
+*/
+class Smarty_Internal_Configfileparser
+}
+%include_class
+{
+ /**
+ * result status
+ *
+ * @var bool
+ */
+ public $successful = true;
+ /**
+ * return value
+ *
+ * @var mixed
+ */
+ public $retvalue = 0;
+ /**
+ * @var
+ */
+ public $yymajor;
+ /**
+ * lexer object
+ *
+ * @var Smarty_Internal_Configfilelexer
+ */
+ private $lex;
+ /**
+ * internal error flag
+ *
+ * @var bool
+ */
+ private $internalError = false;
+ /**
+ * compiler object
+ *
+ * @var Smarty_Internal_Config_File_Compiler
+ */
+ public $compiler = null;
+ /**
+ * smarty object
+ *
+ * @var Smarty
+ */
+ public $smarty = null;
+ /**
+ * copy of config_overwrite property
+ *
+ * @var bool
+ */
+ private $configOverwrite = false;
+ /**
+ * copy of config_read_hidden property
+ *
+ * @var bool
+ */
+ private $configReadHidden = false;
+ /**
+ * helper map
+ *
+ * @var array
+ */
+ private static $escapes_single = Array('\\' => '\\',
+ '\'' => '\'');
+
+ /**
+ * constructor
+ *
+ * @param Smarty_Internal_Configfilelexer $lex
+ * @param Smarty_Internal_Config_File_Compiler $compiler
+ */
+ function __construct(Smarty_Internal_Configfilelexer $lex, Smarty_Internal_Config_File_Compiler $compiler)
+ {
+ // set instance object
+ self::instance($this);
+ $this->lex = $lex;
+ $this->smarty = $compiler->smarty;
+ $this->compiler = $compiler;
+ $this->configOverwrite = $compiler->smarty->config_overwrite;
+ $this->configReadHidden = $compiler->smarty->config_read_hidden;
+ }
+
+ /**
+ * @param null $new_instance
+ *
+ * @return null
+ */
+ public static function &instance($new_instance = null)
+ {
+ static $instance = null;
+ if (isset($new_instance) && is_object($new_instance)) {
+ $instance = $new_instance;
+ }
+ return $instance;
+ }
+
+ /**
+ * parse optional boolean keywords
+ *
+ * @param string $str
+ *
+ * @return bool
+ */
+ private function parse_bool($str)
+ {
+ $str = strtolower($str);
+ if (in_array($str, array('on', 'yes', 'true'))) {
+ $res = true;
+ } else {
+ $res = false;
+ }
+ return $res;
+ }
+
+ /**
+ * parse single quoted string
+ * remove outer quotes
+ * unescape inner quotes
+ *
+ * @param string $qstr
+ *
+ * @return string
+ */
+ private static function parse_single_quoted_string($qstr)
+ {
+ $escaped_string = substr($qstr, 1, strlen($qstr) - 2); //remove outer quotes
+
+ $ss = preg_split('/(\\\\.)/', $escaped_string, - 1, PREG_SPLIT_DELIM_CAPTURE);
+
+ $str = "";
+ foreach ($ss as $s) {
+ if (strlen($s) === 2 && $s[0] === '\\') {
+ if (isset(self::$escapes_single[$s[1]])) {
+ $s = self::$escapes_single[$s[1]];
+ }
+ }
+ $str .= $s;
+ }
+ return $str;
+ }
+
+ /**
+ * parse double quoted string
+ *
+ * @param string $qstr
+ *
+ * @return string
+ */
+ private static function parse_double_quoted_string($qstr)
+ {
+ $inner_str = substr($qstr, 1, strlen($qstr) - 2);
+ return stripcslashes($inner_str);
+ }
+
+ /**
+ * parse triple quoted string
+ *
+ * @param string $qstr
+ *
+ * @return string
+ */
+ private static function parse_tripple_double_quoted_string($qstr)
+ {
+ return stripcslashes($qstr);
+ }
+
+ /**
+ * set a config variable in target array
+ *
+ * @param array $var
+ * @param array $target_array
+ */
+ private function set_var(Array $var, Array &$target_array)
+ {
+ $key = $var["key"];
+ $value = $var["value"];
+
+ if ($this->configOverwrite || !isset($target_array['vars'][$key])) {
+ $target_array['vars'][$key] = $value;
+ } else {
+ settype($target_array['vars'][$key], 'array');
+ $target_array['vars'][$key][] = $value;
+ }
+ }
+
+ /**
+ * add config variable to global vars
+ *
+ * @param array $vars
+ */
+ private function add_global_vars(Array $vars)
+ {
+ if (!isset($this->compiler->config_data['vars'])) {
+ $this->compiler->config_data['vars'] = Array();
+ }
+ foreach ($vars as $var) {
+ $this->set_var($var, $this->compiler->config_data);
+ }
+ }
+
+ /**
+ * add config variable to section
+ *
+ * @param string $section_name
+ * @param array $vars
+ */
+ private function add_section_vars($section_name, Array $vars)
+ {
+ if (!isset($this->compiler->config_data['sections'][$section_name]['vars'])) {
+ $this->compiler->config_data['sections'][$section_name]['vars'] = Array();
+ }
+ foreach ($vars as $var) {
+ $this->set_var($var, $this->compiler->config_data['sections'][$section_name]);
+ }
+ }
+}
+
+
+%token_prefix TPC_
+
+%parse_accept
+{
+ $this->successful = !$this->internalError;
+ $this->internalError = false;
+ $this->retvalue = $this->_retvalue;
+ //echo $this->retvalue."\n\n";
+}
+
+%syntax_error
+{
+ $this->internalError = true;
+ $this->yymajor = $yymajor;
+ $this->compiler->trigger_config_file_error();
+}
+
+%stack_overflow
+{
+ $this->internalError = true;
+ $this->compiler->trigger_config_file_error("Stack overflow in configfile parser");
+}
+
+// Complete config file
+start(res) ::= global_vars sections. {
+ res = null;
+}
+
+// Global vars
+global_vars(res) ::= var_list(vl). {
+ $this->add_global_vars(vl); res = null;
+}
+
+// Sections
+sections(res) ::= sections section. {
+ res = null;
+}
+
+sections(res) ::= . {
+ res = null;
+}
+
+section(res) ::= OPENB SECTION(i) CLOSEB newline var_list(vars). {
+ $this->add_section_vars(i, vars);
+ res = null;
+}
+
+section(res) ::= OPENB DOT SECTION(i) CLOSEB newline var_list(vars). {
+ if ($this->configReadHidden) {
+ $this->add_section_vars(i, vars);
+ }
+ res = null;
+}
+
+// Var list
+var_list(res) ::= var_list(vl) newline. {
+ res = vl;
+}
+
+var_list(res) ::= var_list(vl) var(v). {
+ res = array_merge(vl, Array(v));
+}
+
+var_list(res) ::= . {
+ res = Array();
+}
+
+
+// Var
+var(res) ::= ID(id) EQUAL value(v). {
+ res = Array("key" => id, "value" => v);
+}
+
+
+value(res) ::= FLOAT(i). {
+ res = (float) i;
+}
+
+value(res) ::= INT(i). {
+ res = (int) i;
+}
+
+value(res) ::= BOOL(i). {
+ res = $this->parse_bool(i);
+}
+
+value(res) ::= SINGLE_QUOTED_STRING(i). {
+ res = self::parse_single_quoted_string(i);
+}
+
+value(res) ::= DOUBLE_QUOTED_STRING(i). {
+ res = self::parse_double_quoted_string(i);
+}
+
+value(res) ::= TRIPPLE_QUOTES(i) TRIPPLE_TEXT(c) TRIPPLE_QUOTES_END(ii). {
+ res = self::parse_tripple_double_quoted_string(c);
+}
+
+value(res) ::= TRIPPLE_QUOTES(i) TRIPPLE_QUOTES_END(ii). {
+ res = '';
+}
+
+value(res) ::= NAKED_STRING(i). {
+ res = i;
+}
+
+// NOTE: this is not a valid rule
+// It is added hier to produce a usefull error message on a missing '=';
+value(res) ::= OTHER(i). {
+ res = i;
+}
+
+
+// Newline and comments
+newline(res) ::= NEWLINE. {
+ res = null;
+}
+
+newline(res) ::= COMMENTSTART NEWLINE. {
+ res = null;
+}
+
+newline(res) ::= COMMENTSTART NAKED_STRING NEWLINE. {
+ res = null;
+}
diff --git a/lexer/smarty_internal_templatelexer.plex b/lexer/smarty_internal_templatelexer.plex
new file mode 100644
index 00000000..d988c12b
--- /dev/null
+++ b/lexer/smarty_internal_templatelexer.plex
@@ -0,0 +1,900 @@
+<?php
+/**
+ * Smarty Internal Plugin Templatelexer
+ * This is the lexer to break the template source into tokens
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+
+/**
+ * Smarty_Internal_Templatelexer
+ * This is the template file lexer.
+ * It is generated from the smarty_internal_templatelexer.plex file
+ *
+ * @package Smarty
+ * @subpackage Compiler
+ * @author Uwe Tews
+ */
+class Smarty_Internal_Templatelexer
+{
+ /**
+ * Source
+ *
+ * @var string
+ */
+ public $data;
+ /**
+ * byte counter
+ *
+ * @var int
+ */
+ public $counter;
+ /**
+ * token number
+ *
+ * @var int
+ */
+ public $token;
+ /**
+ * token value
+ *
+ * @var string
+ */
+ public $value;
+ /**
+ * current line
+ *
+ * @var int
+ */
+ public $line;
+ /**
+ * tag start line
+ *
+ * @var
+ */
+ public $taglineno;
+ /**
+ * flag if parsing php script
+ *
+ * @var bool
+ */
+ public $is_phpScript = false;
+ /**
+ * escaped left delimiter
+ *
+ * @var string
+ */
+ public $ldel = '';
+ /**
+ * escaped left delimiter length
+ *
+ * @var int
+ */
+ public $ldel_length = 0;
+ /**
+ * escaped right delimiter
+ *
+ * @var string
+ */
+ public $rdel = '';
+ /**
+ * escaped right delimiter length
+ *
+ * @var int
+ */
+ public $rdel_length = 0;
+ /**
+ * state number
+ *
+ * @var int
+ */
+ public $state = 1;
+ /**
+ * Smarty object
+ *
+ * @var Smarty
+ */
+ public $smarty = null;
+ /**
+ * compiler object
+ *
+ * @var Smarty_Internal_TemplateCompilerBase
+ */
+ private $compiler = null;
+ /**
+ * literal tag nesting level
+ *
+ * @var int
+ */
+ private $literal_cnt = 0;
+ /**
+ * trace file
+ *
+ * @var resource
+ */
+ public $yyTraceFILE;
+ /**
+ * trace prompt
+ *
+ * @var string
+ */
+ public $yyTracePrompt;
+ /**
+ * state names
+ *
+ * @var array
+ */
+ public $state_name = array(1 => 'TEXT', 2 => 'SMARTY', 3 => 'LITERAL', 4 => 'DOUBLEQUOTEDSTRING', 5 => 'CHILDBODY');
+ /**
+ * token names
+ *
+ * @var array
+ */
+ public $smarty_token_names = array( // Text for parser error messages
+ 'IDENTITY' => '===',
+ 'NONEIDENTITY' => '!==',
+ 'EQUALS' => '==',
+ 'NOTEQUALS' => '!=',
+ 'GREATEREQUAL' => '(>=,ge)',
+ 'LESSEQUAL' => '(<=,le)',
+ 'GREATERTHAN' => '(>,gt)',
+ 'LESSTHAN' => '(<,lt)',
+ 'MOD' => '(%,mod)',
+ 'NOT' => '(!,not)',
+ 'LAND' => '(&&,and)',
+ 'LOR' => '(||,or)',
+ 'LXOR' => 'xor',
+ 'OPENP' => '(',
+ 'CLOSEP' => ')',
+ 'OPENB' => '[',
+ 'CLOSEB' => ']',
+ 'PTR' => '->',
+ 'APTR' => '=>',
+ 'EQUAL' => '=',
+ 'NUMBER' => 'number',
+ 'UNIMATH' => '+" , "-',
+ 'MATH' => '*" , "/" , "%',
+ 'INCDEC' => '++" , "--',
+ 'SPACE' => ' ',
+ 'DOLLAR' => '$',
+ 'SEMICOLON' => ';',
+ 'COLON' => ':',
+ 'DOUBLECOLON' => '::',
+ 'AT' => '@',
+ 'HATCH' => '#',
+ 'QUOTE' => '"',
+ 'BACKTICK' => '`',
+ 'VERT' => '|',
+ 'DOT' => '.',
+ 'COMMA' => '","',
+ 'ANDSYM' => '"&"',
+ 'QMARK' => '"?"',
+ 'ID' => 'identifier',
+ 'TEXT' => 'text',
+ 'FAKEPHPSTARTTAG' => 'Fake PHP start tag',
+ 'PHPSTARTTAG' => 'PHP start tag',
+ 'PHPENDTAG' => 'PHP end tag',
+ 'LITERALSTART' => 'Literal start',
+ 'LITERALEND' => 'Literal end',
+ 'LDELSLASH' => 'closing tag',
+ 'COMMENT' => 'comment',
+ 'AS' => 'as',
+ 'TO' => 'to',
+ );
+
+ /**
+ * constructor
+ *
+ * @param string $data template source
+ * @param Smarty_Internal_TemplateCompilerBase $compiler
+ */
+ function __construct($data, Smarty_Internal_TemplateCompilerBase $compiler)
+ {
+ $this->data = $data;
+ $this->counter = 0;
+ if (preg_match('/^\xEF\xBB\xBF/', $this->data, $match)) {
+ $this->counter += strlen($match[0]);
+ }
+ $this->line = 1;
+ $this->smarty = $compiler->smarty;
+ $this->compiler = $compiler;
+ $this->ldel = preg_quote($this->smarty->left_delimiter, '/');
+ $this->ldel_length = strlen($this->smarty->left_delimiter);
+ $this->rdel = preg_quote($this->smarty->right_delimiter, '/');
+ $this->rdel_length = strlen($this->smarty->right_delimiter);
+ $this->smarty_token_names['LDEL'] = $this->smarty->left_delimiter;
+ $this->smarty_token_names['RDEL'] = $this->smarty->right_delimiter;
+ }
+
+ public function PrintTrace()
+ {
+ $this->yyTraceFILE = fopen('php://output', 'w');
+ $this->yyTracePrompt = '<br>';
+ }
+
+ /*!lex2php
+ %input $this->data
+ %counter $this->counter
+ %token $this->token
+ %value $this->value
+ %line $this->line
+ linebreak = /[\t ]*[\r\n]+[\t ]*/
+ text = /[\S\s]/
+ textdoublequoted = /([^"\\]*?)((?:\\.[^"\\]*?)*?)(?=(SMARTYldel|\$|`\$|"))/
+ dollarid = /\$[0-9]*[a-zA-Z_]\w*/
+ namespace = /([0-9]*[a-zA-Z_]\w*)?(\\[0-9]*[a-zA-Z_]\w*)+/
+ all = /[\S\s]+/
+ emptyjava = /\{\}/
+ phpstarttag = /(<script\s+language\s*=\s*[\"\']?\s*php\s*[\"\']?\s*>)|(<\?(?:php\w+|=|[a-zA-Z]+)?)/
+ phpendtag = /\?>/
+ phpendscript = /<\/script>/
+ aspstarttag = /<%/
+ aspendtag = /%>/
+ slash = /\//
+ ldel = /SMARTYldel\s*/
+ rdel = /\s*SMARTYrdel/
+ smartyblockchildparent = /[\$]smarty\.block\.(child|parent)/
+ integer = /\d+/
+ hex = /0[xX][0-9a-fA-F]+/
+ math = /\s*(\*|\/|\%)\s*/
+ comment = /SMARTYldel\*([\S\s]*?)\*SMARTYrdel/
+ incdec = /\+\+|\-\-/
+ unimath = /\s*(\+|\-)\s*/
+ openP = /\s*\(\s*/
+ closeP = /\s*\)/
+ openB = /\[\s*/
+ closeB = /\s*\]/
+ dollar = /\$/
+ dot = /\./
+ comma = /\s*\,\s*/
+ doublecolon = /\:\:/
+ colon = /\s*\:\s*/
+ at = /@/
+ hatch = /#/
+ semicolon = /\s*\;/
+ equal = /\s*=\s*/
+ space = /\s+/
+ ptr = /\s*\->\s*/
+ aptr = /\s*=>\s*/
+ singlequotestring = /'[^'\\]*(?:\\.[^'\\]*)*'/
+ backtick = /`/
+ backtickdollar = /`\$/
+ vert = /\|/
+ andsym = /\s*\&\s*/
+ qmark = /\s*\?\s*/
+ constant = /([_]+[A-Z0-9][0-9A-Z_]*|[A-Z][0-9A-Z_]*)(?![0-9A-Z_]*[a-z])/
+ attr = /\s+[0-9]*[a-zA-Z_][a-zA-Z0-9_\-:]*\s*=\s*/
+ id = /[0-9]*[a-zA-Z_]\w*/
+ literal = /literal/
+ strip = /strip/
+ equals = /\s*==\s*|\s+eq\s+/
+ notequals = /\s*!=\s*|\s*<>\s*|\s+(ne|neq)\s+/
+ greaterthan = /\s*>\s*|\s+gt\s+/
+ lessthan = /\s*<\s*|\s+lt\s+/
+ greaterequal = /\s*>=\s*|\s+(ge|gte)\s+/
+ lessequal = /\s*<=\s*|\s+(le|lte)\s+/
+ mod = /\s+mod\s+/
+ identity = /\s*===\s*/
+ noneidentity = /\s*!==\s*/
+ isoddby = /\s+is\s+odd\s+by\s+/
+ isnotoddby = /\s+is\s+not\s+odd\s+by\s+/
+ isodd = /\s+is\s+odd/
+ isnotodd = /\s+is\s+not\s+odd/
+ isevenby = /\s+is\s+even\s+by\s+/
+ isnotevenby = /\s+is\s+not\s+even\s+by\s+/
+ iseven = /\s+is\s+even/
+ isnoteven = /\s+is\s+not\s+even/
+ isdivby = /\s+is\s+div\s+by\s+/
+ isnotdivby = /\s+is\s+not\s+div\s+by\s+/
+ isin = /\s+is\s+in\s+/
+ as = /\s+as\s+/
+ to = /\s+to\s+/
+ step = /\s+step\s+/
+ block = /block/
+ if = /(if|elseif|else if|while)\s+/
+ for = /for\s+/
+ foreach = /foreach(?![^\s])/
+ setfilter = /setfilter\s+/
+ instanceof = /\s+instanceof\s+/
+ not = /!\s*|not\s+/
+ land = /\s*\&\&\s*|\s*and\s+/
+ lor = /\s*\|\|\s*|\s*or\s+/
+ lxor = /\s*xor\s+/
+ typecast = /\((int(eger)?|bool(ean)?|float|double|real|string|binary|array|object)\)\s*/
+ double_quote = /"/
+ single_quote = /'/
+ */
+ /*!lex2php
+ %statename TEXT
+ emptyjava {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ }
+ comment {
+ $this->token = Smarty_Internal_Templateparser::TP_COMMENT;
+ }
+ ldel strip rdel {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_STRIPON;
+ }
+ }
+ ldel slash strip rdel {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_STRIPOFF;
+ }
+ }
+ ldel literal rdel {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_LITERALSTART;
+ $this->yypushstate(self::LITERAL);
+ }
+ }
+ ldel if {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_LDELIF;
+ $this->yypushstate(self::SMARTY);
+ $this->taglineno = $this->line;
+ }
+ }
+ ldel for {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_LDELFOR;
+ $this->yypushstate(self::SMARTY);
+ $this->taglineno = $this->line;
+ }
+ }
+ ldel foreach {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_LDELFOREACH;
+ $this->yypushstate(self::SMARTY);
+ $this->taglineno = $this->line;
+ }
+ }
+ ldel setfilter {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_LDELSETFILTER;
+ $this->yypushstate(self::SMARTY);
+ $this->taglineno = $this->line;
+ }
+ }
+ ldel slash {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_LDELSLASH;
+ $this->yypushstate(self::SMARTY);
+ $this->taglineno = $this->line;
+ }
+ }
+ ldel {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_LDEL;
+ $this->yypushstate(self::SMARTY);
+ $this->taglineno = $this->line;
+ }
+ }
+ phpstarttag {
+ if (($script = strpos($this->value, '<s') === 0) || in_array($this->value, Array('<?', '<?=', '<?php'))) {
+ if ($script) {
+ $this->is_phpScript = true;
+ }
+ $this->token = Smarty_Internal_Templateparser::TP_PHPSTARTTAG;
+ } elseif ($this->value == '<?xml') {
+ $this->token = Smarty_Internal_Templateparser::TP_XMLTAG;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ //$this->value = substr($this->value, 0, 2);
+ }
+ }
+ phpendtag {
+ $this->token = Smarty_Internal_Templateparser::TP_PHPENDTAG;
+ }
+ phpendscript {
+ $this->token = Smarty_Internal_Templateparser::TP_PHPENDSCRIPT;
+ }
+ rdel {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ }
+ aspstarttag {
+ $this->token = Smarty_Internal_Templateparser::TP_ASPSTARTTAG;
+ }
+ aspendtag {
+ $this->token = Smarty_Internal_Templateparser::TP_ASPENDTAG;
+ }
+ text {
+ $phpEndScript = $this->is_phpScript ? '|<\\/script>' : '';
+ $to = strlen($this->data);
+ preg_match("/{$this->ldel}|<\?|<%|\?>|%>|<script\s+language\s*=\s*[\"\']?\s*php\s*[\"\']?\s*>{$phpEndScript}/",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter);
+ if (isset($match[0][1])) {
+ $to = $match[0][1];
+ }
+ $this->value = substr($this->data,$this->counter,$to-$this->counter);
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ }
+
+
+ */
+ /*!lex2php
+ %statename SMARTY
+ double_quote {
+ $this->token = Smarty_Internal_Templateparser::TP_QUOTE;
+ $this->yypushstate(self::DOUBLEQUOTEDSTRING);
+ }
+ singlequotestring {
+ $this->token = Smarty_Internal_Templateparser::TP_SINGLEQUOTESTRING;
+ }
+ smartyblockchildparent {
+ $this->token = Smarty_Internal_Templateparser::TP_SMARTYBLOCKCHILDPARENT;
+ $this->taglineno = $this->line;
+ }
+ dollar {
+ $this->token = Smarty_Internal_Templateparser::TP_DOLLAR;
+ }
+ rdel {
+ $this->token = Smarty_Internal_Templateparser::TP_RDEL;
+ $this->yypopstate();
+ }
+ isin {
+ $this->token = Smarty_Internal_Templateparser::TP_ISIN;
+ }
+ as {
+ $this->token = Smarty_Internal_Templateparser::TP_AS;
+ }
+ to {
+ $this->token = Smarty_Internal_Templateparser::TP_TO;
+ }
+ step {
+ $this->token = Smarty_Internal_Templateparser::TP_STEP;
+ }
+ instanceof {
+ $this->token = Smarty_Internal_Templateparser::TP_INSTANCEOF;
+ }
+ identity{
+ $this->token = Smarty_Internal_Templateparser::TP_IDENTITY;
+ }
+ noneidentity{
+ $this->token = Smarty_Internal_Templateparser::TP_NONEIDENTITY;
+ }
+ equals{
+ $this->token = Smarty_Internal_Templateparser::TP_EQUALS;
+ }
+ notequals{
+ $this->token = Smarty_Internal_Templateparser::TP_NOTEQUALS;
+ }
+ greaterequal{
+ $this->token = Smarty_Internal_Templateparser::TP_GREATEREQUAL;
+ }
+ lessequal{
+ $this->token = Smarty_Internal_Templateparser::TP_LESSEQUAL;
+ }
+ greaterthan{
+ $this->token = Smarty_Internal_Templateparser::TP_GREATERTHAN;
+ }
+ lessthan{
+ $this->token = Smarty_Internal_Templateparser::TP_LESSTHAN;
+ }
+ mod{
+ $this->token = Smarty_Internal_Templateparser::TP_MOD;
+ }
+ not{
+ $this->token = Smarty_Internal_Templateparser::TP_NOT;
+ }
+ land {
+ $this->token = Smarty_Internal_Templateparser::TP_LAND;
+ }
+ lor {
+ $this->token = Smarty_Internal_Templateparser::TP_LOR;
+ }
+ lxor {
+ $this->token = Smarty_Internal_Templateparser::TP_LXOR;
+ }
+ isoddby {
+ $this->token = Smarty_Internal_Templateparser::TP_ISODDBY;
+ }
+ isnotoddby {
+ $this->token = Smarty_Internal_Templateparser::TP_ISNOTODDBY;
+ }
+
+ isodd {
+ $this->token = Smarty_Internal_Templateparser::TP_ISODD;
+ }
+ isnotodd {
+ $this->token = Smarty_Internal_Templateparser::TP_ISNOTODD;
+ }
+ isevenby {
+ $this->token = Smarty_Internal_Templateparser::TP_ISEVENBY;
+ }
+ isnotevenby {
+ $this->token = Smarty_Internal_Templateparser::TP_ISNOTEVENBY;
+ }
+ iseven{
+ $this->token = Smarty_Internal_Templateparser::TP_ISEVEN;
+ }
+ isnoteven {
+ $this->token = Smarty_Internal_Templateparser::TP_ISNOTEVEN;
+ }
+ isdivby {
+ $this->token = Smarty_Internal_Templateparser::TP_ISDIVBY;
+ }
+ isnotdivby {
+ $this->token = Smarty_Internal_Templateparser::TP_ISNOTDIVBY;
+ }
+ typecast {
+ $this->token = Smarty_Internal_Templateparser::TP_TYPECAST;
+ }
+ openP {
+ $this->token = Smarty_Internal_Templateparser::TP_OPENP;
+ }
+ closeP {
+ $this->token = Smarty_Internal_Templateparser::TP_CLOSEP;
+ }
+ openB {
+ $this->token = Smarty_Internal_Templateparser::TP_OPENB;
+ }
+
+ closeB {
+ $this->token = Smarty_Internal_Templateparser::TP_CLOSEB;
+ }
+ ptr {
+ $this->token = Smarty_Internal_Templateparser::TP_PTR;
+ }
+ aptr {
+ $this->token = Smarty_Internal_Templateparser::TP_APTR;
+ }
+ equal {
+ $this->token = Smarty_Internal_Templateparser::TP_EQUAL;
+ }
+ incdec {
+ $this->token = Smarty_Internal_Templateparser::TP_INCDEC;
+ }
+ unimath {
+ $this->token = Smarty_Internal_Templateparser::TP_UNIMATH;
+ }
+ math {
+ $this->token = Smarty_Internal_Templateparser::TP_MATH;
+ }
+ at {
+ $this->token = Smarty_Internal_Templateparser::TP_AT;
+ }
+ hatch {
+ $this->token = Smarty_Internal_Templateparser::TP_HATCH;
+ }
+ attr {
+ // resolve conflicts with shorttag and right_delimiter starting with '='
+ if (substr($this->data, $this->counter + strlen($this->value) - 1, $this->rdel_length) == $this->smarty->right_delimiter) {
+ preg_match("/\s+/",$this->value,$match);
+ $this->value = $match[0];
+ $this->token = Smarty_Internal_Templateparser::TP_SPACE;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_ATTR;
+ }
+ }
+ namespace {
+ $this->token = Smarty_Internal_Templateparser::TP_NAMESPACE;
+ }
+ id {
+ $this->token = Smarty_Internal_Templateparser::TP_ID;
+ }
+ integer {
+ $this->token = Smarty_Internal_Templateparser::TP_INTEGER;
+ }
+ backtick {
+ $this->token = Smarty_Internal_Templateparser::TP_BACKTICK;
+ $this->yypopstate();
+ }
+ vert {
+ $this->token = Smarty_Internal_Templateparser::TP_VERT;
+ }
+ dot {
+ $this->token = Smarty_Internal_Templateparser::TP_DOT;
+ }
+ comma {
+ $this->token = Smarty_Internal_Templateparser::TP_COMMA;
+ }
+ semicolon {
+ $this->token = Smarty_Internal_Templateparser::TP_SEMICOLON;
+ }
+ doublecolon {
+ $this->token = Smarty_Internal_Templateparser::TP_DOUBLECOLON;
+ }
+ colon {
+ $this->token = Smarty_Internal_Templateparser::TP_COLON;
+ }
+ andsym {
+ $this->token = Smarty_Internal_Templateparser::TP_ANDSYM;
+ }
+ qmark {
+ $this->token = Smarty_Internal_Templateparser::TP_QMARK;
+ }
+ hex {
+ $this->token = Smarty_Internal_Templateparser::TP_HEX;
+ }
+ space {
+ $this->token = Smarty_Internal_Templateparser::TP_SPACE;
+ }
+ ldel if {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_LDELIF;
+ $this->yypushstate(self::SMARTY);
+ $this->taglineno = $this->line;
+ }
+ }
+ ldel for {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_LDELFOR;
+ $this->yypushstate(self::SMARTY);
+ $this->taglineno = $this->line;
+ }
+ }
+ ldel foreach {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_LDELFOREACH;
+ $this->yypushstate(self::SMARTY);
+ $this->taglineno = $this->line;
+ }
+ }
+ ldel slash {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_LDELSLASH;
+ $this->yypushstate(self::SMARTY);
+ $this->taglineno = $this->line;
+ }
+ }
+ ldel {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_LDEL;
+ $this->yypushstate(self::SMARTY);
+ $this->taglineno = $this->line;
+ }
+ }
+ text {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ }
+ */
+
+ /*!lex2php
+ %statename LITERAL
+ ldel literal rdel {
+ $this->literal_cnt++;
+ $this->token = Smarty_Internal_Templateparser::TP_LITERAL;
+ }
+ ldel slash literal rdel {
+ if ($this->literal_cnt) {
+ $this->literal_cnt--;
+ $this->token = Smarty_Internal_Templateparser::TP_LITERAL;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_LITERALEND;
+ $this->yypopstate();
+ }
+ }
+ text {
+ $to = strlen($this->data);
+ preg_match("/{$this->ldel}\/?literal{$this->rdel}/",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter);
+ if (isset($match[0][1])) {
+ $to = $match[0][1];
+ } else {
+ $this->compiler->trigger_template_error ("missing or misspelled literal closing tag");
+ }
+ $this->value = substr($this->data,$this->counter,$to-$this->counter);
+ $this->token = Smarty_Internal_Templateparser::TP_LITERAL;
+ }
+ */
+ /*!lex2php
+ %statename DOUBLEQUOTEDSTRING
+ ldel if {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_LDELIF;
+ $this->yypushstate(self::SMARTY);
+ $this->taglineno = $this->line;
+ }
+ }
+ ldel for {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_LDELFOR;
+ $this->yypushstate(self::SMARTY);
+ $this->taglineno = $this->line;
+ }
+ }
+ ldel foreach {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_LDELFOREACH;
+ $this->yypushstate(self::SMARTY);
+ $this->taglineno = $this->line;
+ }
+ }
+ ldel literal rdel {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ }
+ ldel slash literal rdel {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ }
+
+ ldel slash {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_LDELSLASH;
+ $this->yypushstate(self::SMARTY);
+ $this->taglineno = $this->line;
+ }
+ }
+ ldel {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_LDEL;
+ $this->yypushstate(self::SMARTY);
+ $this->taglineno = $this->line;
+ }
+ }
+ double_quote {
+ $this->token = Smarty_Internal_Templateparser::TP_QUOTE;
+ $this->yypopstate();
+ }
+ backtickdollar {
+ $this->token = Smarty_Internal_Templateparser::TP_BACKTICK;
+ $this->value = substr($this->value,0,-1);
+ $this->yypushstate(self::SMARTY);
+ $this->taglineno = $this->line;
+ }
+ dollarid {
+ $this->token = Smarty_Internal_Templateparser::TP_DOLLARID;
+ }
+
+ dollar {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ }
+ textdoublequoted {
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ }
+ text {
+ $to = strlen($this->data);
+ $this->value = substr($this->data,$this->counter,$to-$this->counter);
+ $this->token = Smarty_Internal_Templateparser::TP_TEXT;
+ }
+ */
+ /*!lex2php
+ %statename CHILDBODY
+ ldel strip rdel {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ return false;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_STRIPON;
+ }
+ }
+ ldel slash strip rdel {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ return false;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_STRIPOFF;
+ }
+ }
+ ldel block {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ return false;
+ } else {
+ $this->yypopstate();
+ return true;
+ }
+ }
+ text {
+ $to = strlen($this->data);
+ preg_match("/SMARTYldel\s*((\/)?strip\s*SMARTYrdel|block\s+)/",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter);
+ if (isset($match[0][1])) {
+ $to = $match[0][1];
+ }
+ $this->value = substr($this->data,$this->counter,$to-$this->counter);
+ return false;
+ }
+
+ */
+ /*!lex2php
+ %statename CHILDBLOCK
+ ldel literal rdel {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE;
+ $this->yypushstate(self::CHILDLITERAL);
+ }
+ }
+ ldel block {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE;
+ } else {
+ $this->yypopstate();
+ return true;
+ }
+ }
+ ldel slash block {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE;
+ } else {
+ $this->yypopstate();
+ return true;
+ }
+ }
+ ldel smartyblockchildparent {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE;
+ } else {
+ $this->yypopstate();
+ return true;
+ }
+ }
+ text {
+ $to = strlen($this->data);
+ preg_match("/SMARTYldel\s*(literal\s*SMARTYrdel|(\/)?block(\s|SMARTYrdel)|[\$]smarty\.block\.(child|parent))/",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter);
+ if (isset($match[0][1])) {
+ $to = $match[0][1];
+ }
+ $this->value = substr($this->data,$this->counter,$to-$this->counter);
+ $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE;
+ }
+ */
+ /*!lex2php
+ %statename CHILDLITERAL
+ ldel literal rdel {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE;
+ $this->yypushstate(self::CHILDLITERAL);
+ }
+ }
+ ldel slash literal rdel {
+ if ($this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false) {
+ $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE;
+ } else {
+ $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE;
+ $this->yypopstate();
+ }
+ }
+ text {
+ $to = strlen($this->data);
+ preg_match("/{$this->ldel}\/?literal\s*{$this->rdel}/",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter);
+ if (isset($match[0][1])) {
+ $to = $match[0][1];
+ } else {
+ $this->compiler->trigger_template_error ("missing or misspelled literal closing tag");
+ }
+ $this->value = substr($this->data,$this->counter,$to-$this->counter);
+ $this->token = Smarty_Internal_Templateparser::TP_BLOCKSOURCE;
+ }
+ */
+ }
+
+ \ No newline at end of file
diff --git a/lexer/smarty_internal_templateparser.y b/lexer/smarty_internal_templateparser.y
new file mode 100644
index 00000000..ba023b34
--- /dev/null
+++ b/lexer/smarty_internal_templateparser.y
@@ -0,0 +1,1432 @@
+/**
+* Smarty Internal Plugin Templateparser
+*
+* This is the template parser
+*
+*
+* @package Smarty
+* @subpackage Compiler
+* @author Uwe Tews
+*/
+%stack_size 500
+%name TP_
+%declare_class {
+/**
+* Smarty Internal Plugin Templateparser
+*
+* This is the template parser.
+* It is generated from the smarty_internal_templateparser.y file
+* @package Smarty
+* @subpackage Compiler
+* @author Uwe Tews
+*/
+class Smarty_Internal_Templateparser
+}
+%include_class
+{
+ const Err1 = "Security error: Call to private object member not allowed";
+ const Err2 = "Security error: Call to dynamic object member not allowed";
+ const Err3 = "PHP in template not allowed. Use SmartyBC to enable it";
+
+ /**
+ * result status
+ *
+ * @var bool
+ */
+ public $successful = true;
+ /**
+ * return value
+ *
+ * @var mixed
+ */
+ public $retvalue = 0;
+ /**
+ * counter for prefix code
+ *
+ * @var int
+ */
+ public static $prefix_number = 0;
+ /**
+ * @var
+ */
+ public $yymajor;
+ /**
+ * last index of array variable
+ *
+ * @var mixed
+ */
+ public $last_index;
+ /**
+ * last variable name
+ *
+ * @var string
+ */
+ public $last_variable;
+ /**
+ * root parse tree buffer
+ *
+ * @var _smarty_template_buffer
+ */
+ public $root_buffer;
+ /**
+ * current parse tree object
+ *
+ * @var _smarty_template_buffer
+ */
+ public $current_buffer;
+ /**
+ * lexer object
+ *
+ * @var Smarty_Internal_Templatelexer
+ */
+ private $lex;
+ /**
+ * internal error flag
+ *
+ * @var bool
+ */
+ private $internalError = false;
+ /**
+ * {strip} status
+ *
+ * @var bool
+ */
+ private $strip = false;
+ /**
+ * compiler object
+ *
+ * @var Smarty_Internal_TemplateCompilerBase
+ */
+ public $compiler = null;
+ /**
+ * smarty object
+ *
+ * @var Smarty
+ */
+ public $smarty = null;
+ /**
+ * template object
+ *
+ * @var Smarty_Internal_Template
+ */
+ public $template = null;
+ /**
+ * block nesting level
+ *
+ * @var int
+ */
+ public $block_nesting_level = 0;
+ /**
+ * xml tag flag
+ *
+ * @var bool
+ */
+ private $is_xml = false;
+ /**
+ * security object
+ *
+ * @var Smarty_Security
+ */
+ private $security = null;
+ /**
+ * asp enabled
+ *
+ * @var bool
+ */
+ private $asp_tags = false;
+ /**
+ * PHP tag handling mode
+ *
+ * @var int
+ */
+ private $php_handling = 0;
+
+ /**
+ * constructor
+ *
+ * @param Smarty_Internal_Templatelexer $lex
+ * @param Smarty_Internal_TemplateCompilerBase $compiler
+ */
+ function __construct(Smarty_Internal_Templatelexer $lex, Smarty_Internal_TemplateCompilerBase $compiler)
+ {
+ $this->lex = $lex;
+ $this->compiler = $compiler;
+ $this->template = $this->compiler->template;
+ $this->smarty = $this->template->smarty;
+ $this->compiler->has_variable_string = false;
+ $this->compiler->prefix_code = array();
+ if ($this->security = isset($this->smarty->security_policy)) {
+ $this->php_handling = $this->smarty->security_policy->php_handling;
+ } else {
+ $this->php_handling = $this->smarty->php_handling;
+ }
+ $this->asp_tags = (ini_get('asp_tags') != '0');
+ $this->current_buffer = $this->root_buffer = new _smarty_template_buffer($this);
+ }
+
+ /**
+ * insert PHP code in current buffer
+ *
+ * @param string $code
+ */
+ public function insertPhpCode($code)
+ {
+ $this->current_buffer->append_subtree(new _smarty_tag($this, $code));
+ }
+
+ /**
+ * compile variable
+ *
+ * @param string $variable
+ *
+ * @return string
+ */
+ public function compileVariable($variable)
+ {
+ if (strpos($variable, '(') == 0) {
+ // not a variable variable
+ $var = trim($variable, '\'');
+ $this->compiler->tag_nocache = $this->compiler->tag_nocache | $this->template->getVariable($var, null, true, false)->nocache;
+ $this->template->properties['variables'][$var] = $this->compiler->tag_nocache | $this->compiler->nocache;
+ }
+ return '$_smarty_tpl->tpl_vars[' . $variable . ']->value';
+ }
+}
+
+%token_prefix TP_
+
+%parse_accept
+{
+ $this->successful = !$this->internalError;
+ $this->internalError = false;
+ $this->retvalue = $this->_retvalue;
+ //echo $this->retvalue."\n\n";
+
+}
+
+%syntax_error
+{
+ $this->internalError = true;
+ $this->yymajor = $yymajor;
+ $this->compiler->trigger_template_error();
+}
+
+%stack_overflow
+{
+ $this->internalError = true;
+ $this->compiler->trigger_template_error("Stack overflow in template parser");
+}
+
+%left VERT.
+%left COLON.
+
+//
+// complete template
+//
+start(res) ::= template. {
+ res = $this->root_buffer->to_smarty_php();
+}
+
+//
+// loop over template elements
+//
+ // single template element
+template ::= template_element(e). {
+ if (e != null) {
+ $this->current_buffer->append_subtree(e);
+ }
+}
+
+ // loop of elements
+template ::= template template_element(e). {
+ if (e != null) {
+ // because of possible code injection
+ $this->current_buffer->append_subtree(e);
+ }
+}
+
+ // empty template
+template ::= .
+
+//
+// template elements
+//
+ // Smarty tag
+template_element(res)::= smartytag(st) RDEL. {
+ if ($this->compiler->has_code) {
+ $tmp =''; foreach ($this->compiler->prefix_code as $code) {$tmp.=$code;} $this->compiler->prefix_code=array();
+ res = new _smarty_tag($this, $this->compiler->processNocacheCode($tmp.st,true));
+ } else {
+ res = null;
+ }
+ $this->compiler->has_variable_string = false;
+ $this->block_nesting_level = count($this->compiler->_tag_stack);
+}
+
+ // comments
+template_element(res)::= COMMENT(c). {
+ res = null;
+}
+
+ // Literal
+template_element(res) ::= literal(l). {
+ res = new _smarty_text($this, l);
+}
+
+ // '<?php' | '<script language=php>' tag
+template_element(res)::= PHPSTARTTAG(st). {
+ if (strpos(st, '<s') === 0) {
+ $this->lex->is_phpScript = true;
+ }
+ if ($this->php_handling == Smarty::PHP_PASSTHRU) {
+ if ($this->lex->is_phpScript) {
+ $s = addcslashes(st, "'");
+ res = new _smarty_text($this, $s);
+ } else {
+ res = new _smarty_text($this, st);
+ }
+ } elseif ($this->php_handling == Smarty::PHP_QUOTE) {
+ res = new _smarty_text($this, htmlspecialchars(st, ENT_QUOTES));
+ } elseif ($this->php_handling == Smarty::PHP_ALLOW) {
+ if (!($this->smarty instanceof SmartyBC)) {
+ $this->compiler->trigger_template_error (self::Err3);
+ }
+ res = new _smarty_tag($this, $this->compiler->processNocacheCode('<?php ', true));
+ } elseif ($this->php_handling == Smarty::PHP_REMOVE) {
+ res = null;
+ }
+}
+
+ // '?>' tag
+template_element(res)::= PHPENDTAG(st). {
+ if ($this->is_xml) {
+ $this->compiler->tag_nocache = true;
+ $this->is_xml = false;
+ $save = $this->template->has_nocache_code;
+ res = new _smarty_tag($this, $this->compiler->processNocacheCode("<?php echo '?>';?>\n", $this->compiler, true));
+ $this->template->has_nocache_code = $save;
+ } elseif ($this->php_handling == Smarty::PHP_PASSTHRU) {
+ res = new _smarty_text($this, st);
+ } elseif ($this->php_handling == Smarty::PHP_QUOTE) {
+ res = new _smarty_text($this, htmlspecialchars('?>', ENT_QUOTES));
+ } elseif ($this->php_handling == Smarty::PHP_ALLOW) {
+ res = new _smarty_tag($this, $this->compiler->processNocacheCode('?>', true));
+ } elseif ($this->php_handling == Smarty::PHP_REMOVE) {
+ res = null;
+ }
+}
+ // '</script>' tag (only for PHP)
+template_element(res)::= PHPENDSCRIPT(st). {
+ if (!$this->lex->is_phpScript) {
+ res = new _smarty_text($this, st);
+ } else {
+ $this->lex->is_phpScript = false;
+ if ($this->php_handling == Smarty::PHP_PASSTHRU) {
+ res = new _smarty_text($this, st);
+ } elseif ($this->php_handling == Smarty::PHP_QUOTE) {
+ res = new _smarty_text($this, htmlspecialchars(st, ENT_QUOTES));
+ } elseif ($this->php_handling == Smarty::PHP_ALLOW) {
+ res = new _smarty_tag($this, $this->compiler->processNocacheCode('?>', true));
+ } elseif ($this->php_handling == Smarty::PHP_REMOVE) {
+ res = null;
+ }
+ }
+}
+
+ // '<%' tag
+template_element(res)::= ASPSTARTTAG(st). {
+ if ($this->php_handling == Smarty::PHP_PASSTHRU) {
+ res = new _smarty_text($this, st);
+ } elseif ($this->php_handling == Smarty::PHP_QUOTE) {
+ res = new _smarty_text($this, htmlspecialchars(st, ENT_QUOTES));
+ } elseif ($this->php_handling == Smarty::PHP_ALLOW) {
+ if ($this->asp_tags) {
+ if (!($this->smarty instanceof SmartyBC)) {
+ $this->compiler->trigger_template_error (self::Err3);
+ }
+ res = new _smarty_tag($this, $this->compiler->processNocacheCode('<%', true));
+ } else {
+ res = new _smarty_text($this, st);
+ }
+ } elseif ($this->php_handling == Smarty::PHP_REMOVE) {
+ if ($this->asp_tags) {
+ res = null;
+ } else {
+ res = new _smarty_text($this, st);
+ }
+ }
+}
+
+ // '%>' tag
+template_element(res)::= ASPENDTAG(st). {
+ if ($this->php_handling == Smarty::PHP_PASSTHRU) {
+ res = new _smarty_text($this, st);
+ } elseif ($this->php_handling == Smarty::PHP_QUOTE) {
+ res = new _smarty_text($this, htmlspecialchars('%>', ENT_QUOTES));
+ } elseif ($this->php_handling == Smarty::PHP_ALLOW) {
+ if ($this->asp_tags) {
+ res = new _smarty_tag($this, $this->compiler->processNocacheCode('%>', true));
+ } else {
+ res = new _smarty_text($this, st);
+ }
+ } elseif ($this->php_handling == Smarty::PHP_REMOVE) {
+ if ($this->asp_tags) {
+ res = null;
+ } else {
+ res = new _smarty_text($this, st);
+ }
+ }
+}
+
+
+ // XML tag
+template_element(res)::= XMLTAG. {
+ $this->compiler->tag_nocache = true;
+ $this->is_xml = true;
+ $save = $this->template->has_nocache_code;
+ res = new _smarty_tag($this, $this->compiler->processNocacheCode("<?php echo '<?xml';?>", $this->compiler, true));
+ $this->template->has_nocache_code = $save;
+}
+
+ // template text
+template_element(res)::= TEXT(o). {
+ if ($this->strip) {
+ res = new _smarty_text($this, preg_replace('![\t ]*[\r\n]+[\t ]*!', '', o));
+ } else {
+ res = new _smarty_text($this, o);
+ }
+}
+
+ // strip on
+template_element ::= STRIPON(d). {
+ $this->strip = true;
+}
+ // strip off
+template_element ::= STRIPOFF(d). {
+ $this->strip = false;
+}
+ // process source of inheritance child block
+template_element ::= BLOCKSOURCE(s). {
+ if ($this->strip) {
+ SMARTY_INTERNAL_COMPILE_BLOCK::blockSource($this->compiler, preg_replace('![\t ]*[\r\n]+[\t ]*!', '', s));
+ } else {
+ SMARTY_INTERNAL_COMPILE_BLOCK::blockSource($this->compiler, s);
+ }
+}
+
+ // Litteral
+literal(res) ::= LITERALSTART LITERALEND. {
+ res = '';
+}
+
+literal(res) ::= LITERALSTART literal_elements(l) LITERALEND. {
+ res = l;
+}
+
+literal_elements(res) ::= literal_elements(l1) literal_element(l2). {
+ res = l1.l2;
+}
+
+literal_elements(res) ::= . {
+ res = '';
+}
+
+literal_element(res) ::= literal(l). {
+ res = l;
+}
+
+literal_element(res) ::= LITERAL(l). {
+ res = l;
+}
+
+//
+// output tags start here
+//
+
+ // output with optional attributes
+smartytag(res) ::= LDEL value(e). {
+ res = $this->compiler->compileTag('private_print_expression',array(),array('value'=>e));
+}
+
+smartytag(res) ::= LDEL value(e) modifierlist(l) attributes(a). {
+ res = $this->compiler->compileTag('private_print_expression',a,array('value'=>e, 'modifierlist'=>l));
+}
+
+smartytag(res) ::= LDEL value(e) attributes(a). {
+ res = $this->compiler->compileTag('private_print_expression',a,array('value'=>e));
+}
+
+smartytag(res) ::= LDEL expr(e) modifierlist(l) attributes(a). {
+ res = $this->compiler->compileTag('private_print_expression',a,array('value'=>e,'modifierlist'=>l));
+}
+
+smartytag(res) ::= LDEL expr(e) attributes(a). {
+ res = $this->compiler->compileTag('private_print_expression',a,array('value'=>e));
+}
+
+//
+// Smarty tags start here
+//
+
+ // assign new style
+smartytag(res) ::= LDEL DOLLAR ID(i) EQUAL value(e). {
+ res = $this->compiler->compileTag('assign',array(array('value'=>e),array('var'=>"'".i."'")));
+}
+
+smartytag(res) ::= LDEL DOLLAR ID(i) EQUAL expr(e). {
+ res = $this->compiler->compileTag('assign',array(array('value'=>e),array('var'=>"'".i."'")));
+}
+
+smartytag(res) ::= LDEL DOLLAR ID(i) EQUAL expr(e) attributes(a). {
+ res = $this->compiler->compileTag('assign',array_merge(array(array('value'=>e),array('var'=>"'".i."'")),a));
+}
+
+smartytag(res) ::= LDEL varindexed(vi) EQUAL expr(e) attributes(a). {
+ res = $this->compiler->compileTag('assign',array_merge(array(array('value'=>e),array('var'=>vi['var'])),a),array('smarty_internal_index'=>vi['smarty_internal_index']));
+}
+
+ // tag with optional Smarty2 style attributes
+smartytag(res) ::= LDEL ID(i) attributes(a). {
+ if (defined(i)) {
+ res = $this->compiler->compileTag('private_print_expression',a,array('value'=>i));
+ } else {
+ res = $this->compiler->compileTag(i,a);
+ }
+}
+smartytag(res) ::= LDEL ID(i). {
+ if (defined(i)) {
+ res = $this->compiler->compileTag('private_print_expression',array(),array('value'=>i));
+ } else {
+ res = $this->compiler->compileTag(i,array());
+ }
+}
+
+
+ // tag with modifier and optional Smarty2 style attributes
+smartytag(res) ::= LDEL ID(i) modifierlist(l)attributes(a). {
+ if (defined(i)) {
+ res = $this->compiler->compileTag('private_print_expression',a,array('value'=>i, 'modifierlist'=>l));
+ } else {
+ res = '<?php ob_start();?>'.$this->compiler->compileTag(i,a).'<?php echo ';
+ res .= $this->compiler->compileTag('private_modifier',array(),array('modifierlist'=>l,'value'=>'ob_get_clean()')).';?>';
+ }
+}
+
+ // registered object tag
+smartytag(res) ::= LDEL ID(i) PTR ID(m) attributes(a). {
+ res = $this->compiler->compileTag(i,a,array('object_method'=>m));
+}
+
+ // registered object tag with modifiers
+smartytag(res) ::= LDEL ID(i) PTR ID(me) modifierlist(l) attributes(a). {
+ res = '<?php ob_start();?>'.$this->compiler->compileTag(i,a,array('object_method'=>me)).'<?php echo ';
+ res .= $this->compiler->compileTag('private_modifier',array(),array('modifierlist'=>l,'value'=>'ob_get_clean()')).';?>';
+}
+
+ // {if}, {elseif} and {while} tag
+smartytag(res) ::= LDELIF(i) expr(ie). {
+ $tag = trim(substr(i,$this->lex->ldel_length));
+ res = $this->compiler->compileTag(($tag == 'else if')? 'elseif' : $tag,array(),array('if condition'=>ie));
+}
+
+smartytag(res) ::= LDELIF(i) expr(ie) attributes(a). {
+ $tag = trim(substr(i,$this->lex->ldel_length));
+ res = $this->compiler->compileTag(($tag == 'else if')? 'elseif' : $tag,a,array('if condition'=>ie));
+}
+
+smartytag(res) ::= LDELIF(i) statement(ie). {
+ $tag = trim(substr(i,$this->lex->ldel_length));
+ res = $this->compiler->compileTag(($tag == 'else if')? 'elseif' : $tag,array(),array('if condition'=>ie));
+}
+
+smartytag(res) ::= LDELIF(i) statement(ie) attributes(a). {
+ $tag = trim(substr(i,$this->lex->ldel_length));
+ res = $this->compiler->compileTag(($tag == 'else if')? 'elseif' : $tag,a,array('if condition'=>ie));
+}
+
+ // {for} tag
+smartytag(res) ::= LDELFOR statements(st) SEMICOLON optspace expr(ie) SEMICOLON optspace DOLLAR varvar(v2) foraction(e2) attributes(a). {
+ res = $this->compiler->compileTag('for',array_merge(a,array(array('start'=>st),array('ifexp'=>ie),array('var'=>v2),array('step'=>e2))),1);
+}
+
+ foraction(res) ::= EQUAL expr(e). {
+ res = '='.e;
+}
+
+ foraction(res) ::= INCDEC(e). {
+ res = e;
+}
+
+smartytag(res) ::= LDELFOR statement(st) TO expr(v) attributes(a). {
+ res = $this->compiler->compileTag('for',array_merge(a,array(array('start'=>st),array('to'=>v))),0);
+}
+
+smartytag(res) ::= LDELFOR statement(st) TO expr(v) STEP expr(v2) attributes(a). {
+ res = $this->compiler->compileTag('for',array_merge(a,array(array('start'=>st),array('to'=>v),array('step'=>v2))),0);
+}
+
+ // {foreach} tag
+smartytag(res) ::= LDELFOREACH attributes(a). {
+ res = $this->compiler->compileTag('foreach',a);
+}
+
+ // {foreach $array as $var} tag
+smartytag(res) ::= LDELFOREACH SPACE value(v1) AS DOLLAR varvar(v0) attributes(a). {
+ res = $this->compiler->compileTag('foreach',array_merge(a,array(array('from'=>v1),array('item'=>v0))));
+}
+
+smartytag(res) ::= LDELFOREACH SPACE value(v1) AS DOLLAR varvar(v2) APTR DOLLAR varvar(v0) attributes(a). {
+ res = $this->compiler->compileTag('foreach',array_merge(a,array(array('from'=>v1),array('item'=>v0),array('key'=>v2))));
+}
+
+smartytag(res) ::= LDELFOREACH SPACE expr(e) AS DOLLAR varvar(v0) attributes(a). {
+ res = $this->compiler->compileTag('foreach',array_merge(a,array(array('from'=>e),array('item'=>v0))));
+}
+
+smartytag(res) ::= LDELFOREACH SPACE expr(e) AS DOLLAR varvar(v1) APTR DOLLAR varvar(v0) attributes(a). {
+ res = $this->compiler->compileTag('foreach',array_merge(a,array(array('from'=>e),array('item'=>v0),array('key'=>v1))));
+}
+
+ // {setfilter}
+smartytag(res) ::= LDELSETFILTER ID(m) modparameters(p). {
+ res = $this->compiler->compileTag('setfilter',array(),array('modifier_list'=>array(array_merge(array(m),p))));
+}
+
+smartytag(res) ::= LDELSETFILTER ID(m) modparameters(p) modifierlist(l). {
+ res = $this->compiler->compileTag('setfilter',array(),array('modifier_list'=>array_merge(array(array_merge(array(m),p)),l)));
+}
+
+ // {$smarty.block.child} or {$smarty.block.parent}
+smartytag(res) ::= LDEL SMARTYBLOCKCHILDPARENT(i). {
+ $j = strrpos(i,'.');
+ if (i[$j+1] == 'c') {
+ // {$smarty.block.child}
+ res = SMARTY_INTERNAL_COMPILE_BLOCK::compileChildBlock($this->compiler);
+ } else {
+ // {$smarty.block.parent}
+ res = SMARTY_INTERNAL_COMPILE_BLOCK::compileParentBlock($this->compiler);
+ }
+}
+
+
+ // end of block tag {/....}
+smartytag(res) ::= LDELSLASH ID(i). {
+ res = $this->compiler->compileTag(i.'close',array());
+}
+
+smartytag(res) ::= LDELSLASH ID(i) modifierlist(l). {
+ res = $this->compiler->compileTag(i.'close',array(),array('modifier_list'=>l));
+}
+
+ // end of block object tag {/....}
+smartytag(res) ::= LDELSLASH ID(i) PTR ID(m). {
+ res = $this->compiler->compileTag(i.'close',array(),array('object_method'=>m));
+}
+
+smartytag(res) ::= LDELSLASH ID(i) PTR ID(m) modifierlist(l). {
+ res = $this->compiler->compileTag(i.'close',array(),array('object_method'=>m, 'modifier_list'=>l));
+}
+
+//
+//Attributes of Smarty tags
+//
+ // list of attributes
+attributes(res) ::= attributes(a1) attribute(a2). {
+ res = a1;
+ res[] = a2;
+}
+
+ // single attribute
+attributes(res) ::= attribute(a). {
+ res = array(a);
+}
+
+ // no attributes
+attributes(res) ::= . {
+ res = array();
+}
+
+ // attribute
+attribute(res) ::= SPACE ID(v) EQUAL ID(id). {
+ if (preg_match('~^true$~i', id)) {
+ res = array(v=>'true');
+ } elseif (preg_match('~^false$~i', id)) {
+ res = array(v=>'false');
+ } elseif (preg_match('~^null$~i', id)) {
+ res = array(v=>'null');
+ } else {
+ res = array(v=>"'".id."'");
+ }
+}
+
+attribute(res) ::= ATTR(v) expr(e). {
+ res = array(trim(v," =\n\r\t")=>e);
+}
+
+attribute(res) ::= ATTR(v) value(e). {
+ res = array(trim(v," =\n\r\t")=>e);
+}
+
+attribute(res) ::= SPACE ID(v). {
+ res = "'".v."'";
+}
+
+attribute(res) ::= SPACE expr(e). {
+ res = e;
+}
+
+attribute(res) ::= SPACE value(v). {
+ res = v;
+}
+
+attribute(res) ::= SPACE INTEGER(i) EQUAL expr(e). {
+ res = array(i=>e);
+}
+
+
+
+//
+// statement
+//
+statements(res) ::= statement(s). {
+ res = array(s);
+}
+
+statements(res) ::= statements(s1) COMMA statement(s). {
+ s1[]=s;
+ res = s1;
+}
+
+statement(res) ::= DOLLAR varvar(v) EQUAL expr(e). {
+ res = array('var' => v, 'value'=>e);
+}
+
+statement(res) ::= varindexed(vi) EQUAL expr(e). {
+ res = array('var' => vi, 'value'=>e);
+}
+
+statement(res) ::= OPENP statement(st) CLOSEP. {
+ res = st;
+}
+
+
+//
+// expressions
+//
+
+ // single value
+expr(res) ::= value(v). {
+ res = v;
+}
+
+ // ternary
+expr(res) ::= ternary(v). {
+ res = v;
+}
+
+ // resources/streams
+expr(res) ::= DOLLAR ID(i) COLON ID(i2). {
+ res = '$_smarty_tpl->getStreamVariable(\''. i .'://'. i2 . '\')';
+}
+
+ // arithmetic expression
+expr(res) ::= expr(e) MATH(m) value(v). {
+ res = e . trim(m) . v;
+}
+
+expr(res) ::= expr(e) UNIMATH(m) value(v). {
+ res = e . trim(m) . v;
+}
+
+ // bit operation
+expr(res) ::= expr(e) ANDSYM(m) value(v). {
+ res = e . trim(m) . v;
+}
+
+ // array
+expr(res) ::= array(a). {
+ res = a;
+}
+
+ // modifier
+expr(res) ::= expr(e) modifierlist(l). {
+ res = $this->compiler->compileTag('private_modifier',array(),array('value'=>e,'modifierlist'=>l));
+}
+
+// if expression
+ // simple expression
+expr(res) ::= expr(e1) ifcond(c) expr(e2). {
+ res = e1.c.e2;
+}
+
+expr(res) ::= expr(e1) ISIN array(a). {
+ res = 'in_array('.e1.','.a.')';
+}
+
+expr(res) ::= expr(e1) ISIN value(v). {
+ res = 'in_array('.e1.',(array)'.v.')';
+}
+
+expr(res) ::= expr(e1) lop(o) expr(e2). {
+ res = e1.o.e2;
+}
+
+expr(res) ::= expr(e1) ISDIVBY expr(e2). {
+ res = '!('.e1.' % '.e2.')';
+}
+
+expr(res) ::= expr(e1) ISNOTDIVBY expr(e2). {
+ res = '('.e1.' % '.e2.')';
+}
+
+expr(res) ::= expr(e1) ISEVEN. {
+ res = '!(1 & '.e1.')';
+}
+
+expr(res) ::= expr(e1) ISNOTEVEN. {
+ res = '(1 & '.e1.')';
+}
+
+expr(res) ::= expr(e1) ISEVENBY expr(e2). {
+ res = '!(1 & '.e1.' / '.e2.')';
+}
+
+expr(res) ::= expr(e1) ISNOTEVENBY expr(e2). {
+ res = '(1 & '.e1.' / '.e2.')';
+}
+
+expr(res) ::= expr(e1) ISODD. {
+ res = '(1 & '.e1.')';
+}
+
+expr(res) ::= expr(e1) ISNOTODD. {
+ res = '!(1 & '.e1.')';
+}
+
+expr(res) ::= expr(e1) ISODDBY expr(e2). {
+ res = '(1 & '.e1.' / '.e2.')';
+}
+
+expr(res) ::= expr(e1) ISNOTODDBY expr(e2). {
+ res = '!(1 & '.e1.' / '.e2.')';
+}
+
+expr(res) ::= variable(v1) INSTANCEOF(i) ns1(v2). {
+// self::$prefix_number++;
+// $this->compiler->prefix_code[] = '<?php $_tmp'.self::$prefix_number.'='.v1.';? >';
+ // res = '$_tmp'.self::$prefix_number.i.v2;
+ res = v1.i.v2;
+ }
+
+
+//
+// ternary
+//
+ternary(res) ::= OPENP expr(v) CLOSEP QMARK DOLLAR ID(e1) COLON expr(e2). {
+ res = v.' ? '. $this->compileVariable("'".e1."'") . ' : '.e2;
+}
+
+ternary(res) ::= OPENP expr(v) CLOSEP QMARK expr(e1) COLON expr(e2). {
+ res = v.' ? '.e1.' : '.e2;
+}
+
+ // value
+value(res) ::= variable(v). {
+ res = v;
+}
+
+ // +/- value
+value(res) ::= UNIMATH(m) value(v). {
+ res = m.v;
+}
+
+ // logical negation
+value(res) ::= NOT value(v). {
+ res = '!'.v;
+}
+
+value(res) ::= TYPECAST(t) value(v). {
+ res = t.v;
+}
+
+value(res) ::= variable(v) INCDEC(o). {
+ res = v.o;
+}
+
+ // numeric
+value(res) ::= HEX(n). {
+ res = n;
+}
+
+value(res) ::= INTEGER(n). {
+ res = n;
+}
+
+value(res) ::= INTEGER(n1) DOT INTEGER(n2). {
+ res = n1.'.'.n2;
+}
+
+value(res) ::= INTEGER(n1) DOT. {
+ res = n1.'.';
+}
+
+value(res) ::= DOT INTEGER(n1). {
+ res = '.'.n1;
+}
+
+ // ID, true, false, null
+value(res) ::= ID(id). {
+ if (defined(id)) {
+ res = id;
+ } else {
+ res = "'".id."'";
+ }
+}
+
+ // function call
+value(res) ::= function(f). {
+ res = f;
+}
+
+ // expression
+value(res) ::= OPENP expr(e) CLOSEP. {
+ res = "(". e .")";
+}
+
+ // singele quoted string
+value(res) ::= SINGLEQUOTESTRING(t). {
+ res = t;
+}
+
+ // double quoted string
+value(res) ::= doublequoted_with_quotes(s). {
+ res = s;
+}
+
+
+value(res) ::= varindexed(vi) DOUBLECOLON static_class_access(r). {
+ self::$prefix_number++;
+ if (vi['var'] == '\'smarty\'') {
+ $this->compiler->prefix_code[] = '<?php $_tmp'.self::$prefix_number.' = '. $this->compiler->compileTag('private_special_variable',array(),vi['smarty_internal_index']).';?>';
+ } else {
+ $this->compiler->prefix_code[] = '<?php $_tmp'.self::$prefix_number.' = '. $this->compileVariable(vi['var']).vi['smarty_internal_index'].';?>';
+ }
+ res = '$_tmp'.self::$prefix_number.'::'.r;
+
+}
+
+ // Smarty tag
+value(res) ::= smartytag(st) RDEL. {
+ self::$prefix_number++;
+ $this->compiler->prefix_code[] = '<?php ob_start();?>'.st.'<?php $_tmp'.self::$prefix_number.'=ob_get_clean();?>';
+ res = '$_tmp'.self::$prefix_number;
+}
+
+value(res) ::= value(v) modifierlist(l). {
+ res = $this->compiler->compileTag('private_modifier',array(),array('value'=>v,'modifierlist'=>l));
+}
+ // name space constant
+value(res) ::= NAMESPACE(c). {
+ res = c;
+}
+
+
+ // static class access
+value(res) ::= ns1(c)DOUBLECOLON static_class_access(s). {
+ if (!$this->security || isset($this->smarty->registered_classes[c]) || $this->smarty->security_policy->isTrustedStaticClass(c, $this->compiler)) {
+ if (isset($this->smarty->registered_classes[c])) {
+ res = $this->smarty->registered_classes[c].'::'.s;
+ } else {
+ res = c.'::'.s;
+ }
+ } else {
+ $this->compiler->error ("static class '".c."' is undefined or not allowed by security setting");
+ }
+}
+//
+// namespace stuff
+//
+
+ns1(res) ::= ID(i). {
+ res = i;
+}
+
+ns1(res) ::= NAMESPACE(i). {
+ res = i;
+}
+
+ns1(res) ::= variable(v). {
+ res = v;
+}
+
+
+
+
+//
+// variables
+//
+ // Smarty variable (optional array)
+variable(res) ::= varindexed(vi). {
+ if (vi['var'] == '\'smarty\'') {
+ $smarty_var = $this->compiler->compileTag('private_special_variable',array(),vi['smarty_internal_index']);
+ res = $smarty_var;
+ } else {
+ // used for array reset,next,prev,end,current
+ $this->last_variable = vi['var'];
+ $this->last_index = vi['smarty_internal_index'];
+ res = $this->compileVariable(vi['var']).vi['smarty_internal_index'];
+ }
+}
+
+ // variable with property
+variable(res) ::= DOLLAR varvar(v) AT ID(p). {
+ res = '$_smarty_tpl->tpl_vars['. v .']->'.p;
+}
+
+ // object
+variable(res) ::= object(o). {
+ res = o;
+}
+
+ // config variable
+variable(res) ::= HATCH ID(i) HATCH. {
+ res = '$_smarty_tpl->getConfigVariable( \''. i .'\')';
+}
+
+variable(res) ::= HATCH ID(i) HATCH arrayindex(a). {
+ res = '(is_array($tmp = $_smarty_tpl->getConfigVariable( \''. i .'\')) ? $tmp'.a.' :null)';
+}
+
+variable(res) ::= HATCH variable(v) HATCH. {
+ res = '$_smarty_tpl->getConfigVariable( '. v .')';
+}
+
+variable(res) ::= HATCH variable(v) HATCH arrayindex(a). {
+ res = '(is_array($tmp = $_smarty_tpl->getConfigVariable( '. v .')) ? $tmp'.a.' : null)';
+}
+
+varindexed(res) ::= DOLLAR varvar(v) arrayindex(a). {
+ res = array('var'=>v, 'smarty_internal_index'=>a);
+}
+
+//
+// array index
+//
+ // multiple array index
+arrayindex(res) ::= arrayindex(a1) indexdef(a2). {
+ res = a1.a2;
+}
+
+ // no array index
+arrayindex ::= . {
+ return;
+}
+
+// single index definition
+ // Smarty2 style index
+indexdef(res) ::= DOT DOLLAR varvar(v). {
+ res = '['.$this->compileVariable(v).']';
+}
+
+indexdef(res) ::= DOT DOLLAR varvar(v) AT ID(p). {
+ res = '['.$this->compileVariable(v).'->'.p.']';
+}
+
+indexdef(res) ::= DOT ID(i). {
+ if (defined(i)) {
+ res = "[". i ."]";
+ } else {
+ res = "['". i ."']";
+ }
+}
+
+indexdef(res) ::= DOT INTEGER(n). {
+ res = "[". n ."]";
+}
+
+
+indexdef(res) ::= DOT LDEL expr(e) RDEL. {
+ res = "[". e ."]";
+}
+
+ // section tag index
+indexdef(res) ::= OPENB ID(i)CLOSEB. {
+ res = '['.$this->compiler->compileTag('private_special_variable',array(),'[\'section\'][\''.i.'\'][\'index\']').']';
+}
+
+indexdef(res) ::= OPENB ID(i) DOT ID(i2) CLOSEB. {
+ res = '['.$this->compiler->compileTag('private_special_variable',array(),'[\'section\'][\''.i.'\'][\''.i2.'\']').']';
+}
+
+ // PHP style index
+indexdef(res) ::= OPENB expr(e) CLOSEB. {
+ res = "[". e ."]";
+}
+
+ // f�r assign append array
+indexdef(res) ::= OPENB CLOSEB. {
+ res = '[]';
+}
+
+
+//
+// variable variable names
+//
+ // singel identifier element
+varvar(res) ::= varvarele(v). {
+ res = v;
+}
+
+ // sequence of identifier elements
+varvar(res) ::= varvar(v1) varvarele(v2). {
+ res = v1.'.'.v2;
+}
+
+ // fix sections of element
+varvarele(res) ::= ID(s). {
+ res = '\''.s.'\'';
+}
+
+ // variable sections of element
+varvarele(res) ::= LDEL expr(e) RDEL. {
+ res = '('.e.')';
+}
+
+//
+// objects
+//
+object(res) ::= varindexed(vi) objectchain(oc). {
+ if (vi['var'] == '\'smarty\'') {
+ res = $this->compiler->compileTag('private_special_variable',array(),vi['smarty_internal_index']).oc;
+ } else {
+ res = $this->compileVariable(vi['var']).vi['smarty_internal_index'].oc;
+ }
+}
+
+ // single element
+objectchain(res) ::= objectelement(oe). {
+ res = oe;
+}
+
+ // chain of elements
+objectchain(res) ::= objectchain(oc) objectelement(oe). {
+ res = oc.oe;
+}
+
+ // variable
+objectelement(res)::= PTR ID(i) arrayindex(a). {
+ if ($this->security && substr(i,0,1) == '_') {
+ $this->compiler->trigger_template_error (self::Err1);
+ }
+ res = '->'.i.a;
+}
+
+objectelement(res)::= PTR DOLLAR varvar(v) arrayindex(a). {
+ if ($this->security) {
+ $this->compiler->trigger_template_error (self::Err2);
+ }
+ res = '->{'.$this->compileVariable(v).a.'}';
+}
+
+objectelement(res)::= PTR LDEL expr(e) RDEL arrayindex(a). {
+ if ($this->security) {
+ $this->compiler->trigger_template_error (self::Err2);
+ }
+ res = '->{'.e.a.'}';
+}
+
+objectelement(res)::= PTR ID(ii) LDEL expr(e) RDEL arrayindex(a). {
+ if ($this->security) {
+ $this->compiler->trigger_template_error (self::Err2);
+ }
+ res = '->{\''.ii.'\'.'.e.a.'}';
+}
+
+ // method
+objectelement(res)::= PTR method(f). {
+ res = '->'.f;
+}
+
+
+//
+// function
+//
+function(res) ::= ns1(f) OPENP params(p) CLOSEP. {
+ if (!$this->security || $this->smarty->security_policy->isTrustedPhpFunction(f, $this->compiler)) {
+ if (strcasecmp(f,'isset') === 0 || strcasecmp(f,'empty') === 0 || strcasecmp(f,'array') === 0 || is_callable(f)) {
+ $func_name = strtolower(f);
+ if ($func_name == 'isset') {
+ if (count(p) == 0) {
+ $this->compiler->trigger_template_error ('Illegal number of paramer in "isset()"');
+ }
+ $par = implode(',',p);
+ if (strncasecmp($par,'$_smarty_tpl->getConfigVariable',strlen('$_smarty_tpl->getConfigVariable')) === 0) {
+ self::$prefix_number++;
+ $this->compiler->prefix_code[] = '<?php $_tmp'.self::$prefix_number.'='.str_replace(')',', false)',$par).';?>';
+ $isset_par = '$_tmp'.self::$prefix_number;
+ } else {
+ $isset_par=str_replace("')->value","',null,true,false)->value",$par);
+ }
+ res = f . "(". $isset_par .")";
+ } elseif (in_array($func_name,array('empty','reset','current','end','prev','next'))){
+ if (count(p) != 1) {
+ $this->compiler->trigger_template_error ('Illegal number of paramer in "empty()"');
+ }
+ if ($func_name == 'empty') {
+ res = $func_name.'('.str_replace("')->value","',null,true,false)->value",p[0]).')';
+ } else {
+ res = $func_name.'('.p[0].')';
+ }
+ } else {
+ res = f . "(". implode(',',p) .")";
+ }
+ } else {
+ $this->compiler->trigger_template_error ("unknown function \"" . f . "\"");
+ }
+ }
+}
+
+
+//
+// method
+//
+method(res) ::= ID(f) OPENP params(p) CLOSEP. {
+ if ($this->security && substr(f,0,1) == '_') {
+ $this->compiler->trigger_template_error (self::Err1);
+ }
+ res = f . "(". implode(',',p) .")";
+}
+
+method(res) ::= DOLLAR ID(f) OPENP params(p) CLOSEP. {
+ if ($this->security) {
+ $this->compiler->trigger_template_error (self::Err2);
+ }
+ self::$prefix_number++;
+ $this->compiler->prefix_code[] = '<?php $_tmp'.self::$prefix_number.'='.$this->compileVariable("'".f."'").';?>';
+ res = '$_tmp'.self::$prefix_number.'('. implode(',',p) .')';
+}
+
+// function/method parameter
+ // multiple parameters
+params(res) ::= params(p) COMMA expr(e). {
+ res = array_merge(p,array(e));
+}
+
+ // single parameter
+params(res) ::= expr(e). {
+ res = array(e);
+}
+
+ // kein parameter
+params(res) ::= . {
+ res = array();
+}
+
+//
+// modifier
+//
+modifierlist(res) ::= modifierlist(l) modifier(m) modparameters(p). {
+ res = array_merge(l,array(array_merge(m,p)));
+}
+
+modifierlist(res) ::= modifier(m) modparameters(p). {
+ res = array(array_merge(m,p));
+}
+
+modifier(res) ::= VERT AT ID(m). {
+ res = array(m);
+}
+
+modifier(res) ::= VERT ID(m). {
+ res = array(m);
+}
+
+//
+// modifier parameter
+//
+ // multiple parameter
+modparameters(res) ::= modparameters(mps) modparameter(mp). {
+ res = array_merge(mps,mp);
+}
+
+ // no parameter
+modparameters(res) ::= . {
+ res = array();
+}
+
+ // parameter expression
+modparameter(res) ::= COLON value(mp). {
+ res = array(mp);
+}
+
+modparameter(res) ::= COLON array(mp). {
+ res = array(mp);
+}
+
+ // static class methode call
+static_class_access(res) ::= method(m). {
+ res = m;
+}
+
+ // static class methode call with object chainig
+static_class_access(res) ::= method(m) objectchain(oc). {
+ res = m.oc;
+}
+
+ // static class constant
+static_class_access(res) ::= ID(v). {
+ res = v;
+}
+
+ // static class variables
+static_class_access(res) ::= DOLLAR ID(v) arrayindex(a). {
+ res = '$'.v.a;
+}
+
+ // static class variables with object chain
+static_class_access(res) ::= DOLLAR ID(v) arrayindex(a) objectchain(oc). {
+ res = '$'.v.a.oc;
+}
+
+
+// if conditions and operators
+ifcond(res) ::= EQUALS. {
+ res = '==';
+}
+
+ifcond(res) ::= NOTEQUALS. {
+ res = '!=';
+}
+
+ifcond(res) ::= GREATERTHAN. {
+ res = '>';
+}
+
+ifcond(res) ::= LESSTHAN. {
+ res = '<';
+}
+
+ifcond(res) ::= GREATEREQUAL. {
+ res = '>=';
+}
+
+ifcond(res) ::= LESSEQUAL. {
+ res = '<=';
+}
+
+ifcond(res) ::= IDENTITY. {
+ res = '===';
+}
+
+ifcond(res) ::= NONEIDENTITY. {
+ res = '!==';
+}
+
+ifcond(res) ::= MOD. {
+ res = '%';
+}
+
+lop(res) ::= LAND. {
+ res = '&&';
+}
+
+lop(res) ::= LOR. {
+ res = '||';
+}
+
+lop(res) ::= LXOR. {
+ res = ' XOR ';
+}
+
+//
+// ARRAY element assignment
+//
+array(res) ::= OPENB arrayelements(a) CLOSEB. {
+ res = 'array('.a.')';
+}
+
+arrayelements(res) ::= arrayelement(a). {
+ res = a;
+}
+
+arrayelements(res) ::= arrayelements(a1) COMMA arrayelement(a). {
+ res = a1.','.a;
+}
+
+arrayelements ::= . {
+ return;
+}
+
+arrayelement(res) ::= value(e1) APTR expr(e2). {
+ res = e1.'=>'.e2;
+}
+
+arrayelement(res) ::= ID(i) APTR expr(e2). {
+ res = '\''.i.'\'=>'.e2;
+}
+
+arrayelement(res) ::= expr(e). {
+ res = e;
+}
+
+
+//
+// double qouted strings
+//
+doublequoted_with_quotes(res) ::= QUOTE QUOTE. {
+ res = "''";
+}
+
+doublequoted_with_quotes(res) ::= QUOTE doublequoted(s) QUOTE. {
+ res = s->to_smarty_php();
+}
+
+
+doublequoted(res) ::= doublequoted(o1) doublequotedcontent(o2). {
+ o1->append_subtree(o2);
+ res = o1;
+}
+
+doublequoted(res) ::= doublequotedcontent(o). {
+ res = new _smarty_doublequoted($this, o);
+}
+
+doublequotedcontent(res) ::= BACKTICK variable(v) BACKTICK. {
+ res = new _smarty_code($this, '(string)'.v);
+}
+
+doublequotedcontent(res) ::= BACKTICK expr(e) BACKTICK. {
+ res = new _smarty_code($this, '(string)'.e);
+}
+
+doublequotedcontent(res) ::= DOLLARID(i). {
+ res = new _smarty_code($this, '(string)$_smarty_tpl->tpl_vars[\''. substr(i,1) .'\']->value');
+}
+
+doublequotedcontent(res) ::= LDEL variable(v) RDEL. {
+ res = new _smarty_code($this, '(string)'.v);
+}
+
+doublequotedcontent(res) ::= LDEL expr(e) RDEL. {
+ res = new _smarty_code($this, '(string)('.e.')');
+}
+
+doublequotedcontent(res) ::= smartytag(st) RDEL. {
+ res = new _smarty_tag($this, st);
+}
+
+doublequotedcontent(res) ::= TEXT(o). {
+ res = new _smarty_dq_content($this, o);
+}
+
+
+//
+// optional space
+//
+optspace(res) ::= SPACE(s). {
+ res = s;
+}
+
+optspace(res) ::= . {
+ res = '';
+}