12 #include "ktrfmt.tab.h"
15 struct ktrfmt_parse_ctx {
16 struct symtab *symtab;
17 struct evtr_variable *var;
18 struct evtr_variable_value *val;
25 int __ktrfmtlex(YYSTYPE *);
26 #define __ktrfmt_lex __ktrfmtlex
28 void __ktrfmt_error (struct ktrfmt_parse_ctx *, const char *);
32 do_parse_err(struct ktrfmt_parse_ctx *ctx, const char *fmt, ...)
37 vsnprintf(ctx->errbuf, ctx->errbufsz, fmt, ap);
42 #define parse_err(fmt, ...) \
44 do_parse_err(ctx, fmt, ##__VA_ARGS__); \
49 struct evtr_variable *
50 evtr_var_new(const char *name)
52 struct evtr_variable *var;
54 var = calloc(1, sizeof(*var));
56 if (!(var->name = strdup(name))) {
60 var->val.type = EVTR_VAL_NIL;
66 * XXX: should be reentrant
76 snprintf(buf, sizeof(buf), "@%ld", serno);
82 index_hash(struct ktrfmt_parse_ctx *ctx, const char *hashname,
83 evtr_variable_value_t val, evtr_var_t *_var)
87 hsh = symtab_find(ctx->symtab, hashname);
88 if (hsh->val.type == EVTR_VAL_NIL) {
89 /* it's probably the first time we see this "variable" */
90 printd(PARSE, "creating hash for %s\n", hsh->name);
91 hsh->val.type = EVTR_VAL_HASH;
92 hsh->val.hashtab = hash_new();
93 } else if (hsh->val.type != EVTR_VAL_HASH) {
94 printd(PARSE, "trying to use type %d as hash\n", hsh->val.type);
97 if (val->type == EVTR_VAL_INT) {
99 printd(PARSE, "looking up %s[%jd] in %p\n", hsh->name,
100 val->num, hsh->val.hashtab);
101 } else if (val->type == EVTR_VAL_STR) {
102 key = (uintptr_t)val->str;
103 printd(PARSE, "looking up %s[\"%s\"] in %p\n", hsh->name,
104 val->str, hsh->val.hashtab);
106 do_parse_err(ctx, "trying to index hash '%s' with "
107 "non-supported value", hashname);
111 if (hash_find(hsh->val.hashtab, key, &ret)) {
112 printd(PARSE, "didn't find it\n");
113 var = evtr_var_new(uniq_varname());
115 printd(PARSE, "inserting it as %s\n", var->name);
116 if (!hash_insert(hsh->val.hashtab, key,
118 do_parse_err(ctx, "can't insert temporary "
119 "variable into hash\n");
122 symtab_insert(ctx->symtab, var->name, var);
124 do_parse_err(ctx, "out of memory");
127 var = (struct evtr_variable *)ret;
130 fprintf(stderr, "no var!\n");
143 %name-prefix "__ktrfmt_"
145 %parse-param{struct ktrfmt_parse_ctx *ctx}
149 struct evtr_variable *var;
150 struct evtr_variable_value *val;
160 %token<na> TOK_LEFT_BRACK
161 %token<na> TOK_RIGHT_BRACK
166 %type<var> construct_expr
167 %type<var> primary_expr
168 %type<var> postfix_expr
169 %type<var> unary_expr
170 %type<na> assign_expr
185 parse_err("out of memory");
186 var = evtr_var_new(uniq_varname());
187 var->val.type = EVTR_VAL_INT;
189 var->val.num = strtoll($1->str, NULL, 0);
191 parse_err("Can't parse numeric constant '%s'", $1->str);
199 parse_err("out of memory");
200 var = evtr_var_new(uniq_varname());
201 var->val.type = EVTR_VAL_STR;
202 var->val.str = $1->str;
204 parse_err("out of memory");
210 ctor_args: constant {
212 ctor = evtr_var_new(uniq_varname());
213 ctor->val.type = EVTR_VAL_CTOR;
214 ctor->val.ctor.name = NULL;
215 TAILQ_INIT(&ctor->val.ctor.args);
216 TAILQ_INSERT_HEAD(&ctor->val.ctor.args, &$1->val, link);
219 | constant ctor_args {
220 TAILQ_INSERT_HEAD(&$2->val.ctor.args, &$1->val, link);
224 construct_expr: TOK_CTOR {
227 parse_err("out of memory");
228 printd(PARSE, "TOK_CTOR\n");
229 printd(PARSE, "tok: %p, str = %p\n", $1, $1->str);
230 var = evtr_var_new(uniq_varname());
231 var->val.type = EVTR_VAL_CTOR;
232 var->val.ctor.name = $1->str;
233 TAILQ_INIT(&var->val.ctor.args);
237 | TOK_CTOR ctor_args {
238 evtr_variable_value_t val;
240 parse_err("out of memory");
241 printd(PARSE, "TOK_CTOR\n");
242 printd(PARSE, "tok: %p, str = %p\n", $1, $1->str);
243 $2->val.ctor.name = $1->str;
245 printd(PARSE, "CTOR: %s\n", $1->str);
246 TAILQ_FOREACH(val, &$2->val.ctor.args, link) {
249 printd(PARSE, "\t%jd\n", val->num);
252 printd(PARSE, "\t\"%s\"\n", val->str);
255 assert(!"can't get here");
262 primary_expr: TOK_ID {
265 parse_err("out of memory");
266 printd(PARSE, "TOK_ID\n");
267 printd(PARSE, "tok: %p, str = %p\n", $1, $1->str);
268 var = symtab_find(ctx->symtab, $1->str);
270 if (!(var = evtr_var_new($1->str))) {
272 parse_err("out of memory");
274 printd(PARSE, "creating var %s\n", $1->str);
275 symtab_insert(ctx->symtab, $1->str, var);
284 postfix_expr: postfix_expr TOK_LEFT_BRACK postfix_expr TOK_RIGHT_BRACK {
287 if (index_hash(ctx, $1->name, &$3->val, &var))
291 | postfix_expr TOK_DOT TOK_ID {
294 parse_err("out of memory");
295 tmp = evtr_var_new(uniq_varname());
296 tmp->val.type = EVTR_VAL_STR;
297 tmp->val.str = $3->str;
299 if (index_hash(ctx, $1->name, &tmp->val, &var))
308 unary_expr: postfix_expr {
312 assign_expr: unary_expr TOK_EQ constant {
314 ctx->ev->type = EVTR_TYPE_STMT;
315 ctx->ev->stmt.var = $1;
316 ctx->ev->stmt.val = &$3->val;
317 ctx->ev->stmt.op = EVTR_OP_SET;
319 | unary_expr TOK_EQ construct_expr {
321 ctx->ev->type = EVTR_TYPE_STMT;
322 ctx->ev->stmt.var = $1;
323 ctx->ev->stmt.val = &$3->val;
324 ctx->ev->stmt.op = EVTR_OP_SET;
334 void * __ktrfmt_scan_string(const char *);
335 void __ktrfmt_delete_buffer(void *);
338 __ktrfmt_error (struct ktrfmt_parse_ctx *ctx, const char *s)
340 do_parse_err(ctx, s);
344 parse_string(evtr_event_t ev, struct symtab *symtab, const char *str,
345 char *errbuf, size_t errbufsz)
349 struct ktrfmt_parse_ctx ctx;
351 printd(PARSE, "parsing \"%s\"\n", str);
355 ctx.errbuf[0] = '\0';
356 ctx.errbufsz = errbufsz;
358 bufstate = __ktrfmt_scan_string(str);
359 ret = __ktrfmt_parse(&ctx);
360 __ktrfmt_delete_buffer(bufstate);
366 parse_var(const char *str, struct symtab *symtab, struct evtr_variable **var,
367 char *errbuf, size_t errbufsz)
371 struct ktrfmt_parse_ctx ctx;
373 printd(PARSE, "parsing \"%s\"\n", str);
378 ctx.errbuf[0] = '\0';
379 ctx.errbufsz = errbufsz;
381 bufstate = __ktrfmt_scan_string(str);
382 ret = __ktrfmt_parse(&ctx);
383 __ktrfmt_delete_buffer(bufstate);