3 +---------------------------------------------------------------------------------+
4 | Copyright (c) 2010 Haanga |
5 +---------------------------------------------------------------------------------+
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met: |
8 | 1. Redistributions of source code must retain the above copyright |
9 | notice, this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
15 | 3. All advertising materials mentioning features or use of this software |
16 | must display the following acknowledgement: |
17 | This product includes software developed by César D. Rodas. |
19 | 4. Neither the name of the César D. Rodas nor the |
20 | names of its contributors may be used to endorse or promote products |
21 | derived from this software without specific prior written permission. |
23 | THIS SOFTWARE IS PROVIDED BY CÉSAR D. RODAS ''AS IS'' AND ANY |
24 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
26 | DISCLAIMED. IN NO EVENT SHALL CÉSAR D. RODAS BE LIABLE FOR ANY |
27 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
28 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
29 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
30 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
31 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
32 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE |
33 +---------------------------------------------------------------------------------+
34 | Authors: César Rodas <crodas@php.net> |
35 +---------------------------------------------------------------------------------+
38 class HG_Parser Extends Haanga_Compiler_Parser
40 /* subclass to made easier references to constants */
43 class Haanga_Compiler_Lexer
52 function __construct($data, $compiler)
55 $this->compiler = $compiler;
60 function init($template, $compiler)
62 $lexer = new Haanga_Compiler_Lexer($template, $compiler);
63 $parser = new Haanga_Compiler_Parser;
65 $parser->compiler = $compiler;
69 if (!$lexer->yylex()) {
72 $parser->doParse($lexer->token, $lexer->value);
74 } catch (Exception $e) {
75 throw new Haanga_Compiler_Exception($e->getMessage(). ' on line '.$lexer->getLine());
77 $parser->doParse(0, 0);
78 return (array)$parser->body;
86 public $custom_tags=array();
88 function is_custom_tag()
92 $tag = Haanga_Extension::getInstance('Tag');
94 $value = $tag->isValid($this->value);
95 $this->token = $value ? $value : HG_Parser::T_ALPHA;
104 alpha = /([a-zA-Z_][a-zA-Z_0-9]*)/
106 numerals = /([0-9])+/
107 whitespace = /[ \r\t\n]+/
108 html = /([^{]+(.[^%{#])?)+/
109 comment = /([^\#]+\#\})+/
110 custom_tag_end = /end([a-zA-Z][a-zA-Z0-9]*)/
111 token_end = /[^a-zA-Z0-9_\.]/
112 single_string = /[^'\\]+/
113 double_string = /[^"\\]+/
118 $this->token = HG_Parser::T_OPEN_TAG;
119 $this->yypushstate(self::IN_CODE);
123 $this->token = HG_Parser::T_COMMENT_OPEN;
124 $this->yypushstate(self::IN_COMMENT);
129 $this->token = HG_Parser::T_PRINT_OPEN;
130 $this->yypushstate(self::IN_PRINT);
134 $this->token = HG_Parser::T_HTML;
141 $this->token = HG_Parser::T_CLOSE_TAG;
146 $this->token = HG_Parser::T_OBJ;
151 $this->token = HG_Parser::T_DOT;
155 $this->token = HG_Parser::T_BUFFER;
160 $this->token = HG_Parser::T_FOR;
164 $this->token = HG_Parser::T_EMPTY;
168 $this->token = HG_Parser::T_LOAD;
172 $this->token = HG_Parser::T_BLOCK;
176 $this->token = HG_Parser::T_AND;
180 $this->token = HG_Parser::T_AND;
184 $this->token = HG_Parser::T_OR;
188 $this->token = HG_Parser::T_OR;
192 $this->token = HG_Parser::T_EQ;
196 $this->token = HG_Parser::T_NE;
200 $this->token = HG_Parser::T_GE;
204 $this->token = HG_Parser::T_NOT;
208 $this->token = HG_Parser::T_NOT;
213 $this->token = HG_Parser::T_BRACKETS_OPEN;
217 $this->token = HG_Parser::T_BRACKETS_CLOSE;
221 $this->token = HG_Parser::T_GT;
225 $this->token = HG_Parser::T_LT;
228 $this->token = HG_Parser::T_LE;
232 $this->token = HG_Parser::T_PIPE;
236 $this->token = HG_Parser::T_COLON;
240 $this->token = HG_Parser::T_FILTER;
243 "regroup" token_end {
244 $this->token = HG_Parser::T_REGROUP;
247 "endfilter" token_end {
248 $this->token = HG_Parser::T_END_FILTER;
251 "autoescape" token_end {
252 $this->token = HG_Parser::T_AUTOESCAPE;
256 "endautoescape" token_end {
257 $this->token = HG_Parser::T_END_AUTOESCAPE;
261 "endblock" token_end {
262 $this->token = HG_Parser::T_END_BLOCK;
265 "ifchanged" token_end {
266 $this->token = HG_Parser::T_IFCHANGED;
269 "ifequal" token_end {
270 $this->token = HG_Parser::T_IFEQUAL;
273 "endifequal" token_end {
274 $this->token = HG_Parser::T_END_IFEQUAL;
277 "ifnotequal" token_end {
278 $this->token = HG_Parser::T_IFNOTEQUAL;
281 "endifnotequal" token_end {
282 $this->token = HG_Parser::T_END_IFNOTEQUAL;
287 $this->token = HG_Parser::T_ELSE;
290 "endifchanged" token_end {
291 $this->token = HG_Parser::T_ENDIFCHANGED;
296 $this->token = HG_Parser::T_IN;
300 $this->token = HG_Parser::T_CLOSEFOR;
304 $this->token = HG_Parser::T_WITH;
307 "endwith" token_end {
308 $this->token = HG_Parser::T_ENDWITH;
312 $this->token = HG_Parser::T_AS;
316 $this->token = HG_Parser::T_ON;
320 $this->token = HG_Parser::T_OFF;
324 $this->token = HG_Parser::T_BY;
328 $this->token = HG_Parser::T_IF;
332 $this->token = HG_Parser::T_ELSE;
336 $this->token = HG_Parser::T_ENDIF;
340 $this->token = HG_Parser::T_INTL;
345 $this->token = HG_Parser::T_LPARENT;
349 $this->token = HG_Parser::T_RPARENT;
353 $this->token = HG_Parser::T_MOD;
357 $this->token = HG_Parser::T_COMMA;
361 $this->token = HG_Parser::T_PLUS;
364 $this->token = HG_Parser::T_MINUS;
367 $this->token = HG_Parser::T_TIMES;
371 $this->token = HG_Parser::T_DIV;
375 $this->token = HG_Parser::T_STRING_SINGLE_INIT;
376 $this->yypushstate(self::IN_STRING_SINGLE);
380 $this->token = HG_Parser::T_STRING_DOUBLE_INIT;
381 $this->yypushstate(self::IN_STRING_DOUBLE);
385 $this->token = HG_Parser::T_CUSTOM_END;
388 "extends" token_end {
389 $this->token = HG_Parser::T_EXTENDS;
392 "include" token_end {
393 $this->token = HG_Parser::T_INCLUDE;
397 $this->token = HG_Parser::T_NUMERIC;
400 numerals "." numerals {
401 $this->token = HG_Parser::T_NUMERIC;
405 $this->is_custom_tag();
416 $this->token = HG_Parser::T_PRINT_CLOSE;
421 $this->token = HG_Parser::T_PIPE;
425 $this->token = HG_Parser::T_COLON;
429 $this->token = HG_Parser::T_OBJ;
434 $this->token = HG_Parser::T_DOT;
438 $this->token = HG_Parser::T_BRACKETS_OPEN;
442 $this->token = HG_Parser::T_BRACKETS_CLOSE;
446 $this->token = HG_Parser::T_NUMERIC;
449 numerals "." numerals {
450 $this->token = HG_Parser::T_NUMERIC;
454 $this->token = HG_Parser::T_STRING_SINGLE_INIT;
455 $this->yypushstate(self::IN_STRING_SINGLE);
459 $this->token = HG_Parser::T_STRING_DOUBLE_INIT;
460 $this->yypushstate(self::IN_STRING_DOUBLE);
464 $this->token = HG_Parser::T_ALPHA;
473 %statename IN_STRING_DOUBLE
476 $this->token = HG_Parser::T_STRING_CONTENT;
482 $this->token = HG_Parser::T_STRING_CONTENT;
489 $this->token = HG_Parser::T_STRING_DOUBLE_END;
494 $this->token = HG_Parser::T_STRING_CONTENT;
500 %statename IN_STRING_SINGLE
502 $this->token = HG_Parser::T_STRING_CONTENT;
508 $this->token = HG_Parser::T_STRING_CONTENT;
515 $this->token = HG_Parser::T_STRING_SINGLE_END;
520 $this->token = HG_Parser::T_STRING_CONTENT;
526 %statename IN_COMMENT
528 $this->token = HG_Parser::T_COMMENT;