示例#1
0
文件: analyzer.c 项目: notozeki/mysh
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;
}
示例#2
0
文件: parser.c 项目: Totktonada/shell
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;
}
示例#3
0
文件: parser.c 项目: Totktonada/shell
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;
}
示例#4
0
文件: parser.c 项目: Totktonada/shell
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;
}
示例#5
0
文件: parser.c 项目: Totktonada/shell
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;
}