X-Git-Url: http://www.sigaev.ru/git/gitweb.cgi?a=blobdiff_plain;f=tmpl_gram.y;h=3335903508f491aaafdf1c1aab4d7b302eed3f5b;hb=029b7a56ef910c2430ddb40a7383c7caa640ecc1;hp=373066081c2d3c2c7f390c7e00adf3c4cdeedb2d;hpb=ac6f06173082a74d22e6a39df025eb4aad98bc0a;p=tedtools.git diff --git a/tmpl_gram.y b/tmpl_gram.y index 3730660..3335903 100644 --- a/tmpl_gram.y +++ b/tmpl_gram.y @@ -16,30 +16,33 @@ void startTemplateLex(Template tmpl, FILE *in); static Template curTmpl; extern int tmpl_yylineno; +static TemplateNode newExpressionNode(char *op, GList *args); +static GList *makeList2(void *a, void *b); + %} %union { - char *str; - char punct; - int varname; - int flags; - TemplateNode node; + char *str; + char punct; + int flags; + int intval; + double floatval; + TemplateNode node; + GList *list; } %type node %type listnodes %type template -%type condition -%type condition_varname +%type expression +%type list_expression %type varname %type opt_escape -%type opt_global -%type opt_default %type opt_format +%type opt_default -%token OR_P %token STRING %token FILENAME %token TEXT_P @@ -47,7 +50,22 @@ extern int tmpl_yylineno; %token VAR_OPEN VAR_CLOSE EXPR_OPEN EXPR_CLOSE INCLUDE_OPEN INCLUDE_CLOSE %token HTMLESCAPE URLESCAPE IF_P ELSE_P LOOP_P ENDIF_P ENDLOOP_P - NOT_P DEFINED_P +%token CMP_P + +%token INTEGER +%token DOUBLE + + +%left '+' '-' +%left '*' '/' '%' +%left '?' ':' +%left NEG + +%left OR_P +%left AND_P +%left NOT_P + +%left CMP_P %% @@ -80,8 +98,6 @@ varname: | LOOP_P | ENDIF_P | ENDLOOP_P - | NOT_P - | DEFINED_P ; opt_escape: @@ -90,52 +106,103 @@ opt_escape: | { $$=0; } ; -opt_global: - '^' { $$=TND_GLOBAL; } - | { $$=0; } - ; - opt_format: ',' STRING { $$=$2; } | { $$=NULL; } ; opt_default: - OR_P STRING { $$=$2; } + '#' STRING { $$=$2; } | { $$=NULL; } ; -condition_varname: - varname { - $$ = mc0alloc( curTmpl->templateContext, sizeof(TemplateNodeData) ); - $$->type = ConditionNode; - $$->nodeData.condition.varName = $1; - $$->nodeData.condition.varNameLength = strlen($1); - } - | '^' varname { - $$ = mc0alloc( curTmpl->templateContext, sizeof(TemplateNodeData) ); - $$->type = ConditionNode; - $$->nodeData.condition.flags = TND_GLOBAL; - $$->nodeData.condition.varName = $2; - $$->nodeData.condition.varNameLength = strlen($2); +list_expression: + expression ',' expression { + $$ = makeList2($1, $3); } + | list_expression ',' expression { + $$ = GListPush($$, $3); + } ; -condition: - condition_varname { - $$ = $1; +expression: + varname { + $$ = mc0alloc( curTmpl->templateContext, sizeof(TemplateNodeData) ); + $$->type = VariableNode; + $$->nodeData.variable.varName = $1; + $$->nodeData.variable.varNameLength = strlen($1); + } + | '^' varname { + $$ = mc0alloc( curTmpl->templateContext, sizeof(TemplateNodeData) ); + $$->type = VariableNode; + $$->nodeData.variable.flags = TND_GLOBAL; + $$->nodeData.variable.varName = $2; + $$->nodeData.variable.varNameLength = strlen($2); + } + | STRING { + $$ = mc0alloc( curTmpl->templateContext, sizeof(TemplateNodeData) ); + $$->type = ConstNode; + $$->nodeData.value.type = valueString; + $$->nodeData.value.flags = TND_DEFINED; + $$->nodeData.value.value.stringValue = $1; + } + | INTEGER { + $$ = mc0alloc( curTmpl->templateContext, sizeof(TemplateNodeData) ); + $$->type = ConstNode; + $$->nodeData.value.type = valueInt; + $$->nodeData.value.flags = TND_DEFINED; + $$->nodeData.value.value.intValue = $1; + } + | DOUBLE { + $$ = mc0alloc( curTmpl->templateContext, sizeof(TemplateNodeData) ); + $$->type = ConstNode; + $$->nodeData.value.type = valueDouble; + $$->nodeData.value.flags = TND_DEFINED; + $$->nodeData.value.value.doubleValue = $1; } - | DEFINED_P condition_varname { - $$ = $2; - $$->nodeData.condition.flags |= TND_DEFINED; + | expression '+' expression { + $$ = newExpressionNode( "+", makeList2( $1, $3 ) ); } - | NOT_P condition { - $$ = $2; - if ( $$->nodeData.condition.flags & TND_NOT ) - $$->nodeData.condition.flags &= ~TND_NOT; - else - $$->nodeData.condition.flags |= TND_NOT; + | expression '-' expression { + $$ = newExpressionNode( "-", makeList2( $1, $3 ) ); } + | expression '*' expression { + $$ = newExpressionNode( "*", makeList2( $1, $3 ) ); + } + | expression '/' expression { + $$ = newExpressionNode( "/", makeList2( $1, $3 ) ); + } + | expression '%' expression { + $$ = newExpressionNode( "%", makeList2( $1, $3 ) ); + } + | '-' expression %prec NEG { + $$ = newExpressionNode( "-", GListPush( NULL, $2 ) ); + } + | expression AND_P expression { + $$ = newExpressionNode( "&&", makeList2( $1, $3 ) ); + } + | expression OR_P expression { + $$ = newExpressionNode( "||", makeList2( $1, $3 ) ); + } + | expression '?' expression ':' expression { + $$ = newExpressionNode( "?", GListPush( makeList2( $1, $3 ), $5 ) ); + } + | NOT_P expression { + $$ = newExpressionNode( "!", GListPush( NULL, $2 ) ); + } + | expression CMP_P expression { + $$ = newExpressionNode( $2, makeList2( $1, $3 ) ); + } + | varname '(' ')' { + $$ = newExpressionNode( $1, NULL ); + } + | varname '(' expression ')' { + $$ = newExpressionNode( $1, GListPush( NULL, $3 ) ); + } + | varname '(' list_expression ')' { + $$ = newExpressionNode( $1, $3 ); + } + | '(' expression ')' { $$=$2; } ; node: @@ -145,14 +212,13 @@ node: $$->nodeData.text.value = $1; $$->nodeData.text.valueLength = strlen($1); } - | VAR_OPEN opt_global varname opt_format opt_default opt_escape VAR_CLOSE { + | VAR_OPEN expression opt_format opt_default opt_escape VAR_CLOSE { $$ = mc0alloc( curTmpl->templateContext, sizeof(TemplateNodeData) ); - $$->type = VariableNode; - $$->nodeData.variable.varName = $3; - $$->nodeData.variable.varNameLength = strlen($3); - $$->nodeData.variable.formatValue = $4; - $$->nodeData.variable.defaultValue = $5; - $$->nodeData.variable.flags = $2 | $6; + $$->type = PrintNode; + $$->nodeData.print.expressionNode = $2; + $$->nodeData.print.formatValue = $3; + $$->nodeData.print.defaultValue = $4; + $$->nodeData.print.flags = $5; } | INCLUDE_OPEN FILENAME INCLUDE_CLOSE { $$ = mc0alloc( curTmpl->templateContext, sizeof(TemplateNodeData) ); @@ -166,12 +232,16 @@ node: $$->nodeData.loop.varNameLength = strlen($3); $$->nodeData.loop.bodyNode = $5; } - | EXPR_OPEN IF_P condition EXPR_CLOSE listnodes EXPR_OPEN ENDIF_P EXPR_CLOSE { - $$ = $3; + | EXPR_OPEN IF_P expression EXPR_CLOSE listnodes EXPR_OPEN ENDIF_P EXPR_CLOSE { + $$ = mc0alloc( curTmpl->templateContext, sizeof(TemplateNodeData) ); + $$->type = ConditionNode; + $$->nodeData.condition.expressionNode = $3; $$->nodeData.condition.ifNode = $5; } - | EXPR_OPEN IF_P condition EXPR_CLOSE listnodes EXPR_OPEN ELSE_P EXPR_CLOSE listnodes EXPR_OPEN ENDIF_P EXPR_CLOSE { - $$ = $3; + | EXPR_OPEN IF_P expression EXPR_CLOSE listnodes EXPR_OPEN ELSE_P EXPR_CLOSE listnodes EXPR_OPEN ENDIF_P EXPR_CLOSE { + $$ = mc0alloc( curTmpl->templateContext, sizeof(TemplateNodeData) ); + $$->type = ConditionNode; + $$->nodeData.condition.expressionNode = $3; $$->nodeData.condition.ifNode = $5; $$->nodeData.condition.elseNode = $9; } @@ -208,3 +278,19 @@ parseTemplateFile(Template tmpl, char* filename ) { return err; } +static TemplateNode +newExpressionNode(char *op, GList *args) { + TemplateNode res; + + res = mc0alloc( curTmpl->templateContext, sizeof(TemplateNodeData) ); + res->type = ExpressionNode; + res->nodeData.expression.functionName = op; + res->nodeData.expression.argsNode = args; + + return res; +} + +static GList * +makeList2(void *a, void *b) { + return GListPush( GListPush(NULL, a), b ); +}