/* Copyright (C) 2017 Andre Noll , see file COPYING. */ /* * Since we do not supply yywrap(), we use noyywrap to instruct the scanner to * behave as though yywrap() returned 1. */ %option noyywrap /* * We don't want symbols to clash with those of other flex users, particularly * lopsub. */ %option prefix="mp_yy" /* * Generate a scanner that maintains the number of the current line read from * its input in the yylineno variable. */ %option yylineno /* Generate a bison-compatible scanner. */ %option bison-bridge bison-locations /* * Warn (in particular) if the default rule can be matched but no default rule * has been given. */ %option warn /* * Generate a scanner which is portable and safe to use in one or more threads * of control. */ %option reentrant /* * Generate a scanner which always looks one extra character ahead. This is a * bit faster than an interactive scanner for which look ahead happens only * when necessary. */ %option never-interactive %{ #include #include "para.h" #include "string.h" #include "mp.h" #include "error.h" #define YYSTYPE MP_YYSTYPE #define YYLTYPE MP_YYLTYPE #define YY_DECL int mp_yylex(MP_YYSTYPE *yylval_param, MP_YYLTYPE *yylloc_param, \ struct mp_context *ctx, struct mp_ast_node **ast, mp_yyscan_t yyscanner) #include "mp.bison.h" #define MP_YY_USER_ACTION do {mp_yylloc->first_line = mp_yylineno;} while (0); %} DECIMAL_CONSTANT (0|([[:digit:]]{-}[0])[[:digit:]]*) STRING_LITERAL \"([^\"\\\n]|(\\[\"\\abfnrtv]))*\" REGEX_PATTERN \/([^\/\\\n]|(\\[\/\\abfnrtv]))*\/([in])* WILDCARD_PATTERN \|([^\|\\\n]|(\\[\|\\abfnrtv]))*\|([npPlie])* %% is_set {return IS_SET;} num_attributes_set {return NUM_ATTRIBUTES_SET;} path {return PATH;} artist {return ARTIST;} title {return TITLE;} album {return ALBUM;} comment {return COMMENT;} year {return YEAR;} num_played {return NUM_PLAYED;} image_id {return IMAGE_ID;} lyrics_id {return LYRICS_ID;} bitrate {return BITRATE;} frequency {return FREQUENCY;} channels {return CHANNELS;} true {return TRUE;} false {return FALSE;} [[:space:]]+|#.*\n /* skip comments and whitespace */ "("|")"|","|"+"|"-"|"*"|"/"|"<"|">" {return yytext[0];} "||" {return OR;} "&&" {return AND;} "!" {return NOT;} "==" {return EQUAL;} "!=" {return NOT_EQUAL;} "<=" {return LESS_OR_EQUAL;} ">=" {return GREATER_OR_EQUAL;} "=~" {return REGEX_MATCH;} "=|" {return FILENAME_MATCH;} {DECIMAL_CONSTANT} { int ret; yylval->node = mp_new_ast_leaf_node(NUM); ret = para_atoi64(yytext, &yylval->node->sv.intval); if (ret < 0) { free(yylval->node); mp_parse_error(yylloc->first_line, ctx, "%s: %s", yytext, para_strerror(-ret)); return -E_MOOD_PARSE; } return NUM; } {STRING_LITERAL} { yylval->node = mp_new_ast_leaf_node(STRING_LITERAL); parse_quoted_string(yytext, "\"\"", &yylval->node->sv.strval); //PARA_CRIT_LOG("strval: %s\n", yylval->node->sv.strval); //PARA_CRIT_LOG("node: %p\n", yylval->node); return STRING_LITERAL; } {REGEX_PATTERN} { int ret; yylval->node = mp_new_ast_leaf_node(REGEX_PATTERN); ret = mp_parse_regex_pattern(yytext, &yylval->node->sv.re_pattern); if (ret < 0) { mp_parse_error(yylloc->first_line, ctx, "%s: %s", yytext, para_strerror(-ret)); return -E_MOOD_PARSE; } return REGEX_PATTERN; } {WILDCARD_PATTERN} { yylval->node = mp_new_ast_leaf_node(WILDCARD_PATTERN); mp_parse_wildcard_pattern(yytext, &yylval->node->sv.wc_pattern); return WILDCARD_PATTERN; } . { mp_parse_error(yylloc->first_line, ctx, "unrecognized text: %s", yytext); return -E_MOOD_PARSE; }