/*----------------------------------------------------------------------*/ static ast_statement_t *parse_if(parse_state_t *p) { token_t *token; ast_statement_t *statement; /* if */ token = next_token(p); EXPECT(token, TK_IF, "'if' expected"); statement = ALLOC(sizeof(ast_statement_t)); BZERO(statement); statement->tag = AST_STATEMENT_IF; /* if predicate / block */ statement->u.if_.condition = parse_logical_expression(p); statement->u.if_.if_block = parse_statement_list(p); /* else? */ token = peek_token(p); if (test_token(token, TK_ELSE)) { next_token(p); /* else block */ statement->u.if_.else_block = parse_statement_list(p); } else { statement->u.if_.else_block = NULL; } /* end */ token = next_token(p); EXPECT(token, TK_END, "'end' expected"); return statement; }
void cx_parser::parse_case_label(cx_symtab_node* p_function_id, const cx_type *p_expr_type) { get_token_append(); bool sign_flag(false); if (token_in(token, tokenlist_unary_ops)) { sign_flag = true; get_token_append(); } switch (token) { case tc_identifier: if (!search_all(p_token->string__())) { cx_error(err_undefined_identifier); } get_token_append(); break; case tc_number: if (p_token->type() != ty_integer) cx_error(err_invalid_constant); get_token_append(); break; case tc_string: if (sign_flag || (strlen(p_token->string__()) != 3)) { cx_error(err_invalid_constant); } break; default: break; } conditional_get_token_append(tc_colon, err_missing_colon); parse_statement_list(p_function_id, tc_BREAK); }
/** parse_compound parse compounded statements. * * { * <statements>; * } * * @param p_function_id : ptr to this statements function Id. */ void cx_parser::parse_compound(cx_symtab_node* p_function_id) { get_token_append(); parse_statement_list(p_function_id, tc_right_bracket); // if ((p_function_id->defn.routine.which == func_std_iterator)) return; conditional_get_token_append(tc_right_bracket, err_missing_right_bracket); }
/* parse_statement_list Recursively parses a valid statement Parameters: none Return: none */ void parse_statement_list(Tree &cst){ cst.add_branch_node("statement_list"); if(!(curr_token -> type).compare("closed_block")){ // ε production, do nothing } else{ parse_statement(cst); parse_statement_list(cst); } cst.kill_all_children(); }
/* parse_block Matches a block of code Parameters: none Return: none */ void parse_block(Tree &cst){ cst.add_branch_node("block"); if(!(curr_token -> type).compare("open_block")) { match("{", cst); parse_statement_list(cst); match("}", cst); } else{ std::cout << "Invalid block declaration on line " << curr_token -> line_number << std::endl; exit(EXIT_FAILURE); } cst.kill_all_children(); }
/*----------------------------------------------------------------------*/ void parse(parse_input_t *parse_in, parse_output_t *parse_out) { parse_state_t parse_state; parse_state_t *p = &parse_state; p->in = parse_in; p->out = parse_out; p->out->error = 0; p->token_index = 0; if (setjmp(p->jmpbuf)) { return; } p->out->first_statement = parse_statement_list(p); }
/** parse_DO parse do/while statement. * * do * <statement>; * while(<expression>); * * @param p_function_id : ptr to this statements function Id. */ void cx_parser::parse_DO(cx_symtab_node* p_function_id) { int break_point = put_location_marker(); get_token_append(); //do parse_statement_list(p_function_id, tc_WHILE); conditional_get_token_append(tc_WHILE, err_missing_WHILE); conditional_get_token_append(tc_left_paren, err_missing_left_paren); check_boolean(parse_expression()); conditional_get_token_append(tc_right_paren, err_missing_right_paren); fixup_location_marker(break_point); }
/*----------------------------------------------------------------------*/ static ast_statement_t *parse_for(parse_state_t *p) { token_t *token; ast_statement_t *statement_for; ast_statement_t **next_statement; statement_for = ALLOC(sizeof(ast_statement_t)); BZERO(statement_for); statement_for->tag = AST_STATEMENT_FOR; statement_for->u.for_.initialize = NULL; statement_for->u.for_.condition = NULL; statement_for->u.for_.increment = NULL; /* for */ token = next_token(p); EXPECT(token, TK_FOR, "'for' expected"); /* init statements */ next_statement = &statement_for->u.for_.initialize; for (;;) { token = peek_token(p); if (test_token(token, TK_SEMICOLON)) { next_token(p); break; } *next_statement = parse_statement(p); if (*next_statement == NULL) { error(p, "statement expected"); } next_statement = &((*next_statement)->next); *next_statement = NULL; token = peek_token(p); if (test_token(token, TK_SEMICOLON)) { next_token(p); break; } else if (test_token(token, TK_COMMA)) { next_token(p); } else { error(p, "';' or ',' expected"); } } /* conditional */ token = peek_token(p); if (test_token(token, TK_SEMICOLON)) { next_token(p); } else { statement_for->u.for_.condition = parse_logical_expression(p); if (statement_for->u.for_.condition == NULL) { error(p, "conditional expression expected"); } token = peek_token(p); EXPECT(token, TK_SEMICOLON, "';' expected"); next_token(p); } /* increment statements */ next_statement = &statement_for->u.for_.increment; for (;;) { token = peek_token(p); if (test_token(token, TK_DO)) { next_token(p); break; } *next_statement = parse_statement(p); if (*next_statement == NULL) { error(p, "increment statement or 'do' expected"); } next_statement = &((*next_statement)->next); *next_statement = NULL; token = peek_token(p); if (test_token(token, TK_DO)) { next_token(p); break; } else if (test_token(token, TK_COMMA)) { next_token(p); } else { error(p, "'do' or ',' expected"); } } /* block */ statement_for->u.for_.block = parse_statement_list(p); /* end */ token = next_token(p); EXPECT(token, TK_END, "'end' expected"); return statement_for; }
/*----------------------------------------------------------------------*/ static ast_statement_t *parse_define_function(parse_state_t *p) { token_t *token; ast_statement_t *statement; ast_function_parameter_t *parameter = NULL; ast_function_parameter_t *prev_parameter = NULL; statement = ALLOC(sizeof(ast_statement_t)); BZERO(statement); statement->tag = AST_STATEMENT_DEFINE_FUNCTION; /* function keyword */ token = next_token(p); EXPECT(token, TK_FUNCTION, "'function' expected"); /* function name */ token = next_token(p); EXPECT(token, TK_IDENTIFIER, "function name expected"); statement->u.define_function.name_token = token; /* function parameters */ token = peek_token(p); if (test_token(token, TK_LBRACKET)) { /* opening bracket? */ next_token(p); for (;;) { token = peek_token(p); if (token == NULL || token->type != TK_IDENTIFIER) break; next_token(p); prev_parameter = parameter; parameter = ALLOC(sizeof(ast_function_parameter_t)); if (prev_parameter == NULL) { statement->u.define_function.first_parameter = parameter; } else { prev_parameter->next = parameter; } /* parameter name */ parameter->identifier_token = token; /* colon before parameter type */ token = next_token(p); EXPECT(token, TK_COLON, "':' expected"); /* parameter type */ token = next_token(p); EXPECT(token, TK_IDENTIFIER, "parameter type expected"); parameter->type_token = token; /* comma? */ token = peek_token(p); if (!test_token(token, TK_COMMA)) break; next_token(p); } /* closing bracket */ token = next_token(p); EXPECT(token, TK_RBRACKET, "')' expected"); } /* colon before return type? */ token = peek_token(p); if (test_token(token, TK_COLON)) { next_token(p); /* return type */ token = next_token(p); statement->u.define_function.return_type_token = token; EXPECT(token, TK_IDENTIFIER, "return type expected"); } /* function body statement list */ statement->u.define_function.block = parse_statement_list(p); /* end */ token = next_token(p); EXPECT(token, TK_END, "'end' expected"); return statement; }