diff --git a/src/parser/parser.l b/src/parser/parser.l index 068d828..526bc92 100644 --- a/src/parser/parser.l +++ b/src/parser/parser.l @@ -121,6 +121,7 @@ continue return CONTINUE; sizeof return SIZEOF; +__attribute__ return ATTRIBUTE; L?'[^\\]' return CHAR_CONST; L?'\\.' return CHAR_CONST; diff --git a/src/parser/parser.yc b/src/parser/parser.yc index fde0fcb..1d9e9b5 100644 --- a/src/parser/parser.yc +++ b/src/parser/parser.yc @@ -112,6 +112,7 @@ int yylex(YYSTYPE *, YYLTYPE *); %token IDENTIFIER; %token TYPE_NAME; +%token ATTRIBUTE; %start translation_unit @@ -303,6 +304,14 @@ declaration_specifiers $$ = $2; $$->list->push_back($1); } + | attribute_spec { + $$ = new Node(NODE_TYPE_LIST); + $$->list->push_back($1); + } + | attribute_spec declaration_specifiers { + $$ = $2; + $$->list->push_back($1); + } ; init_declarator_list @@ -404,8 +413,8 @@ type_qualifier ; declarator - : pointer direct_declarator { $$ = $2; } - | direct_declarator + : pointer direct_declarator opt_attribute_spec { $$ = $2; } + | direct_declarator opt_attribute_spec ; direct_declarator @@ -558,10 +567,46 @@ external_declaration ; function_definition - : declaration_specifiers declarator declaration_list compound_statement - | declaration_specifiers declarator compound_statement - | declarator declaration_list compound_statement - | declarator compound_statement + : declaration_specifiers declarator declaration_list opt_attribute_spec compound_statement + | declaration_specifiers declarator opt_attribute_spec compound_statement + | declarator declaration_list opt_attribute_spec compound_statement + | declarator opt_attribute_spec compound_statement + ; + +opt_attribute_spec + : { $$ = nullptr; } + | attribute_spec + ; + +attribute_spec + : ATTRIBUTE LPAREN LPAREN attribute_list RPAREN RPAREN + ; + +attribute_list + : attribute { + $$ = new Node(NODE_TYPE_LIST); + $$->list->push_back($1); + } + | attribute_list COMMA attribute { + $$ = $1; + $$->list->push_back($3); + } + ; + +attribute + : IDENTIFIER + | IDENTIFIER LPAREN primary_expression_list RPAREN + ; + +primary_expression_list + : primary_expression { + $$ = new Node(NODE_TYPE_LIST); + $$->list->push_back($1); + } + | primary_expression_list COMMA primary_expression { + $$ = $1; + $$->list->push_back($3); + } ; %%