# Контекстно-свободная Parse::Yapp-грамматика шаблонизатора # # Для корректной работы нужен патченый LIME со следующими изменениями: # (*) Подменой лексемы 'lit' на 'str' в метаграмматике. # Это нужно, чтобы можно было юзать строковые лексемы типа '' %token '{{' %token '}}' %left '..' %left '||' 'OR' 'XOR' %left '&&' 'AND' %nonassoc '==' '!=' '<' '>' '<=' '>=' %left '+' '-' %left '&' %left '*' '/' '%' # Директивы %% template: chunks { $_[0]->{template}->{st}->{functions}->{main}->{body} = "sub fn_main() {\nmy \$stack = [];\nmy \$t = '';\n".$_[1]."\nreturn \$t;\n}\n"; ''; } ; chunks: { ''; } | chunks chunk { $_[1] . $_[2]; } ; chunk: literal { '$t .= ' . $_[1] . ";\n"; } | '' { $_[2]; } | '{{' exp '}}' { '$t .= ' . ($_[2][1] || !$_[0]->{template}->{options}->{auto_escape} ? $_[2][0] : $_[0]->{template}->compile_function($_[0]->{template}->{options}->{auto_escape}, [ $_[2] ])[0]) . ";\n"; } | error { ''; } ; code_chunk: c_if | c_set | c_fn | c_for | exp { '$t .= ' . ($_[1][1] || !$_[0]->{template}->{options}->{auto_escape} ? $_[1][0] : $_[0]->{template}->compile_function($_[0]->{template}->{options}->{auto_escape}, [ $_[1] ])[0]) . ";\n"; } ; c_if: 'IF' exp '-->' chunks '' chunks '' chunks '' chunks c_elseifs chunks '' chunks c_elseifs chunks '' chunks '' { #{ "} elsif (" . $_[3][0] . ") {\n"; #} } | c_elseifs chunks '' { #{ $_[1] . $_[2] . "} elsif (" . $_[5][0] . ") {\n"; #} } ; c_set: 'SET' varref '=' exp { $_[2][0] . ' = ' . $_[4][0] . ";\n"; } | 'SET' varref '-->' chunks '' chunks '' chunks '', $t); } } elseif ($this->in_subst) { $this->in_subst += ($t === $this->options->begin_subst); $this->in_subst -= ($t === $this->options->end_subst); if (!$this->in_subst) { return array('}}', $t); } } return array($t, false); } } // Unknown character $this->skip_error( "Unexpected character '".$this->code{$this->pos}."'" ); return array('error', false); } } }