%{ #include #include "playlist.h" #define YYERROR_VERBOSE 1 /* Forwards */ extern PL_NODE *pl_newpredicate(int tag, int op, char *value); extern PL_NODE *pl_newexpr(PL_NODE *arg1, int op, PL_NODE *arg2); extern int pl_addplaylist(char *name, PL_NODE *root); %} %left TOK_OR TOK_AND %union { unsigned int ival; char *cval; PL_NODE *plval; } %token TOK_ARTIST %token TOK_ALBUM %token TOK_GENRE %token TOK_IS %token TOK_INCLUDES %token TOK_OR %token TOK_AND %token TOK_NOT %token TOK_ID %type expression %type predicate %type idtag %type boolarg %type value %type playlist %% playlistlist: playlist | playlistlist playlist ; playlist: TOK_ID '{' expression '}' { $$ = pl_addplaylist($1, $3); } ; expression: expression TOK_AND expression { $$=pl_newexpr($1,$2,$3); } | expression TOK_OR expression { $$=pl_newexpr($1,$2,$3); } | '(' expression ')' { $$=$2; } | predicate ; predicate: idtag boolarg value { $$=pl_newpredicate($1, $2, $3); } idtag: TOK_ARTIST | TOK_ALBUM | TOK_GENRE ; boolarg: TOK_IS | TOK_INCLUDES | TOK_NOT boolarg { $$=$2 | 0x80000000; } ; value: TOK_ID ; %% PL_NODE *pl_newpredicate(int tag, int op, char *value) { PL_NODE *pnew; pnew=(PL_NODE*)malloc(sizeof(PL_NODE)); if(!pnew) return NULL; pnew->op=op; pnew->arg1.ival=tag; pnew->arg2.cval=value; return pnew; } PL_NODE *pl_newexpr(PL_NODE *arg1, int op, PL_NODE *arg2) { PL_NODE *pnew; pnew=(PL_NODE*)malloc(sizeof(PL_NODE)); if(!pnew) return NULL; pnew->op=op; pnew->arg1.plval=arg1; pnew->arg2.plval=arg2; return pnew; } int pl_addplaylist(char *name, PL_NODE *root) { SMART_PLAYLIST *pnew; pnew=(SMART_PLAYLIST *)malloc(sizeof(SMART_PLAYLIST)); if(!pnew) return -1; pnew->next=pl_smart.next; pnew->name=name; pnew->root=root; pl_smart.next=pnew; return 0; }