Node* analyze_line(String* str) { Node* node; st_token_buf = NULL; lexer_init(str); parser_init(); node = parse_acceptable(); switch ( parser_state() ) { case PS_ACCEPT: if ( node == NULL ) { fprintf(stderr, "parse error\n"); } break; case PS_ERROR: parser_print_error(); if ( node != NULL ) { delete_tree(node); node = NULL; } break; } if ( st_token_buf != NULL) { delete_token(st_token_buf); st_token_buf = NULL; } return node; }
cmd_list_item *parse_cmd_list_item(parser_info *pinfo) { cmd_list_item *list_item = make_cmd_list_item(); #ifdef PARSER_DEBUG parser_print_action(pinfo, "parse_cmd_list_item()", 0); #endif list_item->pl = parse_cmd_pipeline(pinfo); if (pinfo->error) goto error; switch (pinfo->cur_lex->type) { case LEX_OR: list_item->rel = REL_OR; break; case LEX_AND: list_item->rel = REL_AND; break; case LEX_SEMICOLON: list_item->rel = REL_BOTH; break; default: list_item->rel = REL_NONE; break; } if (list_item->rel != REL_NONE) parser_get_lex(pinfo); if (pinfo->error) goto error; #ifdef PARSER_DEBUG parser_print_action(pinfo, "parse_cmd_list_item()", 1); #endif return list_item; error: #ifdef PARSER_DEBUG parser_print_error(pinfo, "parse_cmd_list_item()"); #endif free(list_item); return NULL; }
cmd_list *parse_cmd_list(parser_info *pinfo) { int bracket_terminated = 0; int lex_term = 0; cmd_list *list = make_cmd_list(pinfo); cmd_list_item *cur_item = NULL, *tmp_item = NULL; #ifdef PARSER_DEBUG parser_print_action(pinfo, "parse_cmd_list()", 0); #endif if (pinfo->cur_lex != NULL) bracket_terminated = (pinfo->cur_lex->type == LEX_BRACKET_OPEN); parser_get_lex(pinfo); if (pinfo->error) goto error; switch (pinfo->cur_lex->type) { case LEX_EOLINE: case LEX_EOFILE: /* Empty cmd list */ pinfo->error = 16; /* Error 16 */ goto error; default: /* Do nothing */ break; } do { tmp_item = parse_cmd_list_item(pinfo); if (pinfo->error) goto error; if (list->first_item == NULL) list->first_item = cur_item = tmp_item; else cur_item = cur_item->next = tmp_item; switch (pinfo->cur_lex->type) { case LEX_BACKGROUND: case LEX_BRACKET_CLOSE: case LEX_EOLINE: case LEX_EOFILE: lex_term = 1; break; default: pinfo->error = (cur_item->rel == REL_NONE) ? 15 : 0; /* Error 15 */ break; } } while (!lex_term && !pinfo->error); if (pinfo->error) goto error; if (pinfo->cur_lex->type == LEX_BACKGROUND) { pinfo->error = (cur_item->rel == REL_NONE) ? 0 : 13; /* Error 13 */ if (pinfo->error) goto error; list->foreground = 0; parser_get_lex(pinfo); } if (pinfo->error) goto error; switch (pinfo->cur_lex->type) { case LEX_BRACKET_CLOSE: pinfo->error = (bracket_terminated) ? 0 : 5; /* Error 5 */ break; case LEX_EOLINE: case LEX_EOFILE: pinfo->error = (bracket_terminated) ? 6 : 0; /* Error 6 */ break; default: pinfo->error = 14; /* Error 14 */ break; } if (pinfo->error) goto error; pinfo->error = ((cur_item->rel == REL_NONE) || (cur_item->rel == REL_BOTH)) ? 0 : 7; /* Error 7 */ if (pinfo->error) goto error; cur_item->rel = REL_NONE; #ifdef PARSER_DEBUG parser_print_action(pinfo, "parse_cmd_list()", 1); #endif return list; error: #ifdef PARSER_DEBUG parser_print_error(pinfo, "parse_cmd_list()"); #endif destroy_cmd_list(list); return NULL; }
cmd_pipeline *parse_cmd_pipeline(parser_info *pinfo) { cmd_pipeline *pipeline = make_cmd_pipeline(); cmd_pipeline_item *cur_item = NULL, *tmp_item = NULL; #ifdef PARSER_DEBUG parser_print_action(pinfo, "parse_cmd_pipeline()", 0); #endif do { switch (pinfo->cur_lex->type) { case LEX_WORD: tmp_item = parse_cmd_pipeline_item(pinfo); break; case LEX_BRACKET_OPEN: tmp_item = make_cmd_pipeline_item(); tmp_item->cmd_lst = parse_cmd_list(pinfo); if (pinfo->error) { free(tmp_item); goto error; } parser_get_lex(pinfo); break; default: pinfo->error = 4; /* Error 4 */ break; } if (pinfo->error) goto error; if (pipeline->first_item == NULL) { /* First simple cmd */ pipeline->first_item = cur_item = tmp_item; pipeline->input = cur_item->input; cur_item->input = NULL; } else { /* Second and following simple cmd */ cur_item = cur_item->next = tmp_item; pinfo->error = (cur_item->input == NULL) ? 0 : 8; /* Error 8 */ if (pinfo->error) { free(cur_item->input); if (cur_item->output != NULL) free(cur_item->output); goto error; } } if (pinfo->cur_lex->type == LEX_PIPE) { /* Not last simple cmd */ pinfo->error = (cur_item->output == NULL) ? 0 : 9; /* Error 9 */ if (pinfo->error) { free(cur_item->output); if (cur_item->input != NULL) free(cur_item->input); goto error; } parser_get_lex(pinfo); continue; } else { /* Last simple cmd in this pipeline */ pipeline->output = cur_item->output; pipeline->append = cur_item->append; cur_item->output = NULL; cur_item->append = 0; #ifdef PARSER_DEBUG parser_print_action(pinfo, "parse_cmd_pipeline()", 1); #endif return pipeline; } } while (!pinfo->error); error: #ifdef PARSER_DEBUG parser_print_error(pinfo, "parse_cmd_pipeline()"); #endif destroy_cmd_pipeline(pipeline); return NULL; }
cmd_pipeline_item *parse_cmd_pipeline_item(parser_info *pinfo) { cmd_pipeline_item *simple_cmd = make_cmd_pipeline_item(); word_buffer wbuf; new_word_buffer(&wbuf); #ifdef PARSER_DEBUG parser_print_action(pinfo, "parse_cmd_pipeline_item()", 0); #endif do { switch (pinfo->cur_lex->type) { case LEX_WORD: /* Add to word buffer for making argv */ add_to_word_buffer(&wbuf, pinfo->cur_lex->str); pinfo->save_str = 1; parser_get_lex(pinfo); break; case LEX_INPUT: pinfo->error = (simple_cmd->input == NULL) ? 0 : 10; /* Error 10 */ if (pinfo->error) goto error; parser_get_lex(pinfo); /* Lexer error possible */ if (pinfo->error) goto error; pinfo->error = (pinfo->cur_lex->type != LEX_WORD) ? 12 : 0; /* Error 12 */ if (pinfo->error) goto error; simple_cmd->input = pinfo->cur_lex->str; pinfo->save_str = 1; parser_get_lex(pinfo); break; case LEX_OUTPUT: case LEX_APPEND: pinfo->error = (simple_cmd->output == NULL) ? 0 : 11; /* Error 11 */ if (pinfo->error) goto error; simple_cmd->append = (pinfo->cur_lex->type == LEX_OUTPUT) ? 0 : 1; parser_get_lex(pinfo); /* Lexer error possible */ if (pinfo->error) goto error; pinfo->error = (pinfo->cur_lex->type != LEX_WORD) ? 2 : 0; /* Error 2 */ if (pinfo->error) goto error; simple_cmd->output = pinfo->cur_lex->str; pinfo->save_str = 1; parser_get_lex(pinfo); break; default: /* Lexer error possible */ if (pinfo->error) goto error; pinfo->error = (wbuf.count_words == 0) ? 3 : 0; /* Error 3 */ if (pinfo->error) goto error; /* make argv from word buffer */ simple_cmd->argv = convert_to_argv(&wbuf, 1); #ifdef PARSER_DEBUG parser_print_action(pinfo, "parse_cmd_pipeline_item()", 1); #endif return simple_cmd; } } while (!pinfo->error); error: #ifdef PARSER_DEBUG parser_print_error(pinfo, "parse_cmd_pipeline_item()"); #endif clear_word_buffer(&wbuf, 1); if (simple_cmd->input != NULL) free(simple_cmd->input); if (simple_cmd->output != NULL) free(simple_cmd->output); free(simple_cmd); return NULL; }