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 *);
30 static void do_parse_err
(struct ktrfmt_parse_ctx
*, const char *, ...
)
35 do_parse_err
(struct ktrfmt_parse_ctx
*ctx
, const char *fmt
, ...
)
40 vsnprintf
(ctx
->errbuf
, ctx
->errbufsz
, fmt
, ap
);
45 #define parse_err(fmt, ...) \
47 do_parse_err
(ctx
, fmt
, ##__VA_ARGS__); \
52 struct evtr_variable
*
53 evtr_var_new
(const char *name
)
55 struct evtr_variable
*var
;
57 var
= calloc
(1, sizeof
(*var
));
59 if
(!(var
->name
= strdup
(name
))) {
63 var
->val.type
= EVTR_VAL_NIL
;
69 * XXX: should be reentrant
79 snprintf
(buf
, sizeof
(buf
), "@%ld", serno
);
85 index_hash
(struct ktrfmt_parse_ctx
*ctx
, const char *hashname
,
86 evtr_variable_value_t val
, evtr_var_t
*_var
)
90 hsh
= symtab_find
(ctx
->symtab
, hashname
);
91 if
(hsh
->val.type
== EVTR_VAL_NIL
) {
92 /* it's probably the first time we see this "variable" */
93 printd
(PARSE
, "creating hash for %s\n", hsh
->name
);
94 hsh
->val.type
= EVTR_VAL_HASH
;
95 hsh
->val.hashtab
= hash_new
();
96 } else if
(hsh
->val.type
!= EVTR_VAL_HASH
) {
97 printd
(PARSE
, "trying to use type %d as hash\n", hsh
->val.type
);
100 if
(val
->type
== EVTR_VAL_INT
) {
102 printd
(PARSE
, "looking up %s[%jd] in %p\n", hsh
->name
,
103 val
->num
, hsh
->val.hashtab
);
104 } else if
(val
->type
== EVTR_VAL_STR
) {
105 key
= (uintptr_t)val
->str
;
106 printd
(PARSE
, "looking up %s[\"%s\"] in %p\n", hsh
->name
,
107 val
->str
, hsh
->val.hashtab
);
109 do_parse_err
(ctx
, "trying to index hash '%s' with "
110 "non-supported value", hashname
);
114 if
(hash_find
(hsh
->val.hashtab
, key
, &ret
)) {
115 printd
(PARSE
, "didn't find it\n");
116 var
= evtr_var_new
(uniq_varname
());
118 printd
(PARSE
, "inserting it as %s\n", var
->name
);
119 if
(!hash_insert
(hsh
->val.hashtab
, key
,
121 do_parse_err
(ctx
, "can't insert temporary "
122 "variable into hash\n");
125 symtab_insert
(ctx
->symtab
, var
->name
, var
);
127 do_parse_err
(ctx
, "out of memory");
130 var
= (struct evtr_variable
*)ret
;
133 fprintf
(stderr
, "no var!\n");
146 %name
-prefix
"__ktrfmt_"
148 %parse
-param
{struct ktrfmt_parse_ctx
*ctx
}
152 struct evtr_variable
*var
;
153 struct evtr_variable_value
*val
;
163 %token
<na
> TOK_LEFT_BRACK
164 %token
<na
> TOK_RIGHT_BRACK
169 %type
<var
> construct_expr
170 %type
<var
> primary_expr
171 %type
<var
> postfix_expr
172 %type
<var
> unary_expr
173 %type
<na
> assign_expr
188 parse_err
("out of memory");
189 var
= evtr_var_new
(uniq_varname
());
190 var
->val.type
= EVTR_VAL_INT
;
192 var
->val.num
= strtoll
($1->str
, NULL
, 0);
194 parse_err
("Can't parse numeric constant '%s'", $1->str
);
202 parse_err
("out of memory");
203 var
= evtr_var_new
(uniq_varname
());
204 var
->val.type
= EVTR_VAL_STR
;
205 var
->val.str
= $1->str
;
207 parse_err
("out of memory");
213 ctor_args: constant
{
215 ctor
= evtr_var_new
(uniq_varname
());
216 ctor
->val.type
= EVTR_VAL_CTOR
;
217 ctor
->val.ctor.name
= NULL
;
218 TAILQ_INIT
(&ctor
->val.ctor.args
);
219 TAILQ_INSERT_HEAD
(&ctor
->val.ctor.args
, &$1->val
, link
);
222 | constant ctor_args
{
223 TAILQ_INSERT_HEAD
(&$2->val.ctor.args
, &$1->val
, link
);
227 construct_expr: TOK_CTOR
{
230 parse_err
("out of memory");
231 printd
(PARSE
, "TOK_CTOR\n");
232 printd
(PARSE
, "tok: %p, str = %p\n", $1, $1->str
);
233 var
= evtr_var_new
(uniq_varname
());
234 var
->val.type
= EVTR_VAL_CTOR
;
235 var
->val.ctor.name
= $1->str
;
236 TAILQ_INIT
(&var
->val.ctor.args
);
240 | TOK_CTOR ctor_args
{
241 evtr_variable_value_t val
;
243 parse_err
("out of memory");
244 printd
(PARSE
, "TOK_CTOR\n");
245 printd
(PARSE
, "tok: %p, str = %p\n", $1, $1->str
);
246 $2->val.ctor.name
= $1->str
;
248 printd
(PARSE
, "CTOR: %s\n", $1->str
);
249 TAILQ_FOREACH
(val
, &$2->val.ctor.args
, link
) {
252 printd
(PARSE
, "\t%jd\n", val
->num
);
255 printd
(PARSE
, "\t\"%s\"\n", val
->str
);
258 assert
(!"can't get here");
265 primary_expr: TOK_ID
{
268 parse_err
("out of memory");
269 printd
(PARSE
, "TOK_ID\n");
270 printd
(PARSE
, "tok: %p, str = %p\n", $1, $1->str
);
271 var
= symtab_find
(ctx
->symtab
, $1->str
);
273 if
(!(var
= evtr_var_new
($1->str
))) {
275 parse_err
("out of memory");
277 printd
(PARSE
, "creating var %s\n", $1->str
);
278 symtab_insert
(ctx
->symtab
, $1->str
, var
);
287 postfix_expr: postfix_expr TOK_LEFT_BRACK postfix_expr TOK_RIGHT_BRACK
{
290 if
(index_hash
(ctx
, $1->name
, &$3->val
, &var
))
294 | postfix_expr TOK_DOT TOK_ID
{
297 parse_err
("out of memory");
298 tmp
= evtr_var_new
(uniq_varname
());
299 tmp
->val.type
= EVTR_VAL_STR
;
300 tmp
->val.str
= $3->str
;
302 if
(index_hash
(ctx
, $1->name
, &tmp
->val
, &var
))
311 unary_expr: postfix_expr
{
315 assign_expr: unary_expr TOK_EQ constant
{
317 ctx
->ev
->type
= EVTR_TYPE_STMT
;
318 ctx
->ev
->stmt.var
= $1;
319 ctx
->ev
->stmt.val
= &$3->val
;
320 ctx
->ev
->stmt.op
= EVTR_OP_SET
;
322 | unary_expr TOK_EQ construct_expr
{
324 ctx
->ev
->type
= EVTR_TYPE_STMT
;
325 ctx
->ev
->stmt.var
= $1;
326 ctx
->ev
->stmt.val
= &$3->val
;
327 ctx
->ev
->stmt.op
= EVTR_OP_SET
;
337 void * __ktrfmt_scan_string
(const char *);
338 void __ktrfmt_delete_buffer
(void *);
341 __ktrfmt_error
(struct ktrfmt_parse_ctx
*ctx
, const char *s
)
343 do_parse_err
(ctx
, s
);
347 parse_string
(evtr_event_t ev
, struct symtab
*symtab
, const char *str
,
348 char *errbuf
, size_t errbufsz
)
352 struct ktrfmt_parse_ctx ctx
;
354 printd
(PARSE
, "parsing \"%s\"\n", str
);
358 ctx.errbuf
[0] = '\0';
359 ctx.errbufsz
= errbufsz
;
361 bufstate
= __ktrfmt_scan_string
(str
);
362 ret
= __ktrfmt_parse
(&ctx
);
363 __ktrfmt_delete_buffer
(bufstate
);
369 parse_var
(const char *str
, struct symtab
*symtab
, struct evtr_variable
**var
,
370 char *errbuf
, size_t errbufsz
)
374 struct ktrfmt_parse_ctx ctx
;
376 printd
(PARSE
, "parsing \"%s\"\n", str
);
381 ctx.errbuf
[0] = '\0';
382 ctx.errbufsz
= errbufsz
;
384 bufstate
= __ktrfmt_scan_string
(str
);
385 ret
= __ktrfmt_parse
(&ctx
);
386 __ktrfmt_delete_buffer
(bufstate
);