diff --git a/library/smarty/lexer/smarty_internal_templatelexer.plex b/library/smarty/lexer/smarty_internal_templatelexer.plex new file mode 100644 --- /dev/null +++ b/library/smarty/lexer/smarty_internal_templatelexer.plex @@ -0,0 +1,770 @@ + 'TEXT', 2 => 'TAG', 3 => 'TAGBODY', 4 => 'LITERAL', 5 => 'DOUBLEQUOTEDSTRING', + 6 => 'CHILDBODY', 7 => 'CHILDBLOCK', 8 => 'CHILDLITERAL'); + + /** + * storage for assembled token patterns + * + * @var string + */ + private $yy_global_pattern1 = null; + + private $yy_global_pattern2 = null; + + private $yy_global_pattern3 = null; + + private $yy_global_pattern4 = null; + + private $yy_global_pattern5 = null; + + private $yy_global_pattern6 = null; + + private $yy_global_pattern7 = null; + + private $yy_global_pattern8 = null; + + /** + * token names + * + * @var array + */ + public $smarty_token_names = array( // Text for parser error messages + 'NOT' => '(!,not)', + 'OPENP' => '(', + 'CLOSEP' => ')', + 'OPENB' => '[', + 'CLOSEB' => ']', + 'PTR' => '->', + 'APTR' => '=>', + 'EQUAL' => '=', + 'NUMBER' => 'number', + 'UNIMATH' => '+" , "-', + 'MATH' => '*" , "/" , "%', + 'INCDEC' => '++" , "--', + 'SPACE' => ' ', + 'DOLLAR' => '$', + 'SEMICOLON' => ';', + 'COLON' => ':', + 'DOUBLECOLON' => '::', + 'AT' => '@', + 'HATCH' => '#', + 'QUOTE' => '"', + 'BACKTICK' => '`', + 'VERT' => '"|" modifier', + 'DOT' => '.', + 'COMMA' => '","', + 'QMARK' => '"?"', + 'ID' => 'id, name', + 'TEXT' => 'text', + 'LDELSLASH' => '{/..} closing tag', + 'LDEL' => '{...} Smarty tag', + 'COMMENT' => 'comment', + 'AS' => 'as', + 'TO' => 'to', + 'PHP' => '" '"<", "==" ... logical operator', + 'TLOGOP' => '"lt", "eq" ... logical operator; "is div by" ... if condition', + 'SCOND' => '"is even" ... if condition', + ); + + /** + * 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~i', $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 = '
'; + } + + /* + * Check if this tag is autoliteral + */ + public function isAutoLiteral () + { + return $this->smarty->auto_literal && isset($this->value[$this->ldel_length]) ? strpos(" \n\t\r", $this->value[$this->ldel_length]) !== false : false; + } + + /*!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|\$|`\$|"))~ + namespace = ~([0-9]*[a-zA-Z_]\w*)?(\\[0-9]*[a-zA-Z_]\w*)+~ + all = ~[\S\s]+~ + emptyjava = ~[{][}]~ + phpstart = ~(<[?]((php\s+|=)|\s+))|(<[%])|(<[?]xml\s+)|()|([?][>])|([%][>])|(SMARTYldel\s*php(.*?)SMARTYrdel)|(SMARTYldel\s*[/]phpSMARTYrdel)~ + slash = ~[/]~ + ldel = ~SMARTYldel\s*~ + rdel = ~\s*SMARTYrdel~ + nocacherdel = ~(\s+nocache)?\s*SMARTYrdel~ + notblockid = ~(?:(?!block)[0-9]*[a-zA-Z_]\w*)~ + smartyblockchildparent = ~[\$]smarty\.block\.(child|parent)~ + integer = ~\d+~ + hex = ~0[xX][0-9a-fA-F]+~ + math = ~\s*([*]{1,2}|[%/^&]|[<>]{2})\s*~ + comment = ~SMARTYldel[*]~ + incdec = ~([+]|[-]){2}~ + unimath = ~\s*([+]|[-])\s*~ + openP = ~\s*[(]\s*~ + closeP = ~\s*[)]~ + openB = ~\[\s*~ + closeB = ~\s*\]~ + dollar = ~[$]~ + dot = ~[.]~ + comma = ~\s*[,]\s*~ + doublecolon = ~[:]{2}~ + colon = ~\s*[:]\s*~ + at = ~[@]~ + hatch = ~[#]~ + semicolon = ~\s*[;]\s*~ + equal = ~\s*[=]\s*~ + space = ~\s+~ + ptr = ~\s*[-][>]\s*~ + aptr = ~\s*[=][>]\s*~ + singlequotestring = ~'[^'\\]*(?:\\.[^'\\]*)*'~ + backtick = ~[`]~ + vert = ~[|]~ + 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~ + lop = ~\s*(([!=][=]{1,2})|([<][=>]?)|([>][=]?)|[&|]{2})\s*~ + tlop = ~\s+(eq|ne|neq|gt|ge|gte|lt|le|lte|mod|and|or|xor|(is\s+(not\s+)?(odd|even|div)\s+by))\s+~ + scond = ~\s+is\s+(not\s+)?(odd|even)~ + 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+)~ + 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 { + preg_match("~[*]{$this->rdel}~",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter); + if (isset($match[0][1])) { + $to = $match[0][1] + strlen($match[0][0]); + } else { + $this->compiler->trigger_template_error ("missing or misspelled comment closing tag '*{$this->smarty->right_delimiter}'"); + } + $this->value = substr($this->data,$this->counter,$to-$this->counter); + return false; + } + phpstart { + $obj = new Smarty_Internal_Compile_Private_Php(); + $obj->parsePhp($this); + } + 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 ($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->yypushstate(self::TAG); + return true; + } + } + rdel { + $this->token = Smarty_Internal_Templateparser::TP_TEXT; + } + text { + $to = strlen($this->data); + preg_match("~($this->ldel)|([<]script\s+language\s*=\s*[\"\']?\s*php\s*[\"\']?\s*[>])|([<][?])|([<][%])|([?][>])|([%][>])~i",$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 TAG + ldel if { + $this->token = Smarty_Internal_Templateparser::TP_LDELIF; + $this->yybegin(self::TAGBODY); + $this->taglineno = $this->line; + } + ldel for { + $this->token = Smarty_Internal_Templateparser::TP_LDELFOR; + $this->yybegin(self::TAGBODY); + $this->taglineno = $this->line; + } + ldel foreach { + $this->token = Smarty_Internal_Templateparser::TP_LDELFOREACH; + $this->yybegin(self::TAGBODY); + $this->taglineno = $this->line; + } + ldel setfilter { + $this->token = Smarty_Internal_Templateparser::TP_LDELSETFILTER; + $this->yybegin(self::TAGBODY); + $this->taglineno = $this->line; + } + ldel id nocacherdel { + $this->yypopstate(); + $this->token = Smarty_Internal_Templateparser::TP_SIMPLETAG; + $this->taglineno = $this->line; + } + ldel slash notblockid rdel { + $this->yypopstate(); + $this->token = Smarty_Internal_Templateparser::TP_CLOSETAG; + $this->taglineno = $this->line; + } + ldel dollar id nocacherdel { + if ($this->_yy_stack[count($this->_yy_stack)-1] == self::TEXT) { + $this->yypopstate(); + $this->token = Smarty_Internal_Templateparser::TP_SIMPLEOUTPUT; + $this->taglineno = $this->line; + } else { + $this->value = $this->smarty->left_delimiter; + $this->token = Smarty_Internal_Templateparser::TP_LDEL; + $this->yybegin(self::TAGBODY); + $this->taglineno = $this->line; + } + } + ldel slash { + $this->token = Smarty_Internal_Templateparser::TP_LDELSLASH; + $this->yybegin(self::TAGBODY); + $this->taglineno = $this->line; + } + ldel { + $this->token = Smarty_Internal_Templateparser::TP_LDEL; + $this->yybegin(self::TAGBODY); + $this->taglineno = $this->line; + } + */ + /*!lex2php + %statename TAGBODY + rdel { + $this->token = Smarty_Internal_Templateparser::TP_RDEL; + $this->yypopstate(); + } + 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 id { + $this->token = Smarty_Internal_Templateparser::TP_DOLLARID; + } + dollar { + $this->token = Smarty_Internal_Templateparser::TP_DOLLAR; + } + 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; + } + lop { + $this->token = Smarty_Internal_Templateparser::TP_LOGOP; + } + tlop { + $this->token = Smarty_Internal_Templateparser::TP_TLOGOP; + } + scond { + $this->token = Smarty_Internal_Templateparser::TP_SINGLECOND; + } + not{ + $this->token = Smarty_Internal_Templateparser::TP_NOT; + } + 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; + } + 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 ($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->yypushstate(self::TAG); + return true; + } + } + 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}~i",$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 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->yypushstate(self::TAG); + return true; + } + } + ldel id { + 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->yypushstate(self::TAG); + return true; + } + } + 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->taglineno = $this->line; + $this->yypushstate(self::TAGBODY); + } + } + double_quote { + $this->token = Smarty_Internal_Templateparser::TP_QUOTE; + $this->yypopstate(); + } + backtick dollar { + $this->token = Smarty_Internal_Templateparser::TP_BACKTICK; + $this->value = substr($this->value,0,-1); + $this->yypushstate(self::TAGBODY); + $this->taglineno = $this->line; + } + dollar id { + $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+)~i",$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))~i",$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}~i",$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