2 * Hic Est Leo -- MapCSS Parser
4 * (c) 2014--2015 Martin Mares <mj@ucw.cz>
9 #include <ucw/mempool.h>
18 static void *css_alloc(size_t n)
20 return mp_alloc_zero(css_this->pool, n);
23 static struct css_path *css_new_path(void)
25 struct css_path *p = css_alloc(sizeof(struct css_path));
26 clist_init(&p->conditions);
27 p->layer = STYLE_LAYER_DEFAULT;
31 static void css_add_to_val_list(struct style_prop *list, struct style_prop *elt)
33 struct style_val_list_entry *e = css_alloc(sizeof(*e));
34 clist_add_tail(list->val.list, &e->n);
42 struct css_rule *rule;
43 struct css_selector *selector;
44 struct css_path *path;
45 struct css_condition *condition;
46 struct css_action *action;
47 struct style_prop prop;
48 enum css_cond_op cond_op;
53 %token <s> NUMBER IDENT QUOTED RGB LUA
55 %type <s> ident_or_quoted
56 %type <rule> rule rule_start rule_selectors rule_start_actions rule_actions
57 %type <selector> selector selector_start
58 %type <path> path path_start path_conditions
59 %type <condition> condition
61 %type <prop> prop_value prop_value_single prop_value_list
62 %type <cond_op> binary_op
73 | input_css rule { clist_add_tail(&css_this->rules, &$2->n); }
79 $$ = css_alloc(sizeof(struct css_rule));
80 clist_init(&$$->selectors);
81 clist_init(&$$->actions);
88 clist_add_tail(&$1->selectors, &$2->n);
91 | rule_selectors ',' selector
93 clist_add_tail(&$1->selectors, &$3->n);
104 rule_start_actions '{'
108 | rule_actions action ';'
111 clist_add_tail(&$$->actions, &$2->n);
115 rule: rule_actions '}' ;
120 $$ = css_alloc(sizeof(struct css_selector));
121 clist_init(&$$->path);
128 clist_add_tail(&$1->path, &$2->n);
133 // FIXME: Descendant operator
134 clist_add_tail(&$1->path, &$2->n);
143 if (!strcmp($1, "node"))
144 $$->type = CSS_TYPE_NODE;
145 else if (!strcmp($1, "way"))
146 $$->type = CSS_TYPE_WAY;
147 else if (!strcmp($1, "relation"))
148 $$->type = CSS_TYPE_RELATION;
149 else if (!strcmp($1, "area"))
150 $$->type = CSS_TYPE_AREA;
151 else if (!strcmp($1, "meta"))
152 $$->type = CSS_TYPE_META;
154 die("Invalid selector %s", $1);
159 $$->type = CSS_TYPE_ANY;
165 | path_conditions '[' condition ']'
168 clist_add_tail(&$$->conditions, &$3->n);
176 // So far, no modifiers are supported, so a rule with modifiers never matches
178 $$->modifiers |= PATH_MOD_NEVER;
184 $$->layer = style_layer_encode($3);
190 $$->layer = STYLE_LAYER_ALL;
195 ident_or_quoted binary_op ident_or_quoted
197 $$ = css_alloc(sizeof(struct css_condition));
199 $$->key = osm_key_encode($1);
200 $$->val = osm_val_encode($3);
204 $$ = css_alloc(sizeof(struct css_condition));
205 $$->op = COND_OP_IS_SET;
206 $$->key = osm_key_encode($1);
208 | '!' ident_or_quoted
210 $$ = css_alloc(sizeof(struct css_condition));
211 $$->op = COND_OP_IS_UNSET;
212 $$->key = osm_key_encode($2);
214 | ident_or_quoted '?'
216 $$ = css_alloc(sizeof(struct css_condition));
217 $$->op = COND_OP_IS_TRUE;
218 $$->key = osm_key_encode($1);
220 | ident_or_quoted '?' '!'
222 $$ = css_alloc(sizeof(struct css_condition));
223 $$->op = COND_OP_IS_FALSE;
224 $$->key = osm_key_encode($1);
229 '=' { $$ = COND_OP_EQ; }
230 | '<' { $$ = COND_OP_LT; }
231 | '>' { $$ = COND_OP_GT; }
232 | LE { $$ = COND_OP_LE; }
233 | GE { $$ = COND_OP_GE; }
234 | NE { $$ = COND_OP_NE; }
238 ident_or_quoted ':' prop_value
240 $$ = css_alloc(sizeof(struct css_action));
241 $$->type = CSS_ACTION_SET;
243 $$->prop.key = style_prop_encode($1);
247 $$ = css_alloc(sizeof(struct css_action));
248 $$->type = CSS_ACTION_EXPR;
249 expr_compile($$, $1);
261 $$.type = PROP_TYPE_IDENT;
262 $$.val.id = osm_val_encode($1);
266 $$.type = PROP_TYPE_STRING;
267 $$.val.id = osm_val_encode($1);
271 $$.type = PROP_TYPE_NUMBER;
272 $$.val.number = atof($1);
276 $$.type = PROP_TYPE_COLOR;
277 $$.val.color = css_rgb_to_color($1);
282 prop_value_single ',' prop_value_single
284 $$.type = PROP_TYPE_LIST;
285 $$.val.list = css_alloc(sizeof(clist));
286 clist_init($$.val.list);
287 css_add_to_val_list(&$$, &$1);
288 css_add_to_val_list(&$$, &$3);
290 | prop_value_list ',' prop_value_single
293 css_add_to_val_list(&$$, &$3);
298 SINGLE_PROP prop_value
300 struct style_prop *p = css_alloc(sizeof(*p));
301 css_this->parsed_prop = p;
306 ident_or_quoted: IDENT | QUOTED ;
310 struct css_sheet *css_this;
312 struct css_sheet *css_load(char *filename)
314 struct mempool *mp = mp_new(4096);
315 struct css_sheet *ss = mp_alloc_zero(mp, sizeof(*ss));
317 clist_init(&ss->rules);
318 ss->filename = mp_strdup(mp, filename);
329 struct style_prop *css_parse_prop(struct mempool *mp, char *objname, const char *key_str, const char *value_str)
331 struct css_sheet ss = {
334 .pushed_token = SINGLE_PROP,
336 clist_init(&ss.rules);
339 css_lex_string(value_str);
342 struct style_prop *p = ss.parsed_prop;
343 p->key = style_prop_encode(key_str);