X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=formats%2Fctf%2Fmetadata%2Fctf-parser.y;h=61ec47dd28fe80fcfc0674674233a819a2d272d3;hb=697b10505ff455ec93d57868d1b15bcda4d9dd37;hp=3ae0bc237120009363d6eedfe2d815dd3b879dcf;hpb=fa45f52394a80b99ce747d1aed78653cb0a11e36;p=babeltrace.git diff --git a/formats/ctf/metadata/ctf-parser.y b/formats/ctf/metadata/ctf-parser.y index 3ae0bc23..61ec47dd 100644 --- a/formats/ctf/metadata/ctf-parser.y +++ b/formats/ctf/metadata/ctf-parser.y @@ -15,9 +15,18 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. */ #include +#include #include #include #include @@ -31,7 +40,7 @@ #include "ctf-parser.h" #include "ctf-ast.h" -__attribute__((visibility("protected"))) +BT_HIDDEN int yydebug; /* Join two lists, put "add" at the end of "head". */ @@ -47,16 +56,20 @@ _bt_list_splice_tail (struct bt_list_head *add, struct bt_list_head *head) } } -__attribute__((visibility("protected"))) +BT_HIDDEN int yyparse(struct ctf_scanner *scanner); -__attribute__((visibility("protected"))) +BT_HIDDEN int yylex(union YYSTYPE *yyval, struct ctf_scanner *scanner); -__attribute__((visibility("protected"))) +BT_HIDDEN int yylex_init_extra(struct ctf_scanner *scanner, yyscan_t * ptr_yy_globals); -__attribute__((visibility("protected"))) +BT_HIDDEN int yylex_destroy(yyscan_t yyscanner); -__attribute__((visibility("protected"))) +BT_HIDDEN void yyrestart(FILE * in_str, yyscan_t scanner); +BT_HIDDEN +int yyget_lineno(yyscan_t yyscanner); +BT_HIDDEN +char *yyget_text(yyscan_t yyscanner); struct gc_string { struct bt_list_head gc; @@ -65,34 +78,21 @@ struct gc_string { }; static const char *node_type_to_str[] = { - [ NODE_UNKNOWN ] = "NODE_UNKNOWN", - [ NODE_ROOT ] = "NODE_ROOT", - [ NODE_EVENT ] = "NODE_EVENT", - [ NODE_ENV ] = "NODE_ENV", - [ NODE_STREAM ] = "NODE_STREAM", - [ NODE_TRACE ] = "NODE_TRACE", - [ NODE_CLOCK ] = "NODE_CLOCK", - [ NODE_CTF_EXPRESSION ] = "NODE_CTF_EXPRESSION", - [ NODE_UNARY_EXPRESSION ] = "NODE_UNARY_EXPRESSION", - [ NODE_TYPEDEF ] = "NODE_TYPEDEF", - [ NODE_TYPEALIAS_TARGET ] = "NODE_TYPEALIAS_TARGET", - [ NODE_TYPEALIAS_ALIAS ] = "NODE_TYPEALIAS_ALIAS", - [ NODE_TYPEALIAS ] = "NODE_TYPEALIAS", - [ NODE_TYPE_SPECIFIER ] = "NODE_TYPE_SPECIFIER", - [ NODE_TYPE_SPECIFIER_LIST ] = "NODE_TYPE_SPECIFIER_LIST", - [ NODE_POINTER ] = "NODE_POINTER", - [ NODE_TYPE_DECLARATOR ] = "NODE_TYPE_DECLARATOR", - [ NODE_FLOATING_POINT ] = "NODE_FLOATING_POINT", - [ NODE_INTEGER ] = "NODE_INTEGER", - [ NODE_STRING ] = "NODE_STRING", - [ NODE_ENUMERATOR ] = "NODE_ENUMERATOR", - [ NODE_ENUM ] = "NODE_ENUM", - [ NODE_STRUCT_OR_VARIANT_DECLARATION ] = "NODE_STRUCT_OR_VARIANT_DECLARATION", - [ NODE_VARIANT ] = "NODE_VARIANT", - [ NODE_STRUCT ] = "NODE_STRUCT", +#define ENTRY(S) [S] = #S, + FOREACH_CTF_NODES(ENTRY) +#undef ENTRY +}; + +/* + * Static node for out of memory errors. Only "type" is used. lineno is + * always left at 0. The rest of the node content can be overwritten, + * but is never used. + */ +static struct ctf_node error_node = { + .type = NODE_ERROR, }; -__attribute__((visibility("protected"))) +BT_HIDDEN const char *node_type(struct ctf_node *node) { if (node->type < NR_NODE_TYPES) @@ -118,45 +118,200 @@ static struct gc_string *gc_string_alloc(struct ctf_scanner *scanner, return gstr; } -/* - * note: never use gc_string_append on a string that has external references. - * gsrc will be garbage collected immediately, and gstr might be. - * Should only be used to append characters to a string literal or constant. - */ -__attribute__((visibility("protected"))) -struct gc_string *gc_string_append(struct ctf_scanner *scanner, - struct gc_string *gstr, - struct gc_string *gsrc) +void setstring(struct ctf_scanner *scanner, YYSTYPE *lvalp, const char *src) { - size_t newlen = strlen(gsrc->s) + strlen(gstr->s) + 1; - size_t alloclen; + lvalp->gs = gc_string_alloc(scanner, strlen(src) + 1); + strcpy(lvalp->gs->s, src); +} - /* TODO: could be faster with find first bit or glib Gstring */ - /* sizeof long to account for malloc header (int or long ?) */ - for (alloclen = 8; alloclen < sizeof(long) + sizeof(*gstr) + newlen; - alloclen *= 2); +static +int str_check(size_t str_len, size_t offset, size_t len) +{ + /* check overflow */ + if (offset + len < offset) + return -1; + if (offset + len > str_len) + return -1; + return 0; +} - if (alloclen > gstr->alloclen) { - struct gc_string *newgstr; +static +int bt_isodigit(int c) +{ + switch (c) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + return 1; + default: + return 0; + } +} - newgstr = gc_string_alloc(scanner, newlen); - strcpy(newgstr->s, gstr->s); - strcat(newgstr->s, gsrc->s); - bt_list_del(&gstr->gc); - free(gstr); - gstr = newgstr; - } else { - strcat(gstr->s, gsrc->s); +static +int parse_base_sequence(const char *src, size_t len, size_t pos, + char *buffer, size_t *buf_len, int base) +{ + const size_t max_char = 3; + int nr_char = 0; + + while (!str_check(len, pos, 1) && nr_char < max_char) { + char c = src[pos++]; + + if (base == 8) { + if (bt_isodigit(c)) + buffer[nr_char++] = c; + else + break; + } else if (base == 16) { + if (isxdigit(c)) + buffer[nr_char++] = c; + else + break; + + } else { + /* Unsupported base */ + return -1; + } } - bt_list_del(&gsrc->gc); - free(gsrc); - return gstr; + assert(nr_char > 0); + buffer[nr_char] = '\0'; + *buf_len = nr_char; + return 0; } -void setstring(struct ctf_scanner *scanner, YYSTYPE *lvalp, const char *src) +static +int import_basic_string(struct ctf_scanner *scanner, YYSTYPE *lvalp, + size_t len, const char *src, char delim) { - lvalp->gs = gc_string_alloc(scanner, strlen(src) + 1); - strcpy(lvalp->gs->s, src); + size_t pos = 0, dpos = 0; + + if (str_check(len, pos, 1)) + return -1; + if (src[pos++] != delim) + return -1; + + while (src[pos] != delim) { + char c; + + if (str_check(len, pos, 1)) + return -1; + c = src[pos++]; + if (c == '\\') { + if (str_check(len, pos, 1)) + return -1; + c = src[pos++]; + + switch (c) { + case 'a': + c = '\a'; + break; + case 'b': + c = '\b'; + break; + case 'f': + c = '\f'; + break; + case 'n': + c = '\n'; + break; + case 'r': + c = '\r'; + break; + case 't': + c = '\t'; + break; + case 'v': + c = '\v'; + break; + case '\\': + c = '\\'; + break; + case '\'': + c = '\''; + break; + case '\"': + c = '\"'; + break; + case '?': + c = '?'; + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + { + char oct_buffer[4]; + size_t oct_len; + + if (parse_base_sequence(src, len, pos - 1, + oct_buffer, &oct_len, 8)) + return -1; + c = strtoul(&oct_buffer[0], NULL, 8); + pos += oct_len - 1; + break; + } + case 'x': + { + char hex_buffer[4]; + size_t hex_len; + + if (parse_base_sequence(src, len, pos, + hex_buffer, &hex_len, 16)) + return -1; + c = strtoul(&hex_buffer[0], NULL, 16); + pos += hex_len; + break; + } + default: + return -1; + } + } + if (str_check(len, dpos, 1)) + return -1; + lvalp->gs->s[dpos++] = c; + } + + if (str_check(len, dpos, 1)) + return -1; + lvalp->gs->s[dpos++] = '\0'; + + if (str_check(len, pos, 1)) + return -1; + if (src[pos++] != delim) + return -1; + + if (str_check(len, pos, 1)) + return -1; + if (src[pos] != '\0') + return -1; + return 0; +} + +int import_string(struct ctf_scanner *scanner, YYSTYPE *lvalp, + const char *src, char delim) +{ + size_t len; + + len = strlen(src) + 1; + lvalp->gs = gc_string_alloc(scanner, len); + if (src[0] == 'L') { + // TODO: import wide string + printfl_error(yyget_lineno(scanner), + "Wide string not supported yet."); + return -1; + } else { + return import_basic_string(scanner, lvalp, len, src, delim); + } } static void init_scope(struct ctf_scanner_scope *scope, @@ -202,7 +357,7 @@ static int lookup_type(struct ctf_scanner_scope *s, const char *id) return ret; } -__attribute__((visibility("protected"))) +BT_HIDDEN int is_type(struct ctf_scanner *scanner, const char *id) { struct ctf_scanner_scope *it; @@ -233,17 +388,21 @@ static struct ctf_node *make_node(struct ctf_scanner *scanner, struct ctf_node *node; node = malloc(sizeof(*node)); - if (!node) - return NULL; + if (!node) { + printfl_fatal(yyget_lineno(scanner->scanner), "out of memory"); + return &error_node; + } memset(node, 0, sizeof(*node)); node->type = type; + node->lineno = yyget_lineno(scanner->scanner); BT_INIT_LIST_HEAD(&node->tmp_head); bt_list_add(&node->gc, &ast->allocated_nodes); bt_list_add(&node->siblings, &node->tmp_head); switch (type) { case NODE_ROOT: - fprintf(stderr, "[error] %s: trying to create root node\n", __func__); + node->type = NODE_ERROR; + printfn_fatal(node, "trying to create root node"); break; case NODE_EVENT: @@ -261,6 +420,9 @@ static struct ctf_node *make_node(struct ctf_scanner *scanner, case NODE_CLOCK: BT_INIT_LIST_HEAD(&node->u.clock.declaration_list); break; + case NODE_CALLSITE: + BT_INIT_LIST_HEAD(&node->u.callsite.declaration_list); + break; case NODE_CTF_EXPRESSION: BT_INIT_LIST_HEAD(&node->u.ctf_expression.left); @@ -320,8 +482,8 @@ static struct ctf_node *make_node(struct ctf_scanner *scanner, case NODE_UNKNOWN: default: - fprintf(stderr, "[error] %s: unknown node type %d\n", __func__, - (int) type); + node->type = NODE_ERROR; + printfn_fatal(node, "unknown node type '%d'", (int) type); break; } @@ -347,6 +509,9 @@ static int reparent_ctf_expression(struct ctf_node *node, case NODE_CLOCK: _bt_list_splice_tail(&node->tmp_head, &parent->u.clock.declaration_list); break; + case NODE_CALLSITE: + _bt_list_splice_tail(&node->tmp_head, &parent->u.callsite.declaration_list); + break; case NODE_FLOATING_POINT: _bt_list_splice_tail(&node->tmp_head, &parent->u.floating_point.expressions); break; @@ -377,8 +542,7 @@ static int reparent_ctf_expression(struct ctf_node *node, case NODE_UNKNOWN: default: - fprintf(stderr, "[error] %s: unknown node type %d\n", __func__, - (int) parent->type); + printfn_fatal(node, "unknown node type '%d'", (int) parent->type); return -EINVAL; } return 0; @@ -405,6 +569,9 @@ static int reparent_typedef(struct ctf_node *node, struct ctf_node *parent) case NODE_CLOCK: _bt_list_splice_tail(&node->tmp_head, &parent->u.clock.declaration_list); break; + case NODE_CALLSITE: + _bt_list_splice_tail(&node->tmp_head, &parent->u.callsite.declaration_list); + break; case NODE_VARIANT: _bt_list_splice_tail(&node->tmp_head, &parent->u.variant.declaration_list); break; @@ -432,8 +599,7 @@ static int reparent_typedef(struct ctf_node *node, struct ctf_node *parent) case NODE_UNKNOWN: default: - fprintf(stderr, "[error] %s: unknown node type %d\n", __func__, - (int) parent->type); + printfn_fatal(node, "unknown node type %d", parent->type); return -EINVAL; } return 0; @@ -460,6 +626,9 @@ static int reparent_typealias(struct ctf_node *node, struct ctf_node *parent) case NODE_CLOCK: _bt_list_splice_tail(&node->tmp_head, &parent->u.clock.declaration_list); break; + case NODE_CALLSITE: + _bt_list_splice_tail(&node->tmp_head, &parent->u.callsite.declaration_list); + break; case NODE_VARIANT: _bt_list_splice_tail(&node->tmp_head, &parent->u.variant.declaration_list); break; @@ -487,8 +656,7 @@ static int reparent_typealias(struct ctf_node *node, struct ctf_node *parent) case NODE_UNKNOWN: default: - fprintf(stderr, "[error] %s: unknown node type %d\n", __func__, - (int) parent->type); + printfn_fatal(node, "unknown node type '%d'", (int) parent->type); return -EINVAL; } return 0; @@ -508,6 +676,7 @@ static int reparent_type_specifier(struct ctf_node *node, case NODE_ENV: case NODE_TRACE: case NODE_CLOCK: + case NODE_CALLSITE: case NODE_VARIANT: case NODE_STRUCT: case NODE_TYPEDEF: @@ -528,8 +697,7 @@ static int reparent_type_specifier(struct ctf_node *node, case NODE_UNKNOWN: default: - fprintf(stderr, "[error] %s: unknown node type %d\n", __func__, - (int) parent->type); + printfn_fatal(node, "unknown node type '%d'", (int) parent->type); return -EINVAL; } return 0; @@ -557,6 +725,9 @@ static int reparent_type_specifier_list(struct ctf_node *node, case NODE_CLOCK: bt_list_add_tail(&node->siblings, &parent->u.clock.declaration_list); break; + case NODE_CALLSITE: + bt_list_add_tail(&node->siblings, &parent->u.callsite.declaration_list); + break; case NODE_VARIANT: bt_list_add_tail(&node->siblings, &parent->u.variant.declaration_list); break; @@ -592,8 +763,7 @@ static int reparent_type_specifier_list(struct ctf_node *node, case NODE_UNKNOWN: default: - fprintf(stderr, "[error] %s: unknown node type %d\n", __func__, - (int) parent->type); + printfn_fatal(node, "unknown node type '%d'", (int) parent->type); return -EINVAL; } return 0; @@ -626,6 +796,7 @@ static int reparent_type_declarator(struct ctf_node *node, case NODE_ENV: case NODE_TRACE: case NODE_CLOCK: + case NODE_CALLSITE: case NODE_VARIANT: case NODE_STRUCT: case NODE_TYPEALIAS: @@ -643,8 +814,7 @@ static int reparent_type_declarator(struct ctf_node *node, case NODE_UNKNOWN: default: - fprintf(stderr, "[error] %s: unknown node type %d\n", __func__, - (int) parent->type); + printfn_fatal(node, "unknown node type '%d'", (int) parent->type); return -EINVAL; } return 0; @@ -667,7 +837,7 @@ static int set_parent_node(struct ctf_node *node, switch (node->type) { case NODE_ROOT: - fprintf(stderr, "[error] %s: trying to reparent root node\n", __func__); + printfn_fatal(node, "trying to reparent root node"); return -EINVAL; case NODE_EVENT: @@ -705,6 +875,13 @@ static int set_parent_node(struct ctf_node *node, return -EPERM; } break; + case NODE_CALLSITE: + if (parent->type == NODE_ROOT) { + _bt_list_splice_tail(&node->tmp_head, &parent->u.root.callsite); + } else { + return -EPERM; + } + break; case NODE_CTF_EXPRESSION: return reparent_ctf_expression(node, parent); @@ -775,20 +952,21 @@ static int set_parent_node(struct ctf_node *node, case NODE_UNKNOWN: default: - fprintf(stderr, "[error] %s: unknown node type %d\n", __func__, - (int) parent->type); + printfn_fatal(node, "unknown node type '%d'", (int) parent->type); return -EINVAL; } return 0; } -__attribute__((visibility("protected"))) +BT_HIDDEN void yyerror(struct ctf_scanner *scanner, const char *str) { - fprintf(stderr, "error %s\n", str); + printfl_error(yyget_lineno(scanner->scanner), + "token \"%s\": %s\n", + yyget_text(scanner->scanner), str); } -__attribute__((visibility("protected"))) +BT_HIDDEN int yywrap(void) { return 1; @@ -796,7 +974,7 @@ int yywrap(void) #define reparent_error(scanner, str) \ do { \ - yyerror(scanner, YY_("reparent_error: " str "\n")); \ + yyerror(scanner, YY_("reparent_error: " str)); \ YYERROR; \ } while (0) @@ -825,6 +1003,7 @@ static struct ctf_ast *ctf_ast_alloc(void) BT_INIT_LIST_HEAD(&ast->root.u.root.stream); BT_INIT_LIST_HEAD(&ast->root.u.root.event); BT_INIT_LIST_HEAD(&ast->root.u.root.clock); + BT_INIT_LIST_HEAD(&ast->root.u.root.callsite); return ast; } @@ -834,6 +1013,7 @@ static void ctf_ast_free(struct ctf_ast *ast) bt_list_for_each_entry_safe(node, tmp, &ast->allocated_nodes, gc) free(node); + free(ast); } int ctf_scanner_append_ast(struct ctf_scanner *scanner) @@ -855,7 +1035,7 @@ struct ctf_scanner *ctf_scanner_alloc(FILE *input) ret = yylex_init_extra(scanner, &scanner->scanner); if (ret) { - fprintf(stderr, "yylex_init error\n"); + printf_fatal("yylex_init error"); goto cleanup_scanner; } /* Start processing new stream */ @@ -878,7 +1058,7 @@ struct ctf_scanner *ctf_scanner_alloc(FILE *input) cleanup_lexer: ret = yylex_destroy(scanner->scanner); if (!ret) - fprintf(stderr, "yylex_destroy error\n"); + printf_fatal("yylex_destroy error"); cleanup_scanner: free(scanner); return NULL; @@ -893,7 +1073,7 @@ void ctf_scanner_free(struct ctf_scanner *scanner) ctf_ast_free(scanner->ast); ret = yylex_destroy(scanner->scanner); if (ret) - fprintf(stderr, "yylex_destroy error\n"); + printf_error("yylex_destroy error"); free(scanner); } @@ -901,6 +1081,7 @@ void ctf_scanner_free(struct ctf_scanner *scanner) %define api.pure /* %locations */ +%error-verbose %parse-param {struct ctf_scanner *scanner} %lex-param {struct ctf_scanner *scanner} /* @@ -913,20 +1094,23 @@ void ctf_scanner_free(struct ctf_scanner *scanner) */ %expect 2 %start file -%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 ENV EVENT FLOATING_POINT FLOAT INTEGER INT LONG SHORT SIGNED STREAM STRING STRUCT TRACE CLOCK TYPEALIAS TYPEDEF UNSIGNED VARIANT VOID _BOOL _COMPLEX _IMAGINARY DECIMAL_CONSTANT OCTAL_CONSTANT HEXADECIMAL_CONSTANT TOK_ALIGN +%token INTEGER_LITERAL STRING_LITERAL CHARACTER_LITERAL LSBRAC RSBRAC LPAREN RPAREN LBRAC RBRAC RARROW STAR PLUS MINUS LT GT TYPEASSIGN COLON SEMICOLON DOTDOTDOT DOT EQUAL COMMA CONST CHAR DOUBLE ENUM ENV EVENT FLOATING_POINT FLOAT INTEGER INT LONG SHORT SIGNED STREAM STRING STRUCT TRACE CALLSITE CLOCK TYPEALIAS TYPEDEF UNSIGNED VARIANT VOID _BOOL _COMPLEX _IMAGINARY TOK_ALIGN %token IDENTIFIER ID_TYPE %token ERROR %union { long long ll; + unsigned long long ull; char c; struct gc_string *gs; struct ctf_node *n; } +%type STRING_LITERAL CHARACTER_LITERAL + %type keywords -%type s_char s_char_sequence c_char c_char_sequence +%type INTEGER_LITERAL %type postfix_expression unary_expression unary_expression_or_range %type declaration @@ -935,6 +1119,7 @@ void ctf_scanner_free(struct ctf_scanner *scanner) %type env_declaration %type trace_declaration %type clock_declaration +%type callsite_declaration %type integer_declaration_specifiers %type declaration_specifiers %type alias_declaration_specifiers @@ -1031,45 +1216,12 @@ keywords: { $$ = yylval.gs; } | CLOCK { $$ = yylval.gs; } + | CALLSITE + { $$ = yylval.gs; } | TOK_ALIGN { $$ = yylval.gs; } ; -/* 1.5 Constants */ - -c_char_sequence: - c_char - { $$ = $1; } - | c_char_sequence c_char - { $$ = gc_string_append(scanner, $1, $2); } - ; - -c_char: - CHAR_STRING_TOKEN - { $$ = yylval.gs; } - | ESCSEQ - { - reparent_error(scanner, "escape sequences not supported yet"); - } - ; - -/* 1.6 String literals */ - -s_char_sequence: - s_char - { $$ = $1; } - | s_char_sequence s_char - { $$ = gc_string_append(scanner, $1, $2); } - ; - -s_char: - CHAR_STRING_TOKEN - { $$ = yylval.gs; } - | ESCSEQ - { - reparent_error(scanner, "escape sequences not supported yet"); - } - ; /* 2: Phrase structure grammar */ @@ -1092,50 +1244,27 @@ postfix_expression: $$->u.unary_expression.type = UNARY_STRING; $$->u.unary_expression.u.string = yylval.gs->s; } - | DECIMAL_CONSTANT - { - $$ = make_node(scanner, NODE_UNARY_EXPRESSION); - $$->u.unary_expression.type = UNARY_UNSIGNED_CONSTANT; - sscanf(yylval.gs->s, "%" PRIu64, - &$$->u.unary_expression.u.unsigned_constant); - } - | OCTAL_CONSTANT + | INTEGER_LITERAL { $$ = make_node(scanner, NODE_UNARY_EXPRESSION); $$->u.unary_expression.type = UNARY_UNSIGNED_CONSTANT; - sscanf(yylval.gs->s, "0%" PRIo64, - &$$->u.unary_expression.u.unsigned_constant); + $$->u.unary_expression.u.unsigned_constant = $1; } - | HEXADECIMAL_CONSTANT - { - $$ = make_node(scanner, NODE_UNARY_EXPRESSION); - $$->u.unary_expression.type = UNARY_UNSIGNED_CONSTANT; - sscanf(yylval.gs->s, "0x%" PRIx64, - &$$->u.unary_expression.u.unsigned_constant); - } - | STRING_LITERAL_START DQUOTE - { - $$ = make_node(scanner, NODE_UNARY_EXPRESSION); - $$->u.unary_expression.type = UNARY_STRING; - $$->u.unary_expression.u.string = ""; - } - | STRING_LITERAL_START s_char_sequence DQUOTE + | STRING_LITERAL { $$ = make_node(scanner, NODE_UNARY_EXPRESSION); $$->u.unary_expression.type = UNARY_STRING; - $$->u.unary_expression.u.string = $2->s; + $$->u.unary_expression.u.string = $1->s; } - | CHARACTER_CONSTANT_START c_char_sequence SQUOTE + | CHARACTER_LITERAL { $$ = make_node(scanner, NODE_UNARY_EXPRESSION); $$->u.unary_expression.type = UNARY_STRING; - $$->u.unary_expression.u.string = $2->s; + $$->u.unary_expression.u.string = $1->s; } | LPAREN unary_expression RPAREN { - $$ = make_node(scanner, NODE_UNARY_EXPRESSION); - $$->u.unary_expression.type = UNARY_NESTED; - $$->u.unary_expression.u.nested_exp = $2; + $$ = $2; } | postfix_expression LSBRAC unary_expression RSBRAC { @@ -1187,21 +1316,25 @@ unary_expression: postfix_expression { $$ = $1; } | PLUS postfix_expression - { $$ = $2; } - | MINUS postfix_expression { $$ = $2; - if ($$->u.unary_expression.type != UNARY_SIGNED_CONSTANT - && $$->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT) + if ($$->u.unary_expression.type != UNARY_UNSIGNED_CONSTANT + && $$->u.unary_expression.type != UNARY_SIGNED_CONSTANT) { reparent_error(scanner, "expecting numeric constant"); - + } + } + | MINUS postfix_expression + { + $$ = $2; if ($$->u.unary_expression.type == UNARY_UNSIGNED_CONSTANT) { $$->u.unary_expression.type = UNARY_SIGNED_CONSTANT; $$->u.unary_expression.u.signed_constant = -($$->u.unary_expression.u.unsigned_constant); - } else { + } else if ($$->u.unary_expression.type == UNARY_UNSIGNED_CONSTANT) { $$->u.unary_expression.u.signed_constant = -($$->u.unary_expression.u.signed_constant); + } else { + reparent_error(scanner, "expecting numeric constant"); } } ; @@ -1232,6 +1365,8 @@ declaration: { $$ = $1; } | clock_declaration { $$ = $1; } + | callsite_declaration + { $$ = $1; } | declaration_specifiers TYPEDEF declaration_specifiers type_declarator_list SEMICOLON { struct ctf_node *list; @@ -1399,6 +1534,29 @@ clock_declaration_end: { pop_scope(scanner); } ; +callsite_declaration: + CALLSITE callsite_declaration_begin callsite_declaration_end + { + $$ = make_node(scanner, NODE_CALLSITE); + } + | CALLSITE callsite_declaration_begin ctf_assignment_expression_list callsite_declaration_end + { + $$ = make_node(scanner, NODE_CALLSITE); + if (set_parent_node($3, $$)) + reparent_error(scanner, "trace_declaration"); + } + ; + +callsite_declaration_begin: + LBRAC + { push_scope(scanner); } + ; + +callsite_declaration_end: + RBRAC SEMICOLON + { pop_scope(scanner); } + ; + integer_declaration_specifiers: CONST { @@ -2143,15 +2301,10 @@ enumerator: $$ = make_node(scanner, NODE_ENUMERATOR); $$->u.enumerator.id = $1->s; } - | STRING_LITERAL_START DQUOTE + | STRING_LITERAL { $$ = make_node(scanner, NODE_ENUMERATOR); - $$->u.enumerator.id = ""; - } - | STRING_LITERAL_START s_char_sequence DQUOTE - { - $$ = make_node(scanner, NODE_ENUMERATOR); - $$->u.enumerator.id = $2->s; + $$->u.enumerator.id = $1->s; } | IDENTIFIER EQUAL unary_expression_or_range { @@ -2171,17 +2324,11 @@ enumerator: $$->u.enumerator.id = $1->s; bt_list_splice(&($3)->tmp_head, &($$)->u.enumerator.values); } - | STRING_LITERAL_START DQUOTE EQUAL unary_expression_or_range + | STRING_LITERAL EQUAL unary_expression_or_range { $$ = make_node(scanner, NODE_ENUMERATOR); - $$->u.enumerator.id = ""; - bt_list_splice(&($4)->tmp_head, &($$)->u.enumerator.values); - } - | STRING_LITERAL_START s_char_sequence DQUOTE EQUAL unary_expression_or_range - { - $$ = make_node(scanner, NODE_ENUMERATOR); - $$->u.enumerator.id = $2->s; - bt_list_splice(&($5)->tmp_head, &($$)->u.enumerator.values); + $$->u.enumerator.id = $1->s; + bt_list_splice(&($3)->tmp_head, &($$)->u.enumerator.values); } ;