2 * Hic Est Leo -- MapCSS Parser
4 * (c) 2014 Martin Mares <mj@ucw.cz>
9 #include <ucw/mempool.h>
17 static void *css_alloc(size_t n)
19 return mp_alloc_zero(css_this->pool, n);
22 static struct css_path *css_new_path(void)
24 struct css_path *p = css_alloc(sizeof(struct css_path));
25 clist_init(&p->conditions);
26 p->layer = STYLE_LAYER_DEFAULT;
30 static void css_add_to_val_list(struct style_prop *list, struct style_prop *elt)
32 struct style_val_list_entry *e = css_alloc(sizeof(*e));
33 clist_add_tail(list->val.list, &e->n);
41 struct css_rule *rule;
42 struct css_selector *selector;
43 struct css_path *path;
44 struct css_condition *condition;
45 struct css_action *action;
46 struct style_prop prop;
47 enum css_cond_op cond_op;
52 %token <s> NUMBER IDENT QUOTED RGB
54 %type <s> ident_or_quoted
55 %type <rule> rule rule_start rule_selectors rule_start_actions rule_actions
56 %type <selector> selector selector_start
57 %type <path> path path_start path_conditions
58 %type <condition> condition
60 %type <prop> prop_value prop_value_single prop_value_list
61 %type <cond_op> binary_op
72 | input_css rule { clist_add_tail(&css_this->rules, &$2->n); }
78 $$ = css_alloc(sizeof(struct css_rule));
79 clist_init(&$$->selectors);
80 clist_init(&$$->actions);
87 clist_add_tail(&$1->selectors, &$2->n);
90 | rule_selectors ',' selector
92 clist_add_tail(&$1->selectors, &$3->n);
103 rule_start_actions '{'
107 | rule_actions action ';'
110 clist_add_tail(&$$->actions, &$2->n);
114 rule: rule_actions '}' ;
119 $$ = css_alloc(sizeof(struct css_selector));
120 clist_init(&$$->path);
127 clist_add_tail(&$1->path, &$2->n);
132 // FIXME: Descendant operator
133 clist_add_tail(&$1->path, &$2->n);
142 if (!strcmp($1, "node"))
143 $$->type = CSS_TYPE_NODE;
144 else if (!strcmp($1, "way"))
145 $$->type = CSS_TYPE_WAY;
146 else if (!strcmp($1, "relation"))
147 $$->type = CSS_TYPE_RELATION;
148 else if (!strcmp($1, "area"))
149 $$->type = CSS_TYPE_AREA;
150 else if (!strcmp($1, "meta"))
151 $$->type = CSS_TYPE_META;
153 die("Invalid selector %s", $1);
158 $$->type = CSS_TYPE_ANY;
164 | path_conditions '[' condition ']'
167 clist_add_tail(&$$->conditions, &$3->n);
175 // So far, no modifiers are supported, so a rule with modifiers never matches
177 $$->modifiers |= PATH_MOD_NEVER;
183 $$->layer = style_layer_encode($3);
189 $$->layer = STYLE_LAYER_ALL;
194 ident_or_quoted binary_op ident_or_quoted
196 $$ = css_alloc(sizeof(struct css_condition));
198 $$->key = osm_key_encode($1);
199 $$->val = osm_val_encode($3);
203 $$ = css_alloc(sizeof(struct css_condition));
204 $$->op = COND_OP_IS_SET;
205 $$->key = osm_key_encode($1);
207 | '!' ident_or_quoted
209 $$ = css_alloc(sizeof(struct css_condition));
210 $$->op = COND_OP_IS_UNSET;
211 $$->key = osm_key_encode($2);
213 | ident_or_quoted '?'
215 $$ = css_alloc(sizeof(struct css_condition));
216 $$->op = COND_OP_IS_TRUE;
217 $$->key = osm_key_encode($1);
219 | ident_or_quoted '?' '!'
221 $$ = css_alloc(sizeof(struct css_condition));
222 $$->op = COND_OP_IS_FALSE;
223 $$->key = osm_key_encode($1);
228 '=' { $$ = COND_OP_EQ; }
229 | '<' { $$ = COND_OP_LT; }
230 | '>' { $$ = COND_OP_GT; }
231 | LE { $$ = COND_OP_LE; }
232 | GE { $$ = COND_OP_GE; }
233 | NE { $$ = COND_OP_NE; }
237 ident_or_quoted ':' prop_value
239 $$ = css_alloc(sizeof(struct css_action));
241 $$->prop.key = style_prop_encode($1);
253 $$.type = PROP_TYPE_IDENT;
254 $$.val.id = osm_val_encode($1);
258 $$.type = PROP_TYPE_STRING;
259 $$.val.id = osm_val_encode($1);
263 $$.type = PROP_TYPE_NUMBER;
264 $$.val.number = atof($1);
268 $$.type = PROP_TYPE_COLOR;
269 $$.val.color = css_rgb_to_color($1);
274 prop_value_single ',' prop_value_single
276 $$.type = PROP_TYPE_LIST;
277 $$.val.list = css_alloc(sizeof(clist));
278 clist_init($$.val.list);
279 css_add_to_val_list(&$$, &$1);
280 css_add_to_val_list(&$$, &$3);
282 | prop_value_list ',' prop_value_single
285 css_add_to_val_list(&$$, &$3);
290 SINGLE_PROP prop_value
292 struct style_prop *p = css_alloc(sizeof(*p));
293 css_this->parsed_prop = p;
298 ident_or_quoted: IDENT | QUOTED ;
302 struct css_sheet *css_this;
304 struct css_sheet *css_load(char *filename)
306 struct mempool *mp = mp_new(4096);
307 struct css_sheet *ss = mp_alloc_zero(mp, sizeof(*ss));
309 clist_init(&ss->rules);
310 ss->filename = mp_strdup(mp, filename);
321 struct style_prop *css_parse_prop(struct mempool *mp, char *objname, const char *key_str, const char *value_str)
323 struct css_sheet ss = {
326 .pushed_token = SINGLE_PROP,
328 clist_init(&ss.rules);
331 css_lex_string(value_str);
334 struct style_prop *p = ss.parsed_prop;
335 p->key = style_prop_encode(key_str);