Files
handlebars.js/src/handlebars.yy
T
Yehuda Katz 17ee7ffaca Merge pull request #388 from dmarcotte/empty-inverse-blocks
Allow empty blocks around simple inverses
2012-12-23 20:31:46 -08:00

110 lines
2.6 KiB
Plaintext

%start root
%%
root
: program EOF { return $1; }
;
program
: simpleInverse statements { $$ = new yy.ProgramNode([], $2); }
| statements simpleInverse statements { $$ = new yy.ProgramNode($1, $3); }
| statements simpleInverse { $$ = new yy.ProgramNode($1, []); }
| statements { $$ = new yy.ProgramNode($1); }
| simpleInverse { $$ = new yy.ProgramNode([], []); }
| "" { $$ = new yy.ProgramNode([]); }
;
statements
: statement { $$ = [$1]; }
| statements statement { $1.push($2); $$ = $1; }
;
statement
: openInverse program closeBlock { $$ = new yy.BlockNode($1, $2.inverse, $2, $3); }
| openBlock program closeBlock { $$ = new yy.BlockNode($1, $2, $2.inverse, $3); }
| mustache { $$ = $1; }
| partial { $$ = $1; }
| CONTENT { $$ = new yy.ContentNode($1); }
| COMMENT { $$ = new yy.CommentNode($1); }
;
openBlock
: OPEN_BLOCK inMustache CLOSE { $$ = new yy.MustacheNode($2[0], $2[1]); }
;
openInverse
: OPEN_INVERSE inMustache CLOSE { $$ = new yy.MustacheNode($2[0], $2[1]); }
;
closeBlock
: OPEN_ENDBLOCK path CLOSE { $$ = $2; }
;
mustache
: OPEN inMustache CLOSE { $$ = new yy.MustacheNode($2[0], $2[1]); }
| OPEN_UNESCAPED inMustache CLOSE { $$ = new yy.MustacheNode($2[0], $2[1], true); }
;
partial
: OPEN_PARTIAL partialName CLOSE { $$ = new yy.PartialNode($2); }
| OPEN_PARTIAL partialName path CLOSE { $$ = new yy.PartialNode($2, $3); }
;
simpleInverse
: OPEN_INVERSE CLOSE { }
;
inMustache
: path params hash { $$ = [[$1].concat($2), $3]; }
| path params { $$ = [[$1].concat($2), null]; }
| path hash { $$ = [[$1], $2]; }
| path { $$ = [[$1], null]; }
| DATA { $$ = [[new yy.DataNode($1)], null]; }
;
params
: params param { $1.push($2); $$ = $1; }
| param { $$ = [$1]; }
;
param
: path { $$ = $1; }
| STRING { $$ = new yy.StringNode($1); }
| INTEGER { $$ = new yy.IntegerNode($1); }
| BOOLEAN { $$ = new yy.BooleanNode($1); }
| DATA { $$ = new yy.DataNode($1); }
;
hash
: hashSegments { $$ = new yy.HashNode($1); }
;
hashSegments
: hashSegments hashSegment { $1.push($2); $$ = $1; }
| hashSegment { $$ = [$1]; }
;
hashSegment
: ID EQUALS path { $$ = [$1, $3]; }
| ID EQUALS STRING { $$ = [$1, new yy.StringNode($3)]; }
| ID EQUALS INTEGER { $$ = [$1, new yy.IntegerNode($3)]; }
| ID EQUALS BOOLEAN { $$ = [$1, new yy.BooleanNode($3)]; }
| ID EQUALS DATA { $$ = [$1, new yy.DataNode($3)]; }
;
partialName
: PARTIAL_NAME { $$ = new yy.PartialNameNode($1); }
;
path
: pathSegments { $$ = new yy.IdNode($1); }
;
pathSegments
: pathSegments SEP ID { $1.push($3); $$ = $1; }
| ID { $$ = [$1]; }
;