示例#1
0
文件: parser.c 项目: fwum/fwum
static statement *parse_func_call(linked_list *tokens) {
	linked_list *accumulator = ll_new();
	linked_iter iterator = ll_iter_head(tokens);
	statement *call = new(call);
	call->type = FUNC_CALL;
	call->data = ((parse_token*)ll_iter_next(&iterator))->data;
	call->children = ll_new();
	int paren_level = 0;
	ll_iter_next(&iterator); //Discard opening parenthesis
	for(parse_token *current = ll_iter_next(&iterator); ll_iter_has_next(&iterator); current = ll_iter_next(&iterator)) {
		if(paren_level == 0 && (equals_string(current->data, ",") || equals_string(current->data, ")"))) {
			statement *parameter = parse_simple_expression(accumulator);
			if(parameter != NULL)
				ll_add_last(call->children, parameter);
			ll_clear(accumulator);
		} else {
			ll_add_last(accumulator, current);
		}
		if(equals_string(current->data, "("))
			paren_level += 1;
		else if(equals_string(current->data, ")"))
			paren_level -= 1;
	}
	statement *parameter = parse_simple_expression(accumulator);
	if(parameter != NULL)
		ll_add_last(call->children, parameter);
	ll_destroy(accumulator);
	return call;
}
示例#2
0
reaver::despayre::expression reaver::despayre::_v1::parse_expression(reaver::despayre::context & ctx)
{
    auto expr = parse_simple_expression(ctx);
    auto peeked = peek(ctx);
    auto start = get<0>(fmap(expr, [](auto && expr){ return expr.range.start(); }));
    if (peeked && (peeked->type == token_type::plus || peeked->type == token_type::minus))
    {
        auto operations = parse_operations(ctx);
        return expression{ range_type{ start, operations.back().range.end() }, std::move(expr), std::move(operations) };
    }

    auto end = get<0>(fmap(expr, [](auto && expr){ return expr.range.end(); }));
    return expression{ range_type{ start, end }, std::move(expr), {} };
}
示例#3
0
std::vector<reaver::despayre::operation> reaver::despayre::_v1::parse_operations(reaver::despayre::context & ctx)
{
    auto peeked = peek(ctx);

    std::vector<operation> operations;
    while (peeked && (peeked->type == token_type::plus || peeked->type == token_type::minus))
    {
        operation_type operation = expect(ctx, peeked->type).type == token_type::plus ? operation_type::addition : operation_type::removal;
        auto operand = parse_simple_expression(ctx);
        auto end = get<0>(fmap(operand, [](auto && op){ return op.range.end(); }));
        operations.push_back({ range_type{ peeked->range.start(), end }, operation, std::move(operand) });

        peeked = peek(ctx);
    }

    return operations;
}
示例#4
0
文件: parser.c 项目: fwum/fwum
static statement *parse_array_index(linked_list *tokens) {
	statement *index = new(index);
	index->type = OP_INDEX;
	index->data = new_slice("");
	index->children = ll_new();
	statement *name = new(name);
	name->type = NAME;
	name->data = ((parse_token*)ll_get_first(tokens))->data;
	name->children = NULL;
	ll_add_first(index->children, name);
	linked_list *inside_list = ll_duplicate(tokens);
	ll_remove_first(inside_list); //Remove name
	ll_remove_first(inside_list); //Remove [
	ll_remove_last(inside_list); //Remove ]
	statement *inside = parse_simple_expression(inside_list);
	ll_destroy(inside_list);
	ll_add_last(index->children, inside);
	return index;
}
示例#5
0
文件: parser.c 项目: fwum/fwum
static statement *parse_simple_expression(linked_list *tokens) {
	while(equals_string(((parse_token*)ll_get_first(tokens))->data, "(") && equals_string(((parse_token*)ll_get_last(tokens))->data, ")")) {
		ll_remove_first(tokens);
		ll_remove_last(tokens);
	}
	int size = ll_size(tokens);
	switch(size) {
	case 0:
		return NULL;
	case 1:
		return parse_single_token(tokens);
	default: {
		if(size == 2) {
			parse_token *token = ll_get_first(tokens);
			bool isStack;
	        if((isStack = equals_string(token->data, "new")) || equals_string(token->data, "newref")) {
	            statement *expression = new(expression);
	            expression->children = ll_new();
	            expression->type = isStack ? STACK_INIT : HEAP_INIT;
	            linked_list *name = ll_duplicate(tokens);
	            ll_remove_first(name);
	            ll_add_first(expression->children, parse_simple_expression(name));
	            return expression;
	        }
		}
		int paren_level = 1;
		linked_iter iterator = ll_iter_head(tokens);
		bool is_index = true, is_call = true;
		ll_iter_next(&iterator);
		parse_token *second = ll_iter_next(&iterator);
		if(equals_string(second->data, "(")) {
			is_index = false;
		} else if(equals_string(second->data, "[")) {
			is_call = false;
		} else {
			is_index = is_call = false;
		}
		while((is_index || is_call) && ll_iter_has_next(&iterator)) {
			parse_token *token = ll_iter_next(&iterator);
			if(equals_string(token->data, "(") || equals_string(token->data, "[")) {
				paren_level += 1;
			} else if(paren_level == 0) {
				is_index = false;
				is_call = false;
			} else if(equals_string(token->data, ")") || equals_string(token->data, "]")) {
				paren_level -= 1;
			}
		}
		if(is_index) {
			return parse_array_index(tokens);
		} else if(is_call) {
			return parse_func_call(tokens);
		}
		linked_list *operator = get_node();
		linked_iter level = ll_iter_head(operator);
		while(ll_iter_has_next(&level)) {
			int paren_level = 0;
			linked_list *currentLevel = ll_iter_next(&level);
			linked_iter iterator = ll_iter_head(tokens);
			for(parse_token *current = ll_iter_next(&iterator); ll_iter_has_next(&iterator); current = ll_iter_next(&iterator)) {
				char currentChar = current->data.data[0];
				if(currentChar == '(') {
					paren_level += 1;
				} else if(currentChar == ')') {
					paren_level -= 1;
				}
				if(paren_level != 0) continue;
				linked_iter innerMost = ll_iter_head(currentLevel);
				while(ll_iter_has_next(&innerMost)) {
					operator_node *currentOperator = ll_iter_next(&innerMost);
					if(equals_string(current->data, currentOperator->data)) {
						if(!is_unary_operator(new_slice(currentOperator->data))) {
							linked_list *op1 = ll_duplicate(tokens);
							while(ll_get_last(op1) != current)
								ll_remove_last(op1);
							ll_remove_last(op1);
							linked_list *op2 = tokens;
							while(ll_get_first(op2) != current)
								ll_remove_first(op2);
							ll_remove_first(op2);
							statement *expression = new(expression);
							expression->data = new_slice("");
							expression->children = ll_new();
							expression->type = currentOperator->operatorType;
							statement *op1_exp = parse_simple_expression(op1);
							statement *op2_exp = parse_simple_expression(op2);
							ll_add_last(expression->children, op1_exp);
							ll_add_last(expression->children, op2_exp);
							return expression;
						} else {
							statement *expression = new(expression);
							expression->data = new_slice(currentOperator->data);
							expression->type = currentOperator->operatorType;
							linked_list *rest = ll_duplicate(tokens);
							ll_remove_first(rest);
							expression->children = ll_new();
							ll_add_first(expression->children, parse_simple_expression(rest));
							return expression;
						}
					}
				}
			}
		}
		return NULL;
		}
	}
}
示例#6
0
文件: parser.c 项目: fwum/fwum
static statement *get_expression(parse_source *source, int *indent) {
	parse_token token = get_mandatory_token(source);
	if(equals_string(token.data, "{")) {
		statement *expression = new(expression);
		expression->type = BLOCK;
		expression->children = ll_new();
		expression->data = new_slice("");
		int finished = *indent;
		*indent += 1;
		while(*indent != finished) {
			statement *state = get_expression(source, indent);
			if(state != NULL)
				ll_add_last(expression->children, state);
		}
		return expression;
	} else if(equals_string(token.data, "}")) {
		*indent -= 1;
		return NULL;
	} else if(equals_string(token.data, "if") || equals_string(token.data, "while") || equals_string(token.data, "for")) {
		statement *expression = new(expression);
		if(equals_string(token.data, "if"))
			expression->type = IF;
		else if(equals_string(token.data, "while"))
			expression->type = WHILE;
		else if(equals_string(token.data, "for"))
			expression->type = FOR;
		expression->children = ll_new();
		expression->data = new_slice("");
		ll_add_last(expression->children, get_expression(source, indent)); //Add the header
        if(expression->type == FOR) {
            ll_add_last(expression->children, get_expression(source, indent)); //Add the header
            ll_add_last(expression->children, get_expression(source, indent)); //Add the header
        }
		ll_add_last(expression->children, get_expression(source, indent)); //Add the body
		if(expression->type == IF) {
			parse_token next = peek_mandatory_token(source);
			if(equals_string(next.data, "else")) {
				get_mandatory_token(source);
				statement *elseState = new(elseState);
				elseState->type = ELSE;
				elseState->children = ll_new();
				elseState->data = new_slice("");
				ll_add_last(expression->children, elseState);
				ll_add_first(elseState->children, get_expression(source, indent));
			}
		}
		return expression;
	} else if(equals_string(token.data, "break") || equals_string(token.data, "continue")) {
		statement *expression = new(expression);
		expression->type = equals_string(token.data, "break") ? BREAK : CONTINUE;
		expression->data = new_slice("");
		expression->children = NULL;
		parse_token next = get_mandatory_token(source);
		if(!equals_string(next.data, ";"))
			semantic_error("Expected a semicolon after a break or continue", next.origin);
		return expression;
	} else if(equals_string(token.data, "return")) {
		statement *expression = new(expression);
		expression->type = RETURN;
		expression->data = new_slice("");
		expression->children = ll_new();
		ll_add_last(expression->children, get_expression(source, indent));
		return expression;
	} else {
		linked_list *accumulator = ll_new();
		parse_token next = token;
		while(true) {
			parse_token *allocated = new(allocated);
			*allocated = token;
			ll_add_last(accumulator, allocated);
			next = peek_mandatory_token(source);
			if(equals_string(next.data, "{") || equals_string(next.data, "}"))
				break;
			if(equals_string(next.data, ";")) {
				get_mandatory_token(source);
				break;
			}
			token = get_mandatory_token(source);
		}
		statement *expression = parse_simple_expression(accumulator);
		ll_delete_all(accumulator);
		return expression;
	}
}