static enum v7_err parse_if_statement(struct v7 *v7) { int old_no_exec = v7->no_exec; TRY(match(v7, '(')); TRY(parse_expression(v7)); TRY(match(v7, ')')); assert(v7->no_exec || v7->sp > 0); // Stack may be empty if v7->no_exec if (!v7->no_exec && !v7_is_true(v7_top(v7)[-1])) { v7->no_exec = 1; } TRY(parse_compound_statement(v7)); v7->no_exec = old_no_exec; return V7_OK; }
void test_compound_statement() { char tmp; FILE *inn = fopen("tests/test_compound_statement.txt", "r"); while (!feof(inn)) { in = fopen("test.txt", "w+"); while ((tmp = fgetc(inn)) != '}' && tmp != -1) fprintf(in, "%c", tmp); if (tmp == EOF) break; if (tmp <= 31) continue; fseek(in, 0, SEEK_SET); idx = 0; printf("******************\n"); get_token_with_history(); parse_compound_statement(); fclose(in); remove("test.txt"); } }
// assume no EOF found; static struct external_declaration *parse_external_decl(struct parser *parser) { struct declaration_specifiers *decl_specifiers = parse_declaration_specifiers(parser); struct external_declaration *external_decl = external_declaration_init(decl_specifiers); struct declarator *declarator = NULL; // compound statement case struct compound_statement *compound_stmt = NULL; // declaration case struct init_declarator_list *init_declarator_list = NULL; // check for empty init_declarator_list case, similar to what we do in // parse_init_declarator_list union token tok = lexer_next_token(parser->lexer); if (tok.tok_tag == TOK_SEMICOLON) { } else { lexer_put_back(parser->lexer, tok); declarator = parse_declarator(parser); tok = lexer_next_token(parser->lexer); if (tok.tok_tag == TOK_LBRACE) { lexer_push_typedef_tab(parser->lexer); register_func_parameters_for_typedef(parser, declarator); lexer_put_back(parser->lexer, tok); compound_stmt = parse_compound_statement(parser); lexer_pop_typedef_tab(parser->lexer); // set external decl external_decl->func_def_declarator = declarator; external_decl->compound_stmt = compound_stmt; } else { lexer_put_back(parser->lexer, tok); init_declarator_list = parse_init_declarator_list_with_la(parser, declarator); // set external decl external_decl->init_declarator_list = init_declarator_list; register_potential_typedefs(parser, decl_specifiers, init_declarator_list); } } return external_decl; }
/** * return the syntreebasenode which can be used as the base type */ struct syntreebasenode *parse_statement(struct parser *parser) { union token tok = lexer_next_token(parser->lexer); if (initiate_compound_statement(tok)) { lexer_put_back(parser->lexer, tok); lexer_push_typedef_tab(parser->lexer); struct syntreebasenode *ret = (struct syntreebasenode *) parse_compound_statement(parser); lexer_pop_typedef_tab(parser->lexer); return ret; } else if (initiate_iteration_statement(tok)) { lexer_put_back(parser->lexer, tok); return (struct syntreebasenode *) parse_iteration_statement(parser); } else if (initiate_jump_statement(tok)) { lexer_put_back(parser->lexer, tok); return (struct syntreebasenode *) parse_jump_statement(parser); } else if (initiate_selection_statement(tok)) { lexer_put_back(parser->lexer, tok); return (struct syntreebasenode *) parse_selection_statement(parser); } else { // Note: may need 2 lookaheads to decide whether it's a labeled statement // or expression statement // // a + b // a: x = y union token tok2 = lexer_next_token(parser->lexer); if (initiate_labeled_statement(tok, tok2)) { lexer_put_back(parser->lexer, tok2); lexer_put_back(parser->lexer, tok); return (struct syntreebasenode *) parse_labeled_statement(parser); } else { lexer_put_back(parser->lexer, tok2); lexer_put_back(parser->lexer, tok); return (struct syntreebasenode *) parse_expression_statement(parser); } } }