4a53db2741754bf6359733af8b42ca60ca255e92
[paraslash.git] / yy / mp.lex
1 /* Copyright (C) 2017 Andre Noll <maan@tuebingen.mpg.de>, see file COPYING. */
2
3  /*
4   * Since we do not supply yywrap(), we use noyywrap to instruct the scanner to
5   * behave as though yywrap() returned 1.
6   */
7 %option noyywrap
8
9  /*
10   * We don't want symbols to clash with those of other flex users, particularly
11   * lopsub.
12   */
13 %option prefix="mp_yy"
14
15  /*
16   * Generate a scanner that maintains the number of the current line read from
17   * its input in the yylineno variable.
18   */
19 %option yylineno
20
21  /* Generate a bison-compatible scanner. */
22 %option bison-bridge bison-locations
23
24  /*
25   * Warn (in particular) if the default rule can be matched but no default rule
26   * has been given.
27   */
28 %option warn
29
30  /*
31   * Generate a scanner which is portable and safe to use in one or more threads
32   * of control.
33   */
34 %option reentrant
35
36  /*
37   * Generate a scanner which always looks one extra character ahead. This is a
38   * bit faster than an interactive scanner for which look ahead happens only
39   * when necessary.
40   */
41 %option never-interactive
42
43 %{
44 #include <regex.h>
45 #include "para.h"
46 #include "string.h"
47 #include "mp.h"
48 #include "error.h"
49
50 #define YYSTYPE MP_YYSTYPE
51 #define YYLTYPE MP_YYLTYPE
52 #define YY_DECL int mp_yylex(MP_YYSTYPE *yylval_param, MP_YYLTYPE *yylloc_param, \
53         struct mp_context *ctx, struct mp_ast_node **ast, mp_yyscan_t yyscanner)
54 #include "mp.bison.h"
55 #define MP_YY_USER_ACTION do {mp_yylloc->first_line = mp_yylineno;} while (0);
56 %}
57 DECIMAL_CONSTANT  (0|([[:digit:]]{-}[0])[[:digit:]]*)
58 STRING_LITERAL    \"([^\"\\\n]|(\\[\"\\abfnrtv]))*\"
59 REGEX_PATTERN     \/([^\/\\\n]|(\\[\/\\abfnrtv]))*\/([in])*
60 WILDCARD_PATTERN  \|([^\|\\\n]|(\\[\|\\abfnrtv]))*\|([npPlie])*
61 %%
62
63 is_set {return IS_SET;}
64 num_attributes_set {return NUM_ATTRIBUTES_SET;}
65 path {return PATH;}
66 artist {return ARTIST;}
67 title {return TITLE;}
68 album {return ALBUM;}
69 comment {return COMMENT;}
70 year {return YEAR;}
71 num_played {return NUM_PLAYED;}
72 image_id {return IMAGE_ID;}
73 lyrics_id {return LYRICS_ID;}
74 bitrate {return BITRATE;}
75 frequency {return FREQUENCY;}
76 channels {return CHANNELS;}
77 duration {return DURATION;}
78 true {return TRUE;}
79 false {return FALSE;}
80
81 [[:space:]]+|#.*\n /* skip comments and whitespace */
82
83 "("|")"|","|"+"|"-"|"*"|"/"|"<"|">" {return yytext[0];}
84
85 "||" {return OR;}
86 "&&" {return AND;}
87 "!" {return NOT;}
88 "==" {return EQUAL;}
89 "!=" {return NOT_EQUAL;}
90 "<=" {return LESS_OR_EQUAL;}
91 ">=" {return GREATER_OR_EQUAL;}
92 "=~" {return REGEX_MATCH;}
93 "=|" {return FILENAME_MATCH;}
94
95 {DECIMAL_CONSTANT} {
96         int ret;
97         yylval->node = mp_new_ast_leaf_node(NUM);
98         ret = para_atoi64(yytext, &yylval->node->sv.intval);
99         if (ret < 0) {
100                 free(yylval->node);
101                 mp_parse_error(yylloc->first_line, ctx, "%s: %s", yytext,
102                         para_strerror(-ret));
103                 return -E_MOOD_PARSE;
104         }
105         return NUM;
106 }
107
108 {STRING_LITERAL} {
109         yylval->node = mp_new_ast_leaf_node(STRING_LITERAL);
110         parse_quoted_string(yytext, "\"\"", &yylval->node->sv.strval);
111         //PARA_CRIT_LOG("strval: %s\n", yylval->node->sv.strval);
112         //PARA_CRIT_LOG("node: %p\n", yylval->node);
113         return STRING_LITERAL;
114 }
115
116 {REGEX_PATTERN} {
117         int ret;
118         yylval->node = mp_new_ast_leaf_node(REGEX_PATTERN);
119         ret = mp_parse_regex_pattern(yytext, &yylval->node->sv.re_pattern);
120         if (ret < 0) {
121                 mp_parse_error(yylloc->first_line, ctx, "%s: %s", yytext,
122                         para_strerror(-ret));
123                 return -E_MOOD_PARSE;
124         }
125         return REGEX_PATTERN;
126 }
127
128 {WILDCARD_PATTERN} {
129         yylval->node = mp_new_ast_leaf_node(WILDCARD_PATTERN);
130         mp_parse_wildcard_pattern(yytext, &yylval->node->sv.wc_pattern);
131         return WILDCARD_PATTERN;
132 }
133
134 . {
135         mp_parse_error(yylloc->first_line, ctx, "unrecognized text: %s",
136                 yytext);
137         return -E_MOOD_PARSE;
138 }