/** parse_IF parse if/else statements. * * if(<expression>) * <statement>; * else if (<expression>) * <statement>; * else * <statement>; * * @param p_function_id : ptr to this statements function Id. */ void cx_parser::parse_IF(cx_symtab_node* p_function_id) { // Append a placeholder location marker for where to go to if // <expr> is false. Remember the location of this placeholder // so it can be fixed up below. int at_false_location_marker = put_location_marker(); get_token_append(); 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); parse_statement(p_function_id); while (token == tc_semicolon) get_token_append(); fixup_location_marker(at_false_location_marker); if (token == tc_ELSE) { // Append a placeholder location marker for the token that // follows the IF statement. Remember the location of this // placeholder so it can be fixed up below. int at_follow_location_marker = put_location_marker(); get_token_append(); parse_statement(p_function_id); while (token == tc_semicolon) get_token_append(); fixup_location_marker(at_follow_location_marker); } }
/*----------------------------------------------------------------------*/ static ast_statement_t *parse_statement_list(parse_state_t *p) { ast_statement_t *first; ast_statement_t *s; first = parse_statement(p); s = first; for (s = first; s != NULL; s = s->next) { s->next = parse_statement(p); } return first; }
static enum v7_err parse_compound_statement(struct v7 *v7) { if (*v7->cursor == '{') { int old_sp = v7->sp; match(v7, '{'); while (*v7->cursor != '}') { if (v7->sp > old_sp) inc_stack(v7, old_sp - v7->sp); TRY(parse_statement(v7, NULL)); } match(v7, '}'); } else { TRY(parse_statement(v7, NULL)); } return V7_OK; }
V7_PRIVATE enum v7_err do_exec(struct v7 *v7, const char *file_name, const char *source_code, int sp) { int has_ret = 0; struct v7_pstate old_pstate = v7->pstate; enum v7_err err = V7_OK; v7->pstate.source_code = v7->pstate.pc = source_code; v7->pstate.file_name = file_name; v7->pstate.line_no = 1; // Prior calls to v7_exec() may have left current_scope modified, reset now // TODO(lsm): free scope chain v7->this_obj = &v7->root_scope; next_tok(v7); while ((err == V7_OK) && (v7->cur_tok != TOK_END_OF_INPUT)) { // Reset stack on each statement if ((err = inc_stack(v7, sp - v7->sp)) == V7_OK) { err = parse_statement(v7, &has_ret); } } //printf("%s: [%s] %d %d\n", __func__, file_name, v7->pstate.line_no, err); assert(v7->root_scope.proto == &s_global); v7->pstate = old_pstate; return err; }
/* * Parse block of statements. The block has already been checked * to begin with a '{'. */ static int parse_block(policy_lex_file_t *lexer, policy_item_t **tail) { int rcode; policy_lex_t token; debug_tokens("[BLOCK] "); token = policy_lex_file(lexer, 0, NULL, 0); if (token != POLICY_LEX_LC_BRACKET) { fprintf(stderr, "%s[%d]: Expected '{'\n", lexer->filename, lexer->lineno); return 0; } while ((rcode = parse_statement(lexer, tail)) != 0) { if (rcode == 2) { token = policy_lex_file(lexer, 0, NULL, 0); if (token != POLICY_LEX_RC_BRACKET) { fprintf(stderr, "%s[%d]: Expected '}'\n", lexer->filename, lexer->lineno); return 0; } return 1; } rad_assert(*tail != NULL); /* parse_statement must fill this in */ while (*tail) tail = &((*tail)->next); } debug_tokens("\n"); /* * Parse statement failed. */ return 0; }
// the caller should push and pop the typedef table struct compound_statement *parse_compound_statement(struct parser *parser) { expect(parser->lexer, TOK_LBRACE); // lexer_push_typedef_tab(parser->lexer); // look one token ahead to determing if this is a declaration or statement or empty block union token tok = lexer_next_token(parser->lexer); struct dynarr *decl_or_stmt_list = dynarr_init(); while (tok.tok_tag != TOK_RBRACE) { if (initiate_declaration(tok)) { #if 0 if (dynarr_size(stmtList) > 0) { panic("encounter declaration after statement"); } #endif lexer_put_back(parser->lexer, tok); dynarr_add(decl_or_stmt_list, parse_declaration(parser)); } else { // initiate a statement lexer_put_back(parser->lexer, tok); dynarr_add(decl_or_stmt_list, parse_statement(parser)); } tok = lexer_next_token(parser->lexer); } // lexer_pop_typedef_tab(parser->lexer); return compound_statement_init(decl_or_stmt_list); }
static struct iteration_statement *parse_for_statement(struct parser *parser) { struct expression_statement *expr_stmt1, *expr_stmt2; struct expression *expr = NULL; struct statement *stmt; struct iteration_statement *iter_stmt = iteration_statement_init(ITER_TYPE_FOR); union token tok; expect(parser->lexer, TOK_LPAREN); expr_stmt1 = parse_expression_statement(parser); expr_stmt2 = parse_expression_statement(parser); tok = lexer_next_token(parser->lexer); if (tok.tok_tag != TOK_RPAREN) { lexer_put_back(parser->lexer, tok); expr = parse_expression(parser); expect(parser->lexer, TOK_RPAREN); } stmt = parse_statement(parser); iter_stmt->for_stmt.expr_stmt_1 = expr_stmt1; iter_stmt->for_stmt.expr_stmt_2 = expr_stmt2; iter_stmt->for_stmt.expr = expr; iter_stmt->for_stmt.stmt = stmt; return iter_stmt; }
struct node *parse_statements(struct compiler *compiler) { skip_seps(compiler); if(is_expression(compiler)) { struct node *result = parse_statement(compiler); if (is_sep(compiler)) { skip_seps(compiler); if(is_expression(compiler)) { struct node *node = alloc_node(compiler, N_STATEMENTS); node->left = result; node->right = parse_statements(compiler); return node; } } return result; } else return &nil_node; }
/* * Parse through END statement */ void parse_to_end(void) { TOKEN token; parse_till_end(&token); parse_statement(&token); }
/* the program root node */ void parse_prog(ParseState* ps) { if (parse_hasError(ps)) return; do { parse_next(ps); parse_statement(ps); } while (ps->token != TK_EOI && !parse_hasError(ps)); }
/** parse_statement_list parse a statement list until the * terminator token. * * @param p_function_id : function in which these statements are executed. * @param terminator : the token that terminates the list. */ void cx_parser::parse_statement_list(cx_symtab_node* p_function_id, cx_token_code terminator) { do { parse_statement(p_function_id); while (token == tc_semicolon)get_token_append(); } while ((token != terminator) && (token != tc_end_of_file)); }
// Parses a block of statements, terminated by the given // character. void parse_block(Parser *parser, Token terminator) { Lexer *lexer = parser->lexer; // Continually parse statements while (lexer->token != TOKEN_EOF && lexer->token != terminator) { // Parse a single statement parse_statement(parser); } }
AST *ParserContext::parse_ast(bool in_block) { std::vector<const Statement*> statements; while (!lexer_.eos() && !(in_block && curtok()->type() == tok_block_end)) { statements.push_back(parse_statement()); } return new AST(statements); }
// function_defition = "function" "(" func_params ")" "{" func_body "}" static enum v7_err parse_function_definition(struct v7 *v7, struct v7_val **v, int num_params) { int i = 0, old_no_exec = v7->no_exec, old_sp = v7->sp; const char *src = v7->cursor; // If 'v' (func to call) is NULL, that means we're just parsing function // definition to save it's body. v7->no_exec = v == NULL; TRY(match(v7, '(')); // Initialize new scope if (!v7->no_exec) { v7->current_scope++; CHECK(v7->current_scope < (int) ARRAY_SIZE(v7->scopes), V7_RECURSION_TOO_DEEP); CHECK(v7->scopes[v7->current_scope].v.props == NULL, V7_INTERNAL_ERROR); CHECK(v7->scopes[v7->current_scope].type == V7_OBJ, V7_INTERNAL_ERROR); } while (*v7->cursor != ')') { TRY(parse_identifier(v7)); if (!v7->no_exec) { struct v7_val *key = v7_mkval_str(v7, v7->tok, v7->tok_len); struct v7_val *val = i < num_params ? v[i + 1] : v7_mkval(v7, V7_UNDEF); v7_set(v7, &v7->scopes[v7->current_scope], key, val); } i++; if (!test_and_skip_char(v7, ',')) break; } TRY(match(v7, ')')); TRY(match(v7, '{')); while (*v7->cursor != '}') { int is_return_statement = 0; inc_stack(v7, old_sp - v7->sp); // Clean up the stack from prev stmt TRY(parse_statement(v7, &is_return_statement)); if (is_return_statement) break; // Leave statement value on stack } if (v7->no_exec) { TRY(v7_make_and_push(v7, V7_FUNC)); v7_top(v7)[-1]->v.func = v7_strdup(src, (v7->cursor + 1) - src); } TRY(match(v7, '}')); // Deinitialize scope if (!v7->no_exec) { v7->scopes[v7->current_scope].ref_count = 1; // Force free_val() below free_val(v7, &v7->scopes[v7->current_scope]); v7->current_scope--; assert(v7->current_scope >= 0); } v7->no_exec = old_no_exec; return V7_OK; }
vanilla::statement_node::ptr vanilla::parse_string(char const* str) { scanner scan( (str) ); token_buffer buffer( (scan) ); std::vector<vanilla::statement_node::ptr> block; while(!buffer.accept(vanilla::ttype::eof)) block.push_back(parse_statement(buffer)); return make_unique<vanilla::statement_sequence_node>(0, 0, std::move(block)); }
/* 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(); }
void Parser::parse_multi_line_statements( CmdList& commands ) { consume_eols(); while (next_is_statement()) { Cmd* statement = parse_statement(); if (statement) { commands.add( statement ); } while (consume_eols() || consume(TOKEN_SEMICOLON)) {} } }
static struct iteration_statement *parse_while_statement(struct parser *parser) { struct expression *expr; struct statement *stmt; struct iteration_statement *iter_stmt = iteration_statement_init(ITER_TYPE_WHILE); expect(parser->lexer, TOK_LPAREN); expr = parse_expression(parser); expect(parser->lexer, TOK_RPAREN); stmt = parse_statement(parser); iter_stmt->while_stmt.expr = expr; iter_stmt->while_stmt.stmt = stmt; return iter_stmt; }
static struct selection_statement *parse_if_statement(struct parser *parser) { struct expression *expr; struct statement *truestmt, *falsestmt = NULL; union token tok; struct selection_statement *selstmt = selection_statement_init(SEL_TYPE_IF); expect(parser->lexer, TOK_LPAREN); expr = parse_expression(parser); expect(parser->lexer, TOK_RPAREN); truestmt = parse_statement(parser); tok = lexer_next_token(parser->lexer); if (tok.tok_tag == TOK_ELSE) { falsestmt = parse_statement(parser); } else { lexer_put_back(parser->lexer, tok); } selstmt->if_stmt.expr = expr; selstmt->if_stmt.truestmt = truestmt; selstmt->if_stmt.falsestmt = falsestmt; return selstmt; }
static struct selection_statement *parse_switch_statement(struct parser *parser) { struct expression *expr; struct selection_statement *selstmt = selection_statement_init(SEL_TYPE_SWITCH); struct statement *stmt; expect(parser->lexer, TOK_LPAREN); expr = parse_expression(parser); expect(parser->lexer, TOK_RPAREN); stmt = parse_statement(parser); selstmt->switch_stmt.expr = expr; selstmt->switch_stmt.stmt = stmt; return selstmt; }
void parse(parser_t* p) { token_type_t tok = get_token(p->t); while (TT_EOF != tok) { if (TT_DEF == tok) { unget_token(p->t); list_insert(p->ast->function_list, parse_funcdef(p, false)); } else { unget_token(p->t); statement_t* statement = parse_statement(p); list_insert(p->ast->statement_list, statement); } tok = get_token(p->t); } }
/** parse_WHILE parse while statement. * * while(<expression>) * <statement>; * * @param p_function_id : ptr to this statements function Id. */ void cx_parser::parse_WHILE(cx_symtab_node* p_function_id) { int break_point = put_location_marker(); get_token_append(); // 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); parse_statement(p_function_id); fixup_location_marker(break_point); }
// code = { statement } enum v7_err v7_exec(struct v7 *v7, const char *source_code) { v7->source_code = v7->cursor = source_code; skip_whitespaces_and_comments(v7); // The following code may raise an exception and jump to the previous line, // returning non-zero from the setjmp() call // Prior calls to v7_exec() may have left current_scope modified, reset now v7->current_scope = 0; // XXX free up higher scopes? inc_stack(v7, -v7->sp); while (*v7->cursor != '\0') { inc_stack(v7, -v7->sp); // Reset stack on each statement TRY(parse_statement(v7, 0)); // Leave the result of last expr on stack } return V7_OK; }
static block_t* parse_block(parser_t* p) { block_t* block = (block_t*)malloc(sizeof(block_t)); block->statements = create_list(); while (1) { token_type_t tok; tok = get_token(p->t); if (IS_END_OF_BLOCK_TOKEN(tok)) { unget_token(p->t); break; } else { unget_token(p->t); list_insert(block->statements, parse_statement(p)); } } return block; }
struct StatementList* parse_statementlist(const struct Symbol** symbols, int symbolCount, int* symbolsConsumed) { struct StatementList* statementlist = (struct StatementList*)calloc(1, sizeof(struct StatementList)); // Make sure there are symbols left if (symbolCount <= 0) { SYNTAX_ERROR("Unexpected EOF when looking for statement list"); } PRINTF_AST("STATEMENTLIST"); PRINTF_AST_ENTER(); // Start by pulling out the next statement int symbolsInStatement = 0; statementlist->statement = parse_statement(symbols, symbolCount, &symbolsInStatement); // If that is not the end of the symbols, parse more statements if (symbols[symbolsInStatement]->type != SYMBOL_EOF) { if (symbols[symbolsInStatement]->type == SYMBOL_EOL) { int symbolsInStatementList = 0; statementlist->statementlist = parse_statementlist( &symbols[symbolsInStatement+1], (symbolCount - 1) - symbolsInStatement, &symbolsInStatementList); *symbolsConsumed = symbolsInStatement + 1 /* newline */ + symbolsInStatementList; } else { SYNTAX_ERROR_AT(symbols[symbolCount-1], "Expected newline or EOF at end of statement"); } } // If that is the end of the symbols, the list is complete else { *symbolsConsumed = symbolsInStatement; } PRINTF_AST_LEAVE(); return statementlist; }
/** parse_SWITCH parse switch statements. * * switch(<expression>){ * case <const-expression>: * default: * } * * NOTE: * Broken/not implemented yet. * * @param p_function_id : ptr to this statements function Id. */ void cx_parser::parse_SWITCH(cx_symtab_node* p_function_id) { get_token_append(); conditional_get_token_append(tc_left_paren, err_missing_left_paren); cx_type *p_expr_type = parse_expression()->base_type(); conditional_get_token_append(tc_right_paren, err_missing_right_paren); if ((p_expr_type != p_integer_type) && (p_expr_type != p_char_type) && (p_expr_type->form != fc_enum)) { cx_error(err_incompatible_types); } parse_statement(p_function_id); }
void test_statement() { char tmp; FILE *inn = fopen("tests/test_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_statement(); fclose(in); remove("test.txt"); } }
AST *ParserContext::parse_block() { AST *ret = 0; if (curtok()->type() == tok_block_start) { eat_token(tok_block_start); if (curtok()->type() == tok_block_end) { ret = new AST(std::vector<const Statement*>()); } else { ret = parse_ast(true); } eat_token(tok_block_end); } else { std::vector<const Statement*> statements; statements.push_back(parse_statement()); ret = new AST(statements); } return ret; }
/* * Parse until END statement */ void parse_till_end(TOKEN *token) { int token_class; while (1) { token_class = get_token(token); if (token_class == END_OF_FILE) { parse_error("Premature end-of-file"); exit(1); } if ((token_class == RESERVED) && (token->token_type == END)) return; parse_statement(token); } }
static struct labeled_statement *parse_labeled_statement(struct parser *parser) { union token initok = lexer_next_token(parser->lexer); struct labeled_statement *labeled_stmt = labeled_statement_init(initok.tok_tag); switch (initok.tok_tag) { case TOK_IDENTIFIER: labeled_stmt->label_str = initok.id.s; break; case TOK_CASE: labeled_stmt->case_expr = parse_constant_expression(parser); break; case TOK_DEFAULT: break; default: panic("invalid labeled statement"); } expect(parser->lexer, TOK_COLON); labeled_stmt->stmt = parse_statement(parser); return labeled_stmt; }