VMXTemplate/template.y

65 lines
3.0 KiB
Plaintext
Raw Permalink Normal View History

2013-04-19 13:50:42 +04:00
// Контекстно-свободная грамматика шаблонизатора
// Подразумевается, что лексический анализатор зависим от работы синтаксического,
// знает о его состоянии и соответственно выдаёт либо лексемы "внутри" блоков кода,
// либо литералы "вне" оных
// {{ двойные скобки }} нужно исключительно чтобы маркеры начала и конца подстановки
// были уникальны в грамматике. Вместо них обычно используются { одинарные }, а
// выбор корректной лексемы - скобки или маркера - делает лексический анализатор.
// Но зато вместо { фигурных скобок } можно выбрать себе любые другие маркеры!
2013-04-19 13:50:42 +04:00
// Олдстайл BEGIN .. END ликвидирован
2013-04-19 23:26:52 +04:00
// Возможно, нужно сделать foreach ... as key => value
2012-07-30 03:06:38 +04:00
%token literal
%token name
2013-04-19 13:50:42 +04:00
%left ".."
%left "||" "OR" "XOR"
%left "&&" "AND"
2013-04-19 13:50:42 +04:00
%nonassoc "==" "!=" "<" ">" "<=" ">="
%left "+" "-"
2013-04-19 17:04:03 +04:00
%left "&"
2013-04-19 13:50:42 +04:00
%left "*" "/" "%"
2012-07-30 03:06:38 +04:00
%%
2013-04-19 13:50:42 +04:00
chunks: | chunks chunk
chunk: literal | "<!--" code_chunk "-->" | "{{" exp "}}" | error
2013-04-19 13:50:42 +04:00
code_chunk: c_if | c_set | c_fn | c_for | exp
c_if: "IF" exp "-->" chunks "<!--" "END" |
"IF" exp "-->" chunks "<!--" "ELSE" "-->" chunks "<!--" "END" |
"IF" exp "-->" chunks c_elseifs chunks "<!--" "END" |
"IF" exp "-->" chunks c_elseifs chunks "<!--" "ELSE" "-->" chunks "<!--" "END"
2013-04-19 13:50:42 +04:00
c_elseifs: "<!--" elseif exp "-->" | c_elseifs chunks "<!--" elseif exp "-->"
c_set: "SET" varref "=" exp | "SET" varref "-->" chunks "<!--" "END"
c_fn: fn name "(" arglist ")" "=" exp | fn name "(" arglist ")" "-->" chunks "<!--" "END"
c_for: for varref "=" exp "-->" chunks "<!--" "END"
fn: "FUNCTION" | "BLOCK" | "MACRO"
for: "FOR" | "FOREACH"
elseif: "ELSE" "IF" | "ELSIF" | "ELSEIF"
2012-07-30 03:06:38 +04:00
2013-04-19 13:50:42 +04:00
exp: exp ".." exp |
exp "||" exp | exp "OR" exp | exp "XOR" exp |
exp "&&" exp | exp "AND" exp |
2013-04-19 13:50:42 +04:00
exp "==" exp | exp "!=" exp |
exp "<" exp | exp ">" exp | exp "<=" exp | exp ">=" exp |
exp "+" exp | exp "-" exp |
2013-04-19 17:04:03 +04:00
exp "&" exp |
2013-04-19 13:50:42 +04:00
exp "*" exp | exp "/" exp | exp "%" exp |
p10
2012-07-30 03:06:38 +04:00
p10: p11 | '-' p11
p11: nonbrace | '(' exp ')' varpath | '!' p11 | "NOT" p11
nonbrace: '{' hash '}' | literal | varref | name '(' ')' | name '(' list ')' | name '(' gthash ')' | name nonbrace
2012-09-26 00:58:18 +04:00
list: exp | exp ',' list
2012-07-30 03:06:38 +04:00
arglist: name | name ',' arglist |
hash: pair | pair ',' hash |
2013-04-19 19:55:42 +04:00
gthash: gtpair | gtpair ',' gthash
2012-09-26 00:58:18 +04:00
pair: exp ',' exp | gtpair
gtpair: exp "=>" exp
2012-07-30 03:06:38 +04:00
varref: name | varref varpart
varpart: '.' namekw | '[' exp ']' | '.' namekw '(' ')' | '.' namekw '(' list ')'
2012-07-30 03:06:38 +04:00
varpath: | varpath varpart
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"
2012-07-30 03:06:38 +04:00
%%