/* A.2.2 Declarations (6.7) declaration: declaration-specifiers init-declarator-list(opt) ; (6.7) declaration-specifiers: storage-class-specifier declaration-specifiers(opt) type-specifier declaration-specifiers(opt) type-qualifier declaration-specifiers(opt) function-specifier declaration-specifiers(opt) (6.7) init-declarator-list: init-declarator init-declarator-list , init-declarator (6.7) init-declarator: declarator declarator = initializer (6.7.1) storage-class-specifier: typedef extern static auto register (6.7.2) type-specifier: void char short int long float double signed unsigned _Bool _Complex struct-or-union-specifier enum-specifier typedef-name (6.7.2.1) struct-or-union-specifier: struct-or-union identifier(opt) { struct-declaration-list } struct-or-union identifier (6.7.2.1) struct-or-union: struct union (6.7.2.1) struct-declaration-list: struct-declaration struct-declaration-list struct-declaration (6.7.2.1) struct-declaration: specifier-qualifier-list struct-declarator-list ; (6.7.2.1) specifier-qualifier-list: type-specifier specifier-qualifier-list(opt) type-qualifier specifier-qualifier-list(opt) (6.7.2.1) struct-declarator-list: struct-declarator struct-declarator-list , struct-declarator (6.7.2.1) struct-declarator: declarator declarator(opt) : constant-expression (6.7.2.2) enum-specifier: enum identifier(opt) { enumerator-list } enum identifier(opt) { enumerator-list , } enum identifier (6.7.2.2) enumerator-list: enumerator enumerator-list , enumerator (6.7.2.2) enumerator: enumeration-constant enumeration-constant = constant-expression (6.7.3) type-qualifier: const restrict volatile (6.7.4) function-specifier: inline (6.7.5) declarator: pointer(opt) direct-declarator (6.7.5) direct-declarator: identifier ( declarator ) direct-declarator [ type-qualifier-list(opt) assignment-expression(opt) ] direct-declarator [ static type-qualifier-list(opt) assignment-expression ] direct-declarator [ type-qualifier-list static assignment-expression ] direct-declarator [ type-qualifier-list(opt) * ] direct-declarator ( parameter-type-list ) direct-declarator ( identifier-list(opt) ) (6.7.5) pointer: * type-qualifier-list(opt) * type-qualifier-list(opt) pointer (6.7.5) type-qualifier-list: type-qualifier type-qualifier-list type-qualifier (6.7.5) parameter-type-list: parameter-list parameter-list , ... (6.7.5) parameter-list: parameter-declaration parameter-list , parameter-declaration (6.7.5) parameter-declaration: declaration-specifiers declarator declaration-specifiers abstract-declarator(opt) (6.7.5) identifier-list: identifier identifier-list , identifier (6.7.6) type-name: specifier-qualifier-list abstract-declarator(opt) (6.7.6) abstract-declarator: pointer pointer(opt) direct-abstract-declarator (6.7.6) direct-abstract-declarator: ( abstract-declarator ) direct-abstract-declarator(opt) [ type-qualifier-list (opt) assignment-expression(opt) ] direct-abstract-declarator(opt) [ static type-qualifier-list(opt) assignment-expression ] direct-abstract-declarator(opt) [ type-qualifier-list static assignment-expression ] direct-abstract-declarator(opt) [ * ] direct-abstract-declarator(opt) ( parameter-type-list(opt) ) (6.7.7) typedef-name: identifier (6.7.8) initializer: assignment-expression { initializer-list } { initializer-list , } (6.7.8) initializer-list: designation(opt) initializer initializer-list , designation(opt) initializer (6.7.8) designation: designator-list = (6.7.8) designator-list: designator designator-list designator (6.7.8) designator: [ constant-expression ] . identifier A.2.4 External definitions (6.9) translation-unit: external-declaration translation-unit external-declaration (6.9) external-declaration: function-definition declaration (6.9.1) function-definition: declaration-specifiers declarator declaration-list(opt) compound-statement (6.9.1) declaration-list: declaration declaration-list declaration */ #include #include scc_ast_decl_t *scc_parse_declaration(scc_parser_t *parser) { /** * ISO/IEC 9899:TC3 * 6.7 Declarations * Syntax * * declaration: * declaration-specifiers init-declarator-list(opt) ; * declaration-specifiers: * storage-class-specifier declaration-specifiers(opt) * type-specifier declaration-specifiers(opt) * type-qualifier declaration-specifiers(opt) * function-specifier declaration-specifiers(opt) * init-declarator-list: * init-declarator * init-declarator-list , init-declarator * init-declarator: * declarator * declarator = initializer */ cbool ok; scc_lexer_tok_t tok; scc_ast_node_t *type_or_decl = _scc_parse_type(parser); scc_ast_decl_t *decl = null; if (type_or_decl == null) { return null; } if (SCC_AST_IS_A(scc_ast_type_t, type_or_decl)) { LOG_WARN("declaration dose not declare anything"); return null; } else if (SCC_AST_IS_A(scc_ast_decl_t, type_or_decl)) { decl = SCC_AST_CAST_TO(scc_ast_decl_t, type_or_decl); } else { LOG_ERROR("invalid declaration"); return null; } const scc_lexer_tok_t *tok_ptr = scc_parser_peek(parser); if (tok_ptr->type == SCC_TOK_SEMICOLON) { scc_parser_next_consume(parser, null); goto RETURN; } else if (tok_ptr->type == SCC_TOK_ASSIGN) { scc_parser_next_consume(parser, null); scc_ast_expr_t *init = scc_parse_expression(parser); decl->var.init = init; if (!scc_parser_consume_if(parser, SCC_TOK_SEMICOLON)) { LOG_ERROR("expect semicolon"); } goto RETURN; } else if (tok_ptr->type == SCC_TOK_L_BRACE) { scc_ast_stmt_t *body = scc_parse_statement(parser); Assert(decl->base.type == SCC_AST_DECL_FUNC); decl->func.body = body; Assert(decl->func.type != null); Assert(decl->func.type->base.type == SCC_AST_TYPE_FUNCTION); Assert(decl->func.body != null); Assert(decl->func.body->base.type == SCC_AST_STMT_COMPOUND); } else { UNREACHABLE(); } RETURN: if (decl) { parser->sema_callbacks.on_decl(parser->sema_callbacks.context, decl->base.type, decl); } return decl; }