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;
51 %token <s> NUMBER IDENT QUOTED RGB
53 %type <s> ident_or_quoted
54 %type <rule> rule rule_start rule_selectors rule_start_actions rule_actions
55 %type <selector> selector selector_start
56 %type <path> path path_start path_conditions
57 %type <condition> condition
59 %type <prop> prop_value prop_value_single prop_value_list
60 %type <cond_op> binary_op
66 | input rule { clist_add_tail(&css_this->rules, &$2->n); }
72 $$ = css_alloc(sizeof(struct css_rule));
73 clist_init(&$$->selectors);
74 clist_init(&$$->actions);
81 clist_add_tail(&$1->selectors, &$2->n);
84 | rule_selectors ',' selector
86 clist_add_tail(&$1->selectors, &$3->n);
97 rule_start_actions '{'
101 | rule_actions action ';'
104 clist_add_tail(&$$->actions, &$2->n);
108 rule: rule_actions '}' ;
113 $$ = css_alloc(sizeof(struct css_selector));
114 clist_init(&$$->path);
121 clist_add_tail(&$1->path, &$2->n);
126 // FIXME: Descendant operator
127 clist_add_tail(&$1->path, &$2->n);
136 if (!strcmp($1, "node"))
137 $$->type = CSS_TYPE_NODE;
138 else if (!strcmp($1, "way"))
139 $$->type = CSS_TYPE_WAY;
140 else if (!strcmp($1, "relation"))
141 $$->type = CSS_TYPE_RELATION;
142 else if (!strcmp($1, "area"))
143 $$->type = CSS_TYPE_AREA;
144 else if (!strcmp($1, "meta"))
145 $$->type = CSS_TYPE_META;
147 die("Invalid selector %s", $1);
152 $$->type = CSS_TYPE_ANY;
158 | path_conditions '[' condition ']'
161 clist_add_tail(&$$->conditions, &$3->n);
169 // So far, no modifiers are supported, so a rule with modifiers never matches
171 $$->modifiers |= PATH_MOD_NEVER;
177 $$->layer = style_layer_encode($3);
183 $$->layer = STYLE_LAYER_ALL;
188 ident_or_quoted binary_op ident_or_quoted
190 $$ = css_alloc(sizeof(struct css_condition));
192 $$->key = osm_key_encode($1);
193 $$->val = osm_val_encode($3);
197 $$ = css_alloc(sizeof(struct css_condition));
198 $$->op = COND_OP_IS_SET;
199 $$->key = osm_key_encode($1);
201 | '!' ident_or_quoted
203 $$ = css_alloc(sizeof(struct css_condition));
204 $$->op = COND_OP_IS_UNSET;
205 $$->key = osm_key_encode($2);
207 | ident_or_quoted '?'
209 $$ = css_alloc(sizeof(struct css_condition));
210 $$->op = COND_OP_IS_TRUE;
211 $$->key = osm_key_encode($1);
213 | ident_or_quoted '?' '!'
215 $$ = css_alloc(sizeof(struct css_condition));
216 $$->op = COND_OP_IS_FALSE;
217 $$->key = osm_key_encode($1);
222 '=' { $$ = COND_OP_EQ; }
223 | '<' { $$ = COND_OP_LT; }
224 | '>' { $$ = COND_OP_GT; }
225 | LE { $$ = COND_OP_LE; }
226 | GE { $$ = COND_OP_GE; }
227 | NE { $$ = COND_OP_NE; }
231 ident_or_quoted ':' prop_value
233 $$ = css_alloc(sizeof(struct css_action));
235 $$->prop.key = style_prop_encode($1);
247 $$.type = PROP_TYPE_IDENT;
248 $$.val.id = osm_val_encode($1);
252 $$.type = PROP_TYPE_STRING;
253 $$.val.id = osm_val_encode($1);
257 $$.type = PROP_TYPE_NUMBER;
258 $$.val.number = atof($1);
262 $$.type = PROP_TYPE_COLOR;
263 $$.val.color = css_rgb_to_color($1);
268 prop_value_single ',' prop_value_single
270 $$.type = PROP_TYPE_LIST;
271 $$.val.list = css_alloc(sizeof(clist));
272 clist_init($$.val.list);
273 css_add_to_val_list(&$$, &$1);
274 css_add_to_val_list(&$$, &$3);
276 | prop_value_list ',' prop_value_single
279 css_add_to_val_list(&$$, &$3);
283 ident_or_quoted: IDENT | QUOTED ;
287 struct css_sheet *css_this;
289 struct css_sheet *css_load(char *filename)
291 struct mempool *mp = mp_new(4096);
292 struct css_sheet *ss = mp_alloc_zero(mp, sizeof(*ss));
294 clist_init(&ss->rules);
295 ss->filename = mp_strdup(mp, filename);