2013-04-19 23:26:52 +04:00
|
|
|
|
# Контекстно-свободная LIME-грамматика шаблонизатора
|
|
|
|
|
#
|
2013-04-20 15:05:45 +04:00
|
|
|
|
# Для корректной работы нужен патченый LIME со следующими изменениями:
|
|
|
|
|
# (*) Подменой лексемы 'lit' на 'str' в метаграмматике.
|
2013-04-19 23:26:52 +04:00
|
|
|
|
# Это нужно, чтобы можно было юзать строковые лексемы типа '<!--'.
|
2013-04-20 15:05:45 +04:00
|
|
|
|
# (*) Для корректной обработки ошибок нужно, чтобы метод eat() возвращал
|
|
|
|
|
# false при ошибке и true при успехе. Т.к. подразумевается, что лексический
|
|
|
|
|
# анализатор зависим от работы синтаксического, знает о его состоянии и
|
|
|
|
|
# соответственно выдаёт либо лексемы "внутри" блоков кода, либо литералы
|
|
|
|
|
# "вне" оных.
|
2013-04-22 03:24:36 +04:00
|
|
|
|
# Взять таковой можно здесь: https://github.com/vitalif/lime
|
2013-08-26 02:20:13 +04:00
|
|
|
|
# Компилить так: php -d xdebug.max_nesting_level=200 lime.php template.lime > template.class
|
2013-04-20 15:05:45 +04:00
|
|
|
|
#
|
2013-04-22 11:23:01 +04:00
|
|
|
|
# {{ двойные скобки }} нужно исключительно чтобы маркеры начала и конца подстановки
|
|
|
|
|
# были уникальны в грамматике. Вместо них обычно используются { одинарные }, а
|
|
|
|
|
# выбор корректной лексемы - скобки или маркера - делает лексический анализатор.
|
|
|
|
|
# Но зато вместо { фигурных скобок } можно выбрать себе любые другие маркеры!
|
|
|
|
|
#
|
2013-04-23 23:08:58 +04:00
|
|
|
|
# Все выражения представляются массивом из двух значений: [ код выражения, флаг экранирования ]
|
|
|
|
|
# Флаг экранирования == true, если это выражение HTML-безопасно. При включённом auto_escape
|
|
|
|
|
# небезопасные выражения прогоняются через экранирование.
|
|
|
|
|
#
|
2013-04-20 15:05:45 +04:00
|
|
|
|
# Кстати:
|
2013-04-23 23:09:00 +04:00
|
|
|
|
# * Олдстайл BEGIN .. END ликвидирован
|
|
|
|
|
# * Возможно, нужно добавить в каком-то виде foreach ... as key => value
|
|
|
|
|
#
|
|
|
|
|
# PHP старее 5.4 не поддерживается из-за следующих причин:
|
|
|
|
|
# * используется $a ?: $b в выражении {a || b}
|
|
|
|
|
# * используется короткий синтаксис массивов [ $a, $b ]
|
|
|
|
|
# * используется синтаксис ($array_expression)[$key]
|
2013-04-19 19:55:42 +04:00
|
|
|
|
|
|
|
|
|
%class VMXTemplateParser
|
2013-04-20 03:42:30 +04:00
|
|
|
|
%start template
|
2013-04-19 19:55:42 +04:00
|
|
|
|
|
|
|
|
|
%token literal
|
2013-04-20 03:42:30 +04:00
|
|
|
|
%token incorrect
|
2013-04-19 19:55:42 +04:00
|
|
|
|
%token name
|
2013-04-20 03:42:30 +04:00
|
|
|
|
%token comment
|
2013-04-19 19:55:42 +04:00
|
|
|
|
|
2013-04-20 03:42:30 +04:00
|
|
|
|
%token ".." "concatenation operator '..'"
|
|
|
|
|
%token "||" "OR operator '||'"
|
2013-04-20 15:05:45 +04:00
|
|
|
|
%token "OR" "OR operator 'OR'"
|
|
|
|
|
%token "XOR" "XOR operator 'XOR'"
|
|
|
|
|
%token "AND" "AND operator 'AND'"
|
2013-04-20 03:42:30 +04:00
|
|
|
|
%token "&&" "AND operator '&&'"
|
|
|
|
|
%token "&" "bitwise AND operator '&'"
|
|
|
|
|
%token "==" "equality operator '=='"
|
|
|
|
|
%token "!=" "non-equality operator '!='"
|
|
|
|
|
%token "<" "less than operator '<'"
|
|
|
|
|
%token ">" "greater than operator '>'"
|
|
|
|
|
%token "<=" "less or equal operator '<='"
|
|
|
|
|
%token ">=" "greater or equal operator '>='"
|
|
|
|
|
%token "+" "plus operator '+'"
|
|
|
|
|
%token "-" "minus operator '-'"
|
|
|
|
|
%token "*" "multiply operator '*'"
|
|
|
|
|
%token "/" "divide operator '/'"
|
|
|
|
|
%token "%" "mod operator '%'"
|
|
|
|
|
%token "(" "left round brace '('"
|
|
|
|
|
%token ")" "right round brace '('"
|
|
|
|
|
%token "!" "NOT operator '!'"
|
2013-04-20 15:05:45 +04:00
|
|
|
|
%token "NOT" "NOT operator 'NOT'"
|
2013-04-20 03:42:30 +04:00
|
|
|
|
%token "{" "left curly brace '{'"
|
|
|
|
|
%token "}" "right curly brace '}'"
|
|
|
|
|
%token "," "comma ','"
|
|
|
|
|
%token "=>" "hash item operator '=>'"
|
|
|
|
|
%token "[" "left square brace '['"
|
|
|
|
|
%token "]" "right square brace ']'"
|
2013-04-22 11:23:01 +04:00
|
|
|
|
%token "<!--" "directive begin"
|
|
|
|
|
%token "-->" "directive end"
|
|
|
|
|
%token "{{" "substitution begin"
|
|
|
|
|
%token "}}" "substitution end"
|
2013-04-19 23:26:52 +04:00
|
|
|
|
|
2013-04-19 19:55:42 +04:00
|
|
|
|
%left ".."
|
2013-04-20 15:05:45 +04:00
|
|
|
|
%left "||" "OR" "XOR"
|
|
|
|
|
%left "&&" "AND"
|
2013-04-19 19:55:42 +04:00
|
|
|
|
%nonassoc "==" "!=" "<" ">" "<=" ">="
|
|
|
|
|
%left "+" "-"
|
|
|
|
|
%left "&"
|
|
|
|
|
%left "*" "/" "%"
|
|
|
|
|
|
2013-04-19 23:26:52 +04:00
|
|
|
|
# Директивы
|
2013-04-19 19:55:42 +04:00
|
|
|
|
|
2013-04-20 03:42:30 +04:00
|
|
|
|
template = chunks {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$this->template->st->AST = $1;
|
2013-04-19 19:55:42 +04:00
|
|
|
|
$$ = '';
|
|
|
|
|
}
|
2013-04-20 03:42:30 +04:00
|
|
|
|
.
|
2013-06-18 02:28:10 +04:00
|
|
|
|
chunks = {
|
2015-04-10 14:32:42 +03:00
|
|
|
|
$$ = [];
|
2013-04-20 03:42:30 +04:00
|
|
|
|
}
|
|
|
|
|
| chunks chunk {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = $1;
|
|
|
|
|
if ($2) {
|
|
|
|
|
$$[] = $2;
|
|
|
|
|
}
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
.
|
2013-04-20 03:42:30 +04:00
|
|
|
|
chunk = literal {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'literal', $1 ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
| "<!--" code_chunk/c "-->" {
|
|
|
|
|
$$ = $c;
|
|
|
|
|
}
|
2013-04-22 11:23:01 +04:00
|
|
|
|
| "{{" exp/e "}}" {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'subst', $e ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
2013-04-20 03:42:30 +04:00
|
|
|
|
| error/e {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = false;
|
2013-04-20 03:42:30 +04:00
|
|
|
|
}
|
|
|
|
|
.
|
2013-04-23 23:08:58 +04:00
|
|
|
|
code_chunk = c_if/$ | c_set/$ | c_fn/$ | c_for/$ | exp/e {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'subst', $e ];
|
2013-04-19 23:26:52 +04:00
|
|
|
|
}
|
2013-04-19 19:55:42 +04:00
|
|
|
|
.
|
2013-04-20 15:05:45 +04:00
|
|
|
|
c_if = "IF" exp/e "-->" chunks/if "<!--" "END" {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'if', [ $e, $if ] ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
2013-04-20 15:05:45 +04:00
|
|
|
|
| "IF" exp/e "-->" chunks/if "<!--" "ELSE" "-->" chunks/else "<!--" "END" {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'if', [ $e, $if ], [ false, $else ] ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
2013-04-20 15:05:45 +04:00
|
|
|
|
| "IF" exp/e "-->" chunks/if c_elseifs/ei chunks/ec "<!--" "END" {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = $ei;
|
|
|
|
|
$$[count($$)-1] = $ec;
|
|
|
|
|
$$ = array_merge([ 'if', [ $e, $if ] ], $ei);
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
2013-04-20 15:05:45 +04:00
|
|
|
|
| "IF" exp/e "-->" chunks/if c_elseifs/ei chunks/ec "<!--" "ELSE" "-->" chunks/else "<!--" "END" {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = $ei;
|
|
|
|
|
$$[count($$)-1] = $ec;
|
|
|
|
|
$$[] = [ false, $else ];
|
|
|
|
|
$$ = array_merge([ 'if', [ $e, $if ] ], $$);
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
.
|
|
|
|
|
c_elseifs = "<!--" elseif exp/e "-->" {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ [ $e ] ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
| c_elseifs/p chunks/cs "<!--" elseif exp/e "-->" {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = $p;
|
|
|
|
|
$$[count($$)-1][] = $cs;
|
|
|
|
|
$$[] = [ $e ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
.
|
2013-04-20 15:05:45 +04:00
|
|
|
|
c_set = "SET" varref/v "=" exp/e {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'set', $v, [ 'subst', $e ] ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
2013-04-20 15:05:45 +04:00
|
|
|
|
| "SET" varref/v "-->" chunks/cs "<!--" "END" {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'set', $v, $cs ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
.
|
|
|
|
|
c_fn = fn name/name "(" arglist/args ")" "=" exp/exp {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'function', $name, $args, [ 'subst', $exp ] ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
2013-04-20 15:05:45 +04:00
|
|
|
|
| fn name/name "(" arglist/args ")" "-->" chunks/cs "<!--" "END" {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'function', $name, $args, $cs ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
.
|
2013-04-20 15:05:45 +04:00
|
|
|
|
c_for = for varref/varref "=" exp/exp "-->" chunks/cs "<!--" "END" {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'for', $varref, $exp, $cs ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
.
|
2013-04-20 15:05:45 +04:00
|
|
|
|
fn = "FUNCTION" | "BLOCK" | "MACRO" .
|
|
|
|
|
for = "FOR" | "FOREACH" .
|
|
|
|
|
elseif = "ELSE" "IF" | "ELSIF" | "ELSEIF" .
|
2013-04-19 19:55:42 +04:00
|
|
|
|
|
2013-04-19 23:26:52 +04:00
|
|
|
|
# Выражения
|
2013-04-19 19:55:42 +04:00
|
|
|
|
|
|
|
|
|
exp: exp/a ".." exp/b {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'op', '.', $a, $b ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
| exp/a "||" exp/b {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'op', '||', $a, $b ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
2013-04-20 15:05:45 +04:00
|
|
|
|
| exp/a "OR" exp/b {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'op', '||', $a, $b ];
|
|
|
|
|
}
|
2013-04-20 15:05:45 +04:00
|
|
|
|
| exp/a "XOR" exp/b {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'op', 'XOR', $a, $b ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
| exp/a "&&" exp/b {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'op', '&&', $a, $b ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
2013-04-20 15:05:45 +04:00
|
|
|
|
| exp/a "AND" exp/b {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'op', '&&', $a, $b ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
| exp/a "==" exp/b {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'op', '==', $a, $b ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
| exp/a "!=" exp/b {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'op', '!=', $a, $b ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
| exp/a "<" exp/b {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'op', '<', $a, $b ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
| exp/a ">" exp/b {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'op', '>', $a, $b ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
| exp/a "<=" exp/b {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'op', '<=', $a, $b ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
| exp/a ">=" exp/b {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'op', '>=', $a, $b ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
| exp/a "+" exp/b {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'op', '+', $a, $b ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
| exp/a "-" exp/b {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'op', '-', $a, $b ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
| exp/a "&" exp/b {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'op', '&', $a, $b ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
| exp/a "*" exp/b {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'op', '*', $a, $b ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
| exp/a "/" exp/b {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'op', '/', $a, $b ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
| exp/a "%" exp/b {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'op', '%', $a, $b ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
2013-04-19 23:26:52 +04:00
|
|
|
|
| p10/$
|
2013-04-19 19:55:42 +04:00
|
|
|
|
.
|
2013-04-19 23:26:52 +04:00
|
|
|
|
p10: p11/$
|
|
|
|
|
| '-' p11/a {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'op', '-', $a ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
.
|
2015-04-12 23:34:54 +03:00
|
|
|
|
p11: nonbrace/$
|
2013-04-19 19:55:42 +04:00
|
|
|
|
| '(' exp/e ')' varpath/p {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'varpath', $e, $p ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
| '!' p11/a {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'op', '!', $a ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
2013-04-20 15:05:45 +04:00
|
|
|
|
| "NOT" p11/a {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'op', '!', $a ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
.
|
2015-04-12 23:34:54 +03:00
|
|
|
|
nonbrace: '{' hash/$ '}'
|
|
|
|
|
| literal/$
|
2013-04-19 23:26:52 +04:00
|
|
|
|
| varref/$
|
2013-04-19 19:55:42 +04:00
|
|
|
|
| name/f '(' ')' {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'call', $f, [] ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
| name/f '(' list/args ')' {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'call', $f, $args ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
| name/f '(' gthash/args ')' {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'call_block', $f, $args, $this->template->lexer->errorpos() ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
| name/f nonbrace/arg {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'call', $f, [ $arg ] ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
.
|
|
|
|
|
list: exp/e {
|
|
|
|
|
$$ = [ $e ];
|
|
|
|
|
}
|
|
|
|
|
| exp/e ',' list/l {
|
|
|
|
|
$$ = $l;
|
|
|
|
|
array_unshift($$, $e);
|
|
|
|
|
}
|
|
|
|
|
.
|
2013-04-19 23:26:52 +04:00
|
|
|
|
arglist: name/n {
|
|
|
|
|
$$ = [ $n ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
2013-04-19 23:26:52 +04:00
|
|
|
|
| name/n ',' arglist/args {
|
|
|
|
|
$$ = $args;
|
|
|
|
|
array_unshift($$, $n);
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
| {
|
2013-04-19 23:26:52 +04:00
|
|
|
|
$$ = [];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
.
|
2015-04-12 23:34:54 +03:00
|
|
|
|
hash: pair/p {
|
|
|
|
|
$$ = [ 'hash', $p ];
|
|
|
|
|
}
|
2013-04-19 19:55:42 +04:00
|
|
|
|
| pair/p ',' hash/h {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
array_splice($h, 1, 0, [ $p ]);
|
|
|
|
|
$$ = $h;
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
| {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'hash' ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
.
|
2015-04-12 23:34:54 +03:00
|
|
|
|
gthash: gtpair/p {
|
|
|
|
|
$$ = [ 'hash', $p ];
|
|
|
|
|
}
|
2013-04-19 19:55:42 +04:00
|
|
|
|
| gtpair/p ',' gthash/h {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
array_splice($h, 1, 0, [ $p ]);
|
|
|
|
|
$$ = $h;
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
.
|
|
|
|
|
pair: exp/k ',' exp/v {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ $k, $v ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
2013-04-19 23:26:52 +04:00
|
|
|
|
| gtpair/$
|
2013-04-19 19:55:42 +04:00
|
|
|
|
.
|
|
|
|
|
gtpair: exp/k "=>" exp/v {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ $k, $v ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
.
|
|
|
|
|
varref: name/n {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'varref', $n ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
| varref/v varpart/p {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$v[] = $p;
|
|
|
|
|
$$ = $v;
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
.
|
2013-08-26 02:20:13 +04:00
|
|
|
|
varpart: '.' namekw/n {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'index', $n ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
| '[' exp/e ']' {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'index', $e ];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
2015-04-12 22:55:30 +03:00
|
|
|
|
| '.' namekw/n '(' ')' {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'method', $n, [] ];
|
2014-10-12 15:55:02 +04:00
|
|
|
|
}
|
2015-04-12 22:55:30 +03:00
|
|
|
|
| '.' namekw/n '(' list/l ')' {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [ 'method', $n, $l ];
|
2014-10-12 15:55:02 +04:00
|
|
|
|
}
|
2013-04-19 19:55:42 +04:00
|
|
|
|
.
|
|
|
|
|
varpath: {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$$ = [];
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
| varpath/a varpart/p {
|
2015-04-12 23:34:54 +03:00
|
|
|
|
$a[] = $p;
|
|
|
|
|
$$ = $a;
|
2013-04-19 19:55:42 +04:00
|
|
|
|
}
|
|
|
|
|
.
|
2013-08-26 02:20:13 +04:00
|
|
|
|
namekw: name
|
|
|
|
|
| "IF" | "END" | "ELSE" | "ELSIF" | "ELSEIF"
|
|
|
|
|
| "SET" | "OR" | "XOR" | "AND" | "NOT"
|
|
|
|
|
| "FUNCTION" | "BLOCK" | "MACRO" | "FOR" | "FOREACH"
|
|
|
|
|
.
|