From 80b07bd71464ffbf5f681b7519af520cb0d44d3a Mon Sep 17 00:00:00 2001 From: Etienne Bergeron Date: Thu, 4 Apr 2013 12:38:57 -0400 Subject: [PATCH] Handle integers in lexer rather than grammar Signed-off-by: Etienne Bergeron Signed-off-by: Mathieu Desnoyers --- formats/ctf/metadata/ctf-lexer.l | 20 ++++++++++--- formats/ctf/metadata/ctf-parser.y | 23 ++++----------- tests/ctf-traces/fail/integer-range/metadata | 27 +++++++++++++++++ tests/ctf-traces/succeed/succeed4/metadata | 31 ++++++++++++++++++++ 4 files changed, 79 insertions(+), 22 deletions(-) create mode 100644 tests/ctf-traces/fail/integer-range/metadata create mode 100644 tests/ctf-traces/succeed/succeed4/metadata diff --git a/formats/ctf/metadata/ctf-lexer.l b/formats/ctf/metadata/ctf-lexer.l index a282bf7a..12f9e99c 100644 --- a/formats/ctf/metadata/ctf-lexer.l +++ b/formats/ctf/metadata/ctf-lexer.l @@ -26,11 +26,22 @@ */ #include +#include #include #include "ctf-scanner.h" #include "ctf-parser.h" #include "ctf-ast.h" +#define PARSE_INTEGER_LITERAL(base) \ + do { \ + errno = 0; \ + yylval->ull = strtoull(yytext, NULL, base); \ + if (errno) { \ + printfl_perror(yylineno, "Integer literal"); \ + return ERROR; \ + } \ + } while (0) + BT_HIDDEN void setstring(struct ctf_scanner *scanner, YYSTYPE *lvalp, const char *src); @@ -47,7 +58,7 @@ int import_string(struct ctf_scanner *scanner, YYSTYPE *lvalp, const char *src, %option reentrant yylineno noyywrap bison-bridge %option extra-type="struct ctf_scanner *" /* bison-locations */ -INTEGER_SUFFIX [ \n\t]*(U|UL|ULL|LU|LLU|Ul|Ull|lU|llU|u|uL|uLL|Lu|LLu|ul|ull|lu|llu) +INTEGER_SUFFIX [ \r\n\t]*(U|UL|ULL|LU|LLU|Ul|Ull|lU|llU|u|uL|uLL|Lu|LLu|ul|ull|lu|llu) DIGIT [0-9] NONDIGIT [a-zA-Z_] HEXDIGIT [0-9A-Fa-f] @@ -122,9 +133,10 @@ void setstring(yyextra, yylval, yytext); return VOID; _Bool setstring(yyextra, yylval, yytext); return _BOOL; _Complex setstring(yyextra, yylval, yytext); return _COMPLEX; _Imaginary setstring(yyextra, yylval, yytext); return _IMAGINARY; -[1-9]{DIGIT}*{INTEGER_SUFFIX}? setstring(yyextra, yylval, yytext); return DECIMAL_CONSTANT; -0{OCTALDIGIT}*{INTEGER_SUFFIX}? setstring(yyextra, yylval, yytext); return OCTAL_CONSTANT; -0[xX]{HEXDIGIT}+{INTEGER_SUFFIX}? setstring(yyextra, yylval, yytext); return HEXADECIMAL_CONSTANT; +[1-9]{DIGIT}*{INTEGER_SUFFIX}? PARSE_INTEGER_LITERAL(10); return INTEGER_LITERAL; +0{OCTALDIGIT}*{INTEGER_SUFFIX}? PARSE_INTEGER_LITERAL(8); return INTEGER_LITERAL; +0[xX]{HEXDIGIT}+{INTEGER_SUFFIX}? PARSE_INTEGER_LITERAL(16); return INTEGER_LITERAL; + {IDENTIFIER} printf_debug("\n", yytext); setstring(yyextra, yylval, yytext); if (is_type(yyextra, yytext)) return ID_TYPE; else return IDENTIFIER; [ \t\r\n] ; /* ignore */ . printfl_error(yylineno, "invalid character '0x%02X'", yytext[0]); return ERROR; diff --git a/formats/ctf/metadata/ctf-parser.y b/formats/ctf/metadata/ctf-parser.y index ce514c68..a31e9637 100644 --- a/formats/ctf/metadata/ctf-parser.y +++ b/formats/ctf/metadata/ctf-parser.y @@ -1064,12 +1064,13 @@ void ctf_scanner_free(struct ctf_scanner *scanner) */ %expect 2 %start file -%token 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 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; @@ -1079,6 +1080,7 @@ void ctf_scanner_free(struct ctf_scanner *scanner) %type keywords +%type INTEGER_LITERAL %type postfix_expression unary_expression unary_expression_or_range %type declaration @@ -1212,26 +1214,11 @@ postfix_expression: $$->u.unary_expression.type = UNARY_STRING; $$->u.unary_expression.u.string = yylval.gs->s; } - | DECIMAL_CONSTANT + | INTEGER_LITERAL { $$ = 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 - { - $$ = 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); - } - | 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); + $$->u.unary_expression.u.unsigned_constant = $1; } | STRING_LITERAL { diff --git a/tests/ctf-traces/fail/integer-range/metadata b/tests/ctf-traces/fail/integer-range/metadata new file mode 100644 index 00000000..35749408 --- /dev/null +++ b/tests/ctf-traces/fail/integer-range/metadata @@ -0,0 +1,27 @@ +/* CTF 1.8 */ +typealias integer { size = 8; align = 8; signed = false; } := uint8_t; +typealias integer { size = 32; align = 32; signed = false; } := uint32_t; + +trace { + /* Integer out of range */ + major = 23452397856348975623897562893746589237465289374658923764598237645897234658723648579236; + minor = 1; + uuid = "2a6422d0-6cee-11e0-8c08-cb07d7b3a564"; + byte_order = le; + packet.header := struct { + uint32_t magic; + uint8_t uuid[16]; + }; +}; + +stream { + packet.context := struct { + uint32_t content_size; + uint32_t packet_size; + }; +}; + +event { + name = string; + fields := struct { string str; }; +}; diff --git a/tests/ctf-traces/succeed/succeed4/metadata b/tests/ctf-traces/succeed/succeed4/metadata new file mode 100644 index 00000000..a3d401ab --- /dev/null +++ b/tests/ctf-traces/succeed/succeed4/metadata @@ -0,0 +1,31 @@ +/* CTF 1.8 */ +typealias integer { size = 8; align = 8; signed = false; } := uint8_t; +typealias integer { size = 32; align = 32; signed = false; } := uint32_t; + +trace { + major = 0; + minor = 1; + test = 0xABC234; /* hexadecimal */ + test1 = 06534; /* octal */ + test2 = 1234; /* decimal */ + test3 = +1234; /* decimal with + unary op */ + test4 = -1234; /* decimal (negated) */ + uuid = "2a6422d0-6cee-11e0-8c08-cb07d7b3a564"; + byte_order = le; + packet.header := struct { + uint32_t magic; + uint8_t uuid[16]; + }; +}; + +stream { + packet.context := struct { + uint32_t content_size; + uint32_t packet_size; + }; +}; + +event { + name = string; + fields := struct { string str; }; +}; -- 2.34.1