/* Copyright 2005-2006 Garrett Rooney. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ %include { #include #include "parser.h" #include "common.h" #include "lexer.h" } %name etl_parser_parse %token_prefix ETL_TOK_ %token_type { char * } %extra_argument { etl_parser_state_t *state } %type expression { etl_template_node_t * } %type expression_list { etl_template_node_t * } %type if { etl_if_contents_t * } %type unless { etl_if_contents_t * } %type for { etl_for_contents_t * } %type template { etl_template_t * } template ::= expression_list(E). { if (! state->error) { state->tmpl = apr_pcalloc (state->pool, sizeof (*state->tmpl)); state->tmpl->tree = E; } } expression_list(R) ::= expression_list(L) expression(E). { etl_template_node_t *itr = L; while (itr->next != NULL) itr = itr->next; itr->next = E; R = L; } expression_list(L) ::= expression(E). { L = E; } expression(E) ::= TEXT(T). { E = apr_pcalloc (state->pool, sizeof (*E)); E->type = ETL_NODE_LITERAL; E->contents.l.data = T; E->next = NULL; } if(I) ::= START_DIR IF VAR(V) END_DIR. { I = apr_pcalloc (state->pool, sizeof (*I)); I->var = V; } unless(U) ::= START_DIR UNLESS VAR(V) END_DIR. { U = apr_pcalloc (state->pool, sizeof (*U)); U->var = V; } expression(E) ::= if(I) expression_list(Y) end. { E = apr_pcalloc (state->pool, sizeof (*E)); E->type = ETL_NODE_IF; I->yes_task = Y; I->no_task = NULL; E->contents.i = I; E->next = NULL; } expression(E) ::= unless(U) expression_list(Y) end. { E = apr_pcalloc (state->pool, sizeof (*E)); E->type = ETL_NODE_UNLESS; U->yes_task = Y; U->no_task = NULL; E->contents.i = U; E->next = NULL; } else ::= START_DIR ELSE END_DIR. expression(E) ::= if(I) expression_list(Y) else expression_list(N) end. { E = apr_pcalloc (state->pool, sizeof (*E)); E->type = ETL_NODE_IF; I->yes_task = Y; I->no_task = N; E->contents.i = I; E->next = NULL; } expression(E) ::= unless(U) expression_list(Y) else expression_list(N) end. { E = apr_pcalloc (state->pool, sizeof (*E)); E->type = ETL_NODE_UNLESS; U->yes_task = Y; U->no_task = N; E->contents.i = U; E->next = NULL; } for(F) ::= START_DIR FOR VAR(V) IN VAR(A) END_DIR. { F = apr_pcalloc (state->pool, sizeof (*F)); F->var = V; F->arr = A; } end ::= START_DIR END END_DIR. expression(E) ::= for(F) expression_list(X) end. { E = apr_pcalloc (state->pool, sizeof (*E)); E->type = ETL_NODE_FOR; F->task = X; E->contents.f = F; E->next = NULL; } expression(E) ::= START_DIR PRINT VAR(V) END_DIR. { E = apr_pcalloc (state->pool, sizeof (*E)); E->type = ETL_NODE_PRINT; E->contents.p.var = V; E->next = NULL; } expression(E) ::= START_DIR PRINT VAR(V) PIPE VAR(F) END_DIR. { E = apr_pcalloc (state->pool, sizeof (*E)); E->type = ETL_NODE_FILTER; E->contents.flt = apr_pcalloc (state->pool, sizeof (*E->contents.flt)); E->contents.flt->var = V; if (strcmp (F, "html") == 0) E->contents.flt->filter = etl_template_filter_html; else if (strcmp (F, "xml") == 0) E->contents.flt->filter = etl_template_filter_xml; else if (strcmp (F, "url") == 0) E->contents.flt->filter = etl_template_filter_url; else state->error = apr_psprintf (state->pool, "unknown filter '%s'", F); E->next = NULL; }