X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;ds=sidebyside;f=formats%2Fctf%2Fmetadata%2Fctf-parser.y;h=4ae9b4ee64fbc16a4dc4e5742385cfba8c9deb01;hb=02b234c461611f6f479c2dc3697a1b42b03cf050;hp=f5cb22ad358eee395ecfad052cf8cfad79524a44;hpb=8b9d5b5e700bdf66edf4c0fa035fdf10cb3b36f3;p=babeltrace.git diff --git a/formats/ctf/metadata/ctf-parser.y b/formats/ctf/metadata/ctf-parser.y index f5cb22ad..4ae9b4ee 100644 --- a/formats/ctf/metadata/ctf-parser.y +++ b/formats/ctf/metadata/ctf-parser.y @@ -1,8 +1,20 @@ %{ /* - * ctf.y + * ctf-parser.y * * Common Trace Format Metadata Grammar. + * + * Copyright 2010 - Mathieu Desnoyers + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. */ #include @@ -12,32 +24,26 @@ #include #include #include +#include +#include "ctf-scanner.h" #include "ctf-parser.h" #include "ctf-ast.h" -#define printf_dbg(fmt, args...) fprintf(stderr, "%s: " fmt, __func__, args) -#define printf_dbg_noarg(fmt) fprintf(stderr, "%s: " fmt, __func__) +#define printf_dbg(fmt, args...) fprintf(stderr, "%s: " fmt, __func__, ## args) -int yyparse(void); -int yylex(void); +int yyparse(struct ctf_scanner *scanner); +int yylex(union YYSTYPE *yyval, struct ctf_scanner *scanner); +int yylex_init_extra(struct ctf_scanner *scanner, yyscan_t * ptr_yy_globals); +int yylex_destroy(yyscan_t yyscanner) ; +void yyset_in(FILE * in_str, yyscan_t scanner); -static CDS_LIST_HEAD(allocated_strings); int yydebug; -struct scope; -struct scope { - struct scope *parent; - GHashTable *types; -}; - struct gc_string { struct cds_list_head gc; char s[]; }; -struct scope root_scope; -struct scope *cs = &root_scope; /* current scope */ - char *strredup(char **dest, const char *src) { size_t len = strlen(src) + 1; @@ -49,55 +55,56 @@ char *strredup(char **dest, const char *src) return *dest; } -static struct gc_string *gc_string_alloc(size_t len) +static struct gc_string *gc_string_alloc(struct ctf_scanner *scanner, size_t len) { struct gc_string *gstr; gstr = malloc(sizeof(*gstr) + len); - cds_list_add(&gstr->gc, &allocated_strings); + cds_list_add(&gstr->gc, &scanner->allocated_strings); return gstr; } -void setstring(const char *src) +void setstring(struct ctf_scanner *scanner, YYSTYPE *lvalp, const char *src) { - yylval.gs = gc_string_alloc(strlen(src) + 1); - strcpy(yylval.gs->s, src); + lvalp->gs = gc_string_alloc(scanner, strlen(src) + 1); + strcpy(lvalp->gs->s, src); } -static void init_scope(struct scope *scope, struct scope *parent) +static void init_scope(struct ctf_scanner_scope *scope, + struct ctf_scanner_scope *parent) { scope->parent = parent; scope->types = g_hash_table_new_full(g_str_hash, g_str_equal, (GDestroyNotify) free, NULL); } -static void finalize_scope(struct scope *scope) +static void finalize_scope(struct ctf_scanner_scope *scope) { g_hash_table_destroy(scope->types); } -static void push_scope(void) +static void push_scope(struct ctf_scanner *scanner) { - struct scope *ns; + struct ctf_scanner_scope *ns; - printf_dbg_noarg("push scope\n"); - ns = malloc(sizeof(struct scope)); - init_scope(ns, cs); - cs = ns; + printf_dbg("push scope\n"); + ns = malloc(sizeof(struct ctf_scanner_scope)); + init_scope(ns, scanner->cs); + scanner->cs = ns; } -static void pop_scope(void) +static void pop_scope(struct ctf_scanner *scanner) { - struct scope *os; + struct ctf_scanner_scope *os; - printf_dbg_noarg("pop scope\n"); - os = cs; - cs = os->parent; + printf_dbg("pop scope\n"); + os = scanner->cs; + scanner->cs = os->parent; finalize_scope(os); free(os); } -int lookup_type(struct scope *s, const char *id) +static int lookup_type(struct ctf_scanner_scope *s, const char *id) { int ret; @@ -106,12 +113,12 @@ int lookup_type(struct scope *s, const char *id) return ret; } -int is_type(const char *id) +int is_type(struct ctf_scanner *scanner, const char *id) { - struct scope *it; + struct ctf_scanner_scope *it; int ret = 0; - for (it = cs; it != NULL; it = it->parent) { + for (it = scanner->cs; it != NULL; it = it->parent) { if (lookup_type(it, id)) { ret = 1; break; @@ -121,18 +128,524 @@ int is_type(const char *id) return ret; } -static void add_type(const char *id) +static void add_type(struct ctf_scanner *scanner, const char *id) { char *type_id = NULL; printf_dbg("add type %s\n", id); - if (lookup_type(cs, id)) + if (lookup_type(scanner->cs, id)) return; strredup(&type_id, id); - g_hash_table_insert(cs->types, type_id, type_id); + g_hash_table_insert(scanner->cs->types, type_id, type_id); +} + +static struct ctf_node *make_node(struct ctf_scanner *scanner, + enum node_type type) +{ + struct ctf_ast *ast = ctf_scanner_get_ast(scanner); + struct ctf_node *node; + + node = malloc(sizeof(*node)); + if (!node) + return NULL; + memset(node, 0, sizeof(*node)); + node->type = type; + CDS_INIT_LIST_HEAD(&node->siblings); + cds_list_add(&node->gc, &ast->allocated_nodes); + + switch (type) { + case NODE_ROOT: + fprintf(stderr, "[error] %s: trying to create root node\n", __func__); + break; + + case NODE_EVENT: + CDS_INIT_LIST_HEAD(&node->u.event._typedef); + CDS_INIT_LIST_HEAD(&node->u.event.typealias); + CDS_INIT_LIST_HEAD(&node->u.event.ctf_expression); + CDS_INIT_LIST_HEAD(&node->u.event.declaration_specifier); + break; + case NODE_STREAM: + CDS_INIT_LIST_HEAD(&node->u.stream._typedef); + CDS_INIT_LIST_HEAD(&node->u.stream.typealias); + CDS_INIT_LIST_HEAD(&node->u.stream.ctf_expression); + CDS_INIT_LIST_HEAD(&node->u.stream.declaration_specifier); + break; + case NODE_TRACE: + CDS_INIT_LIST_HEAD(&node->u.trace._typedef); + CDS_INIT_LIST_HEAD(&node->u.trace.typealias); + CDS_INIT_LIST_HEAD(&node->u.trace.ctf_expression); + CDS_INIT_LIST_HEAD(&node->u.trace.declaration_specifier); + break; + + case NODE_CTF_EXPRESSION: + break; + + case NODE_TYPEDEF: + CDS_INIT_LIST_HEAD(&node->u._typedef.type_declarators); + break; + case NODE_TYPEALIAS_TARGET: + CDS_INIT_LIST_HEAD(&node->u.typealias_target.type_declarators); + break; + case NODE_TYPEALIAS_ALIAS: + CDS_INIT_LIST_HEAD(&node->u.typealias_alias.type_declarators); + break; + case NODE_TYPEALIAS: + break; + + case NODE_TYPE_SPECIFIER: + break; + case NODE_DECLARATION_SPECIFIER: + CDS_INIT_LIST_HEAD(&node->u.declaration_specifier.type_specifiers); + break; + case NODE_POINTER: + break; + case NODE_TYPE_DECLARATOR: + CDS_INIT_LIST_HEAD(&node->u.type_declarator.pointers); + break; + + case NODE_FLOATING_POINT: + CDS_INIT_LIST_HEAD(&node->u.floating_point.expressions); + break; + case NODE_INTEGER: + CDS_INIT_LIST_HEAD(&node->u.integer.expressions); + break; + case NODE_STRING: + CDS_INIT_LIST_HEAD(&node->u.string.expressions); + break; + case NODE_ENUMERATOR: + break; + case NODE_ENUM: + CDS_INIT_LIST_HEAD(&node->u._enum.enumerator_list); + break; + case NODE_STRUCT_OR_VARIANT_DECLARATION: + CDS_INIT_LIST_HEAD(&node->u.struct_or_variant_declaration.type_declarators); + break; + case NODE_VARIANT: + CDS_INIT_LIST_HEAD(&node->u.variant._typedef); + CDS_INIT_LIST_HEAD(&node->u.variant.typealias); + CDS_INIT_LIST_HEAD(&node->u.variant.declaration_list); + break; + case NODE_STRUCT: + CDS_INIT_LIST_HEAD(&node->u._struct._typedef); + CDS_INIT_LIST_HEAD(&node->u._struct.typealias); + CDS_INIT_LIST_HEAD(&node->u._struct.declaration_list); + break; + + case NODE_UNKNOWN: + default: + fprintf(stderr, "[error] %s: unknown node type %d\n", __func__, + (int) type); + break; + } + + return node; +} + +static int reparent_ctf_expression(struct ctf_node *node, + struct ctf_node *parent) +{ + switch (parent->type) { + case NODE_EVENT: + cds_list_add(&node->siblings, &parent->u.event.ctf_expression); + break; + case NODE_STREAM: + cds_list_add(&node->siblings, &parent->u.stream.ctf_expression); + break; + case NODE_TRACE: + cds_list_add(&node->siblings, &parent->u.trace.ctf_expression); + break; + case NODE_FLOATING_POINT: + cds_list_add(&node->siblings, &parent->u.floating_point.expressions); + break; + case NODE_INTEGER: + cds_list_add(&node->siblings, &parent->u.integer.expressions); + break; + case NODE_STRING: + cds_list_add(&node->siblings, &parent->u.string.expressions); + break; + + case NODE_ROOT: + case NODE_CTF_EXPRESSION: + case NODE_TYPEDEF: + case NODE_TYPEALIAS_TARGET: + case NODE_TYPEALIAS_ALIAS: + case NODE_TYPEALIAS: + case NODE_TYPE_SPECIFIER: + case NODE_DECLARATION_SPECIFIER: + case NODE_POINTER: + case NODE_TYPE_DECLARATOR: + case NODE_ENUMERATOR: + case NODE_ENUM: + case NODE_STRUCT_OR_VARIANT_DECLARATION: + case NODE_VARIANT: + case NODE_STRUCT: + return -EPERM; + + case NODE_UNKNOWN: + default: + fprintf(stderr, "[error] %s: unknown node type %d\n", __func__, + (int) parent->type); + return -EINVAL; + } + return 0; +} + +static int reparent_typedef(struct ctf_node *node, struct ctf_node *parent) +{ + switch (parent->type) { + case NODE_ROOT: + cds_list_add(&node->siblings, &parent->u.root._typedef); + break; + case NODE_EVENT: + cds_list_add(&node->siblings, &parent->u.event._typedef); + break; + case NODE_STREAM: + cds_list_add(&node->siblings, &parent->u.stream._typedef); + break; + case NODE_TRACE: + cds_list_add(&node->siblings, &parent->u.trace._typedef); + break; + case NODE_VARIANT: + cds_list_add(&node->siblings, &parent->u.variant._typedef); + break; + case NODE_STRUCT: + cds_list_add(&node->siblings, &parent->u._struct._typedef); + break; + + case NODE_FLOATING_POINT: + case NODE_INTEGER: + case NODE_STRING: + case NODE_CTF_EXPRESSION: + case NODE_TYPEDEF: + case NODE_TYPEALIAS_TARGET: + case NODE_TYPEALIAS_ALIAS: + case NODE_TYPEALIAS: + case NODE_TYPE_SPECIFIER: + case NODE_DECLARATION_SPECIFIER: + case NODE_POINTER: + case NODE_TYPE_DECLARATOR: + case NODE_ENUMERATOR: + case NODE_ENUM: + case NODE_STRUCT_OR_VARIANT_DECLARATION: + return -EPERM; + + case NODE_UNKNOWN: + default: + fprintf(stderr, "[error] %s: unknown node type %d\n", __func__, + (int) parent->type); + return -EINVAL; + } + return 0; +} + +static int reparent_typealias(struct ctf_node *node, struct ctf_node *parent) +{ + switch (parent->type) { + case NODE_ROOT: + cds_list_add(&node->siblings, &parent->u.root.typealias); + break; + case NODE_EVENT: + cds_list_add(&node->siblings, &parent->u.event.typealias); + break; + case NODE_STREAM: + cds_list_add(&node->siblings, &parent->u.stream.typealias); + break; + case NODE_TRACE: + cds_list_add(&node->siblings, &parent->u.trace.typealias); + break; + case NODE_VARIANT: + cds_list_add(&node->siblings, &parent->u.variant.typealias); + break; + case NODE_STRUCT: + cds_list_add(&node->siblings, &parent->u._struct.typealias); + break; + + case NODE_FLOATING_POINT: + case NODE_INTEGER: + case NODE_STRING: + case NODE_CTF_EXPRESSION: + case NODE_TYPEDEF: + case NODE_TYPEALIAS_TARGET: + case NODE_TYPEALIAS_ALIAS: + case NODE_TYPEALIAS: + case NODE_TYPE_SPECIFIER: + case NODE_DECLARATION_SPECIFIER: + case NODE_POINTER: + case NODE_TYPE_DECLARATOR: + case NODE_ENUMERATOR: + case NODE_ENUM: + case NODE_STRUCT_OR_VARIANT_DECLARATION: + return -EPERM; + + case NODE_UNKNOWN: + default: + fprintf(stderr, "[error] %s: unknown node type %d\n", __func__, + (int) parent->type); + return -EINVAL; + } + return 0; +} + +static int reparent_declaration_specifier(struct ctf_node *node, + struct ctf_node *parent) +{ + switch (parent->type) { + case NODE_ROOT: + cds_list_add(&node->siblings, &parent->u.root.declaration_specifier); + break; + case NODE_EVENT: + cds_list_add(&node->siblings, &parent->u.event.declaration_specifier); + break; + case NODE_STREAM: + cds_list_add(&node->siblings, &parent->u.stream.declaration_specifier); + break; + case NODE_TRACE: + cds_list_add(&node->siblings, &parent->u.trace.declaration_specifier); + break; + case NODE_VARIANT: + cds_list_add(&node->siblings, &parent->u.variant.declaration_list); + break; + case NODE_STRUCT: + cds_list_add(&node->siblings, &parent->u._struct.declaration_list); + break; + case NODE_TYPEDEF: + parent->u._typedef.declaration_specifier = node; + break; + case NODE_TYPEALIAS_TARGET: + parent->u.typealias_target.declaration_specifier = node; + break; + case NODE_TYPEALIAS_ALIAS: + parent->u.typealias_alias.declaration_specifier = node; + break; + case NODE_TYPE_DECLARATOR: + parent->u.type_declarator.type = TYPEDEC_NESTED; + parent->u.type_declarator.u.nested.length.type = TYPEDEC_TYPE_TYPE; + parent->u.type_declarator.u.nested.length.u.declaration_specifier = node; + break; + case NODE_ENUM: + parent->u._enum.container_type.type = ENUM_TYPE_TYPE; + parent->u._enum.container_type.u.declaration_specifier = node; + break; + case NODE_STRUCT_OR_VARIANT_DECLARATION: + parent->u.struct_or_variant_declaration.declaration_specifier = node; + break; + case NODE_TYPEALIAS: + case NODE_FLOATING_POINT: + case NODE_INTEGER: + case NODE_STRING: + case NODE_CTF_EXPRESSION: + case NODE_TYPE_SPECIFIER: + case NODE_DECLARATION_SPECIFIER: + case NODE_POINTER: + case NODE_ENUMERATOR: + return -EPERM; + + case NODE_UNKNOWN: + default: + fprintf(stderr, "[error] %s: unknown node type %d\n", __func__, + (int) parent->type); + return -EINVAL; + } + return 0; +} + +static int reparent_type_declarator(struct ctf_node *node, + struct ctf_node *parent) +{ + switch (parent->type) { + case NODE_TYPE_DECLARATOR: + parent->u.type_declarator.type = TYPEDEC_NESTED; + parent->u.type_declarator.u.nested.type_declarator = node; + break; + case NODE_STRUCT_OR_VARIANT_DECLARATION: + cds_list_add(&node->siblings, &parent->u.struct_or_variant_declaration.type_declarators); + break; + case NODE_TYPEDEF: + cds_list_add(&node->siblings, &parent->u._typedef.type_declarators); + break; + case NODE_TYPEALIAS_TARGET: + cds_list_add(&node->siblings, &parent->u.typealias_target.type_declarators); + break; + case NODE_TYPEALIAS_ALIAS: + cds_list_add(&node->siblings, &parent->u.typealias_alias.type_declarators); + break; + + case NODE_ROOT: + case NODE_EVENT: + case NODE_STREAM: + case NODE_TRACE: + case NODE_VARIANT: + case NODE_STRUCT: + case NODE_TYPEALIAS: + case NODE_ENUM: + case NODE_FLOATING_POINT: + case NODE_INTEGER: + case NODE_STRING: + case NODE_CTF_EXPRESSION: + case NODE_TYPE_SPECIFIER: + case NODE_DECLARATION_SPECIFIER: + case NODE_POINTER: + case NODE_ENUMERATOR: + return -EPERM; + + case NODE_UNKNOWN: + default: + fprintf(stderr, "[error] %s: unknown node type %d\n", __func__, + (int) parent->type); + return -EINVAL; + } + return 0; +} + +/* + * reparent node + * + * Relink node to new parent. Returns 0 on success, -EPERM if it is not + * permitted to create the link declared by the input, -ENOENT if node or parent + * is NULL, -EINVAL if there is an internal structure problem. + */ +static int reparent_node(struct ctf_node *node, + struct ctf_node *parent) +{ + if (!node || !parent) + return -ENOENT; + + /* Unlink from old parent */ + cds_list_del(&node->siblings); + + /* Link to new parent */ + node->parent = parent; + + switch (node->type) { + case NODE_ROOT: + fprintf(stderr, "[error] %s: trying to reparent root node\n", __func__); + return -EINVAL; + + case NODE_EVENT: + if (parent->type == NODE_ROOT) + cds_list_add(&node->siblings, &parent->u.root.event); + else + return -EPERM; + break; + case NODE_STREAM: + if (parent->type == NODE_ROOT) + cds_list_add(&node->siblings, &parent->u.root.stream); + else + return -EPERM; + break; + case NODE_TRACE: + if (parent->type == NODE_ROOT) + cds_list_add(&node->siblings, &parent->u.root.trace); + else + return -EPERM; + break; + + case NODE_CTF_EXPRESSION: + return reparent_ctf_expression(node, parent); + + case NODE_TYPEDEF: + return reparent_typedef(node, parent); + case NODE_TYPEALIAS_TARGET: + if (parent->type == NODE_TYPEALIAS) + parent->u.typealias.target = node; + else + return -EINVAL; + case NODE_TYPEALIAS_ALIAS: + if (parent->type == NODE_TYPEALIAS) + parent->u.typealias.alias = node; + else + return -EINVAL; + case NODE_TYPEALIAS: + return reparent_typealias(node, parent); + + case NODE_TYPE_SPECIFIER: + if (parent->type == NODE_DECLARATION_SPECIFIER) + cds_list_add(&node->siblings, &parent->u.declaration_specifier.type_specifiers); + else + return -EPERM; + break; + case NODE_DECLARATION_SPECIFIER: + return reparent_declaration_specifier(node, parent); + case NODE_POINTER: + if (parent->type == NODE_TYPE_DECLARATOR) + cds_list_add(&node->siblings, &parent->u.type_declarator.pointers); + else + return -EPERM; + break; + case NODE_TYPE_DECLARATOR: + return reparent_type_declarator(node, parent); + + case NODE_FLOATING_POINT: + if (parent->type == NODE_TYPE_SPECIFIER) { + parent->u.type_specifier.type = TYPESPEC_FLOATING_POINT; + parent->u.type_specifier.u.floating_point = node; + } else + return -EPERM; + break; + case NODE_INTEGER: + if (parent->type == NODE_TYPE_SPECIFIER) { + parent->u.type_specifier.type = TYPESPEC_INTEGER; + parent->u.type_specifier.u.integer = node; + } else + return -EPERM; + break; + case NODE_STRING: + if (parent->type == NODE_TYPE_SPECIFIER) { + parent->u.type_specifier.type = TYPESPEC_STRING; + parent->u.type_specifier.u.string = node; + } else + return -EPERM; + break; + case NODE_ENUMERATOR: + if (parent->type == NODE_ENUM) + cds_list_add(&node->siblings, &parent->u._enum.enumerator_list); + else + return -EPERM; + break; + case NODE_ENUM: + if (parent->type == NODE_TYPE_SPECIFIER) { + parent->u.type_specifier.type = TYPESPEC_ENUM; + parent->u.type_specifier.u._enum = node; + } else + return -EPERM; + break; + case NODE_STRUCT_OR_VARIANT_DECLARATION: + switch (parent->type) { + case NODE_STRUCT: + cds_list_add(&node->siblings, &parent->u.variant.declaration_list); + break; + case NODE_VARIANT: + cds_list_add(&node->siblings, &parent->u._struct.declaration_list); + break; + default: + return -EINVAL; + } + break; + case NODE_VARIANT: + if (parent->type == NODE_TYPE_SPECIFIER) { + parent->u.type_specifier.type = TYPESPEC_VARIANT; + parent->u.type_specifier.u.variant = node; + } else + return -EPERM; + break; + case NODE_STRUCT: + if (parent->type == NODE_TYPE_SPECIFIER) { + parent->u.type_specifier.type = TYPESPEC_STRUCT; + parent->u.type_specifier.u._struct = node; + } else + return -EPERM; + break; + + case NODE_UNKNOWN: + default: + fprintf(stderr, "[error] %s: unknown node type %d\n", __func__, + (int) parent->type); + return -EINVAL; + } + return 0; } -void yyerror(const char *str) +void yyerror(struct ctf_scanner *scanner, const char *str) { fprintf(stderr, "error %s\n", str); } @@ -142,28 +655,101 @@ int yywrap(void) return 1; } -static void free_strings(void) +static void free_strings(struct cds_list_head *list) { struct gc_string *gstr, *tmp; - cds_list_for_each_entry_safe(gstr, tmp, &allocated_strings, gc) + cds_list_for_each_entry_safe(gstr, tmp, list, gc) free(gstr); } -int main(int argc, char **argv) +static struct ctf_ast *ctf_ast_alloc(void) { - yydebug = 1; - init_scope(&root_scope, NULL); - yyparse(); - finalize_scope(&root_scope); - free_strings(); - return 0; -} + struct ctf_ast *ast; + + ast = malloc(sizeof(*ast)); + if (!ast) + return NULL; + memset(ast, 0, sizeof(*ast)); + CDS_INIT_LIST_HEAD(&ast->allocated_nodes); + ast->root.type = NODE_ROOT; + CDS_INIT_LIST_HEAD(&ast->root.siblings); + CDS_INIT_LIST_HEAD(&ast->root.u.root._typedef); + CDS_INIT_LIST_HEAD(&ast->root.u.root.typealias); + CDS_INIT_LIST_HEAD(&ast->root.u.root.declaration_specifier); + CDS_INIT_LIST_HEAD(&ast->root.u.root.trace); + CDS_INIT_LIST_HEAD(&ast->root.u.root.stream); + CDS_INIT_LIST_HEAD(&ast->root.u.root.event); + return ast; +} + +static void ctf_ast_free(struct ctf_ast *ast) +{ + struct ctf_node *node, *tmp; + + cds_list_for_each_entry_safe(node, tmp, &ast->allocated_nodes, gc) + free(node); +} + +int ctf_scanner_append_ast(struct ctf_scanner *scanner) +{ + return yyparse(scanner); +} + +struct ctf_scanner *ctf_scanner_alloc(FILE *input) +{ + struct ctf_scanner *scanner; + int ret; + + scanner = malloc(sizeof(*scanner)); + if (!scanner) + return NULL; + memset(scanner, 0, sizeof(*scanner)); + + ret = yylex_init_extra(scanner, &scanner->scanner); + if (ret) { + fprintf(stderr, "yylex_init error\n"); + goto cleanup_scanner; + } + yyset_in(input, scanner); + + scanner->ast = ctf_ast_alloc(); + if (!scanner->ast) + goto cleanup_lexer; + init_scope(&scanner->root_scope, NULL); + CDS_INIT_LIST_HEAD(&scanner->allocated_strings); + + return scanner; + +cleanup_lexer: + ret = yylex_destroy(scanner->scanner); + if (!ret) + fprintf(stderr, "yylex_destroy error\n"); +cleanup_scanner: + free(scanner); + return NULL; +} + +void ctf_scanner_free(struct ctf_scanner *scanner) +{ + int ret; + + finalize_scope(&scanner->root_scope); + free_strings(&scanner->allocated_strings); + ctf_ast_free(scanner->ast); + ret = yylex_destroy(scanner->scanner); + if (ret) + fprintf(stderr, "yylex_destroy error\n"); + free(scanner); +} %} +%define api.pure + /* %locations */ +%parse-param {struct ctf_scanner *scanner} +%lex-param {struct ctf_scanner *scanner} %start file -/* %glr-parser */ %token CHARACTER_CONSTANT_START SQUOTE STRING_LITERAL_START DQUOTE ESCSEQ CHAR_STRING_TOKEN LSBRAC RSBRAC LPAREN RPAREN LBRAC RBRAC RARROW STAR PLUS MINUS LT GT TYPEASSIGN COLON SEMICOLON DOTDOTDOT DOT EQUAL COMMA CONST CHAR DOUBLE ENUM EVENT FLOATING_POINT FLOAT INTEGER INT LONG SHORT SIGNED STREAM STRING STRUCT TRACE TYPEALIAS TYPEDEF UNSIGNED VARIANT VOID _BOOL _COMPLEX _IMAGINARY DECIMAL_CONSTANT OCTAL_CONSTANT HEXADECIMAL_CONSTANT %token IDENTIFIER ID_TYPE %token ERROR @@ -175,12 +761,10 @@ int main(int argc, char **argv) struct ctf_node *n; } -/* %token UPPERCASE_L LOWERCASE_L _U _NONDIGIT */ -/*%type decl type_decl event_decl stream_decl trace_decl type_def -%type event_attrib field_attrib assign_attrib -%type event_attrib_list attrib_list field_list appendval_list -%type field value type_expr typename typename_postfix -%type typename_prefix identifier */ +%type event_declaration +%type ctf_assignment_expression_list +%type ctf_assignment_expression + %% file: @@ -285,20 +869,20 @@ declaration: event_declaration: event_declaration_begin event_declaration_end | event_declaration_begin ctf_assignment_expression_list event_declaration_end + { + $$ = make_node(scanner, NODE_EVENT); + /* TODO */ + } ; event_declaration_begin: EVENT LBRAC - { - push_scope(); - } + { push_scope(scanner); } ; event_declaration_end: RBRAC SEMICOLON - { - pop_scope(); - } + { pop_scope(scanner); } ; @@ -309,16 +893,12 @@ stream_declaration: stream_declaration_begin: STREAM LBRAC - { - push_scope(); - } + { push_scope(scanner); } ; stream_declaration_end: RBRAC SEMICOLON - { - pop_scope(); - } + { pop_scope(scanner); } ; @@ -329,16 +909,12 @@ trace_declaration: trace_declaration_begin: TRACE LBRAC - { - push_scope(); - } + { push_scope(scanner); } ; trace_declaration_end: RBRAC SEMICOLON - { - pop_scope(); - } + { pop_scope(scanner); } ; declaration_specifiers: @@ -392,16 +968,12 @@ struct_type_specifier: struct_declaration_begin: LBRAC - { - push_scope(); - } + { push_scope(scanner); } ; struct_declaration_end: RBRAC - { - pop_scope(); - } + { pop_scope(scanner); } ; variant_type_specifier: @@ -422,16 +994,12 @@ variant_type_specifier: variant_declaration_begin: LBRAC - { - push_scope(); - } + { push_scope(scanner); } ; variant_declaration_end: RBRAC - { - pop_scope(); - } + { pop_scope(scanner); } ; type_specifier_or_integer_constant: @@ -546,9 +1114,7 @@ type_declarator: direct_type_declarator: IDENTIFIER - { - add_type($1->s); - } + { add_type(scanner, $1->s); } | LPAREN type_declarator RPAREN | direct_type_declarator LSBRAC type_specifier_or_integer_constant RSBRAC ; @@ -561,9 +1127,7 @@ abstract_type_declarator: direct_abstract_type_declarator: /* empty */ | IDENTIFIER - { - add_type($1->s); - } + { add_type(scanner, $1->s); } | LPAREN abstract_type_declarator RPAREN | direct_abstract_type_declarator LSBRAC type_specifier_or_integer_constant RSBRAC | direct_abstract_type_declarator LSBRAC RSBRAC @@ -589,6 +1153,11 @@ ctf_assignment_expression_list: ctf_assignment_expression: unary_expression EQUAL unary_expression + { + $$ = make_node(scanner, NODE_CTF_EXPRESSION); + /* TODO */ + + } | unary_expression TYPEASSIGN type_specifier | declaration_specifiers TYPEDEF declaration_specifiers type_declarator_list | TYPEDEF declaration_specifiers type_declarator_list