s_instr *parse_rule_if(s_lexer *lex) { s_list_instr *list_cond = NULL; s_list_instr *list_instr_t = NULL; s_instr *instr_f = NULL; s_token *tok; if ((NULL == (tok = lexer_pop_token(lex))) || (strcmp(tok->str, "if"))) return (NULL); if (NULL == (list_cond = parse_compound_list(lex))) return (NULL); if ((NULL == (tok = lexer_pop_token(lex))) || (strcmp(tok->str, "then"))) FREE_LIST_RETURN(list_cond, NULL, NULL); if ((NULL == (list_instr_t = parse_compound_list(lex)))) FREE_LIST_RETURN(list_cond, NULL, NULL); if ((NULL == (instr_f = parse_else_clause(lex))) && (errno != ENOTFOUND)) FREE_LIST_RETURN(list_cond, list_instr_t, NULL); if ((NULL == (tok = lexer_pop_token(lex))) || (strcmp(tok->str, "fi"))) FREE_LIST_RETURN(list_cond, list_instr_t, instr_f); return (build_instr(AST_INSTR_IF, build_instr_if(list_cond, list_instr_t, instr_f))); }
/* 3.9.4.1 parse a grouping compound * * The format for grouping commands is a s follows: * * (compound-list) Execute compound-list in a subshell environment; * Variable assignments and built-in commands that * affect the environment shall not remain in effect * after the list finishes. * * { compound-list;} Execute compound-list in the current process * environment. * * ----------------------------------------------------------------------- */ union node *parse_grouping(struct parser *p) { enum tok_flag tok; union node **rptr; union node *grouping; union node *compound_list; /* return NULL on empty compound */ grouping = NULL; if(!(tok = parse_expect(p, P_DEFAULT, T_BEGIN|T_LP, NULL))) return NULL; /* parse compound content and create a compound node if there are commands */ if((compound_list = parse_compound_list(p))) { grouping = tree_newnode(tok == T_BEGIN ? N_CMDLIST : N_SUBSHELL); grouping->ngrp.cmds = compound_list; } /* expect the appropriate ending token */ if(!parse_expect(p, P_DEFAULT, tok << 1, grouping)) return NULL; if(grouping) { tree_init(grouping->ngrp.rdir, rptr); /* now any redirections may follow */ while(parse_gettok(p, P_DEFAULT) & T_REDIR) tree_move(p->tree, rptr); p->pushback++; } return grouping; }
s_instr *parse_rule_until(s_lexer *lex) { s_list_instr *list_cond = NULL; s_list_instr *list_instr = NULL; s_token *tok; if ((NULL == (tok = lexer_pop_token(lex))) || (strcmp(tok->str, "until"))) return (NULL); if (NULL == (list_cond = parse_compound_list(lex))) return (NULL); if (NULL == (list_instr = parse_do_group(lex))) FREE_LIST_RETURN(list_cond); return (build_instr(AST_INSTR_UNTIL, build_instr_until(list_cond, list_instr))); }