示例#1
0
void wpl_block_foreach::parse_value(wpl_namespace *ns) {
	set_parent_namespace (ns);

	exp_init.reset(new wpl_expression());

	wpl_expression_par_enclosed *exp = new wpl_expression_par_enclosed();
	run_condition.reset(exp);

	ignore_whitespace();
	if (!ignore_letter ('(')) {
		THROW_ELEMENT_EXCEPTION("Expected '(' in foreach loop definition");
	}

	/*
	   Allow declaration of variables inside init statement
	   */
	find_and_parse_complete_type();

	exp_init->load_position(get_position());
	exp_init->parse_value(this);
	load_position(exp_init->get_position());

	exp->insert_fake_open_par();
	exp->load_position(get_position());
	exp->parse_value(this);
	load_position(exp->get_position());

	get_block()->load_position(get_position());
	get_block()->parse_value(this);
	load_position(get_block()->get_position());
}
示例#2
0
void wpl_block_for::parse_value (wpl_namespace *ns) {
	set_parent_namespace(ns);

	ignore_whitespace();
	if (!ignore_letter ('(')) {
		THROW_ELEMENT_EXCEPTION("Expected '(' in for loop definition");
	}

	exp_init->load_position(get_position());
	exp_init->parse_value(ns);
	load_position(exp_init->get_position());

	exp_condition->load_position(get_position());
	exp_condition->parse_value(ns);
	load_position(exp_condition->get_position());

	// This expression catches the end parantheses ')'
	exp_increment->insert_fake_open_par();
	exp_increment->load_position(get_position());
	exp_increment->parse_value(ns);
	load_position(exp_increment->get_position());

	ignore_blockstart();
	wpl_block::parse_value(this);
}
示例#3
0
static char next_token(char ** ret)
{
	int i = -1, c;
	*ret = NULL;
	
	ignore_whitespace();

	do {
		i++;
		c = getc(stdin);

		if (i % 128 == 0)
			*ret = realloc(*ret, i + 128);

		(*ret)[i] = c;
	}
	while (c != ']' && c != ',' && c != '=' && c != EOF);

	(*ret)[i] = '\0';
	
	while ( i > 0 && isspace( (*ret)[i - 1] )) {
		(*ret)[--i] = '\0';
	}

	return c;
}
示例#4
0
文件: text.cpp 项目: geirda/P-star
void wpl_text::parse_value(wpl_namespace *parent_namespace) {
	ignore_string_match(NEWLINE, NON_NEWLINE_WS);

	const char *start = get_string_pointer();
	const char *end;
	int par_level = 1;
	while (par_level > 0 && !at_end()) {
		end = get_string_pointer();
		if (ignore_letter('{')) {
			if (ignore_string("@LOOP")) {
				push_chunk (start, end);

				wpl_text *text =
					new wpl_text();
				wpl_expression *exp =
					new wpl_expression_par_enclosed();

				chunks.emplace_back(new wpl_text_chunks::loop(text, exp));

				parse_expression(parent_namespace, exp);
				ignore_string_match(NEWLINE, NON_NEWLINE_WS);
				parse_text(parent_namespace, text);

				start = get_string_pointer();
			}
			else if (ignore_string("@CONDITION")) {
				push_chunk (start, end);

				wpl_text *text =
					new wpl_text();
				wpl_expression *exp =
					new wpl_expression_par_enclosed();
				wpl_text *text_else = NULL;

				wpl_text_chunks::condition *condition = new wpl_text_chunks::condition(text, exp);
				chunks.emplace_back(condition);

				parse_expression(parent_namespace, exp);
				ignore_string_match(NEWLINE, NON_NEWLINE_WS);
				parse_text(parent_namespace, text);

				start = get_string_pointer();
			}
			else if (ignore_string("@TEMPLATE")) {
				push_chunk (start, end);

				wpl_matcher_position pos = get_position();

				char name[WPL_VARNAME_SIZE];
				ignore_whitespace();
				get_word(name);

				wpl_template *my_template = parent_namespace->find_template(name);
				if (!my_template) {
					load_position(pos);
					THROW_ELEMENT_EXCEPTION("Unknown template name");
				}

				chunks.emplace_back(new wpl_text_chunks::html_template(my_template));

				ignore_whitespace();
				if (!ignore_letter ('}')) {
					THROW_ELEMENT_EXCEPTION("Expected } after TEMPLATE call definition");
				}

				start = get_string_pointer();
			}
			else if (ignore_string("@")) {
				push_chunk (start, end);

				wpl_expression *exp =
					new wpl_expression_loose_end();
				chunks.emplace_back(new wpl_text_chunks::expression(exp));

				exp->load_position(get_position());
				exp->parse_value(parent_namespace);
				load_position(exp->get_position());

				ignore_string_match(WHITESPACE, 0);
				if (!ignore_letter('}')) {
					THROW_ELEMENT_EXCEPTION("Expected '}' after expression-in-TEXT");
				}

				start = get_string_pointer();
			}
			else {
				par_level++;
			}
		}
		else if (ignore_letter('}')) {
			par_level--;
		}
		else {
			if (!ignore_string_match(NON_CURLY|UTF8, 0)) {
				cerr << "Unknown character '" << hex << get_letter(ALL) << "'\n";
				THROW_ELEMENT_EXCEPTION("Syntax error in text-string");
			}
		}
	}

	if (par_level != 0) {
		THROW_ELEMENT_EXCEPTION("Excepted '}' after TEXT-block");
	}

	end = get_string_pointer() - 2;

	while (M_NON_NEWLINE_WHITESPACE (*end)) {
		end--;
	}
	end++;

	if (end > start) {
		push_chunk (start, end);
	}
}
示例#5
0
void wpl_struct::parse_value(wpl_namespace *ns) {
	char buf[WPL_VARNAME_SIZE];
	wpl_matcher_position begin_pos(get_position());
	ignore_string_match(WHITESPACE,0);

	if (parse_complete) {
		ignore_whitespace();
		if (ignore_letter ('>')) {
			throw wpl_type_end_template_declaration(this);
		}
		try {
			get_word(buf);
		}
		catch (wpl_element_exception &e) {
			cerr << "After struct name '" << get_name() << "':\n";
			throw;
		}
		throw wpl_type_begin_variable_declaration(this, buf, begin_pos);
	}

	/*
	   TODO allow declaration only now and definition later
	 */
	if (!ignore_letter('{')) {
		THROW_ELEMENT_EXCEPTION("Expected block with declarations after struct declaration");
	}

	if (ignore_letter ('}')) {
		goto no_members;
	}

	do {

		get_word(buf);

		wpl_parseable *parseable;
		if (!(parseable = ns->new_find_parseable(buf))) {
			load_position(begin_pos);
			cerr << "While parsing name '" << buf << "' inside struct:\n";
			THROW_ELEMENT_EXCEPTION("Undefined name");
		}

		parseable->load_position(get_position());

		try {
			try {
				parseable->parse_value(this);
			}
			catch (wpl_type_begin_variable_declaration &e) {
				e.create_variable(this);
				load_position(parseable->get_position());
			}
		}
		catch (wpl_type_begin_function_declaration &e) {
			e.parse_value(this);
			load_position(e.get_position());
		}

		ignore_whitespace();
		if (!ignore_letter (';')) {
			THROW_ELEMENT_EXCEPTION("Expected ';' after definition in struct");
		}
		ignore_whitespace();

		if (ignore_letter ('}')) {
			break;
		}
	} while (!at_end());

	no_members:

	parse_complete = true;
	throw wpl_type_end_statement(get_position());
}
示例#6
0
void parse_next(parse_struct * ps)
{
	int type, c, p, d;
	char * tok1 = NULL;
	char * tok2 = NULL;
	parse_struct sub;
	
	ps->owner = 0;
	ps->name = NULL;

	ignore_whitespace();
	p = type = getc(stdin);
	if (type == EOF) {
		ps->valid = 0;
		return;
	}

	ignore_whitespace();
	c = getc(stdin);
	if (c != ':') error(EXPECTED_COLON, &p);
	p = c;

	ignore_whitespace();
	c = getc(stdin);
	if (c != '[') error(EXPECTED_LBRACKET, &p);

	switch (type)
	{
	////////// Parse Branches \\\\\\\\\\/
	case 'b':
		ps->flags = FL_BRANCH;
		ps->u.dir.size = 0;
	
		do {
			if (tok1 != NULL) free(tok1);
			p = d = next_token(&tok1);

			if (tok1[0] == '#') {
				if (strcmp(tok1, "#protected") == 0) ps->flags |= FL_PROTECTED;
				else error(BAD_BRANCH_FLAG, tok1);
			} else {
				if (d != '=') error(EXPECTED_EQUALS, tok1);
				
				ignore_whitespace();

				if (strcmp(tok1, "contents") == 0) {
					c = getc(stdin);
					if (c != '{') error(EXPECTED_LBRACE, NULL);
					
					ps->u.dir.contents = NULL;
					
					while (1) {
						ignore_whitespace();

						c = getc(stdin);
						if (c == EOF) error(UNEXPECTED_EOF, NULL);
						if (c == '}') break;
						ungetc(c, stdin);
						
						parse_next(&sub);
						if (!sub.valid) error(UNEXPECTED_EOF, NULL);
						
						if (ps->u.dir.size % (0x20 * sizeof(parse_struct)) == 0) {
							ps->u.dir.contents = realloc(ps->u.dir.contents,
								ps->u.dir.size + (0x20 * sizeof(parse_struct)));
						}
						
						ps->u.dir.contents[ps->u.dir.size++] = sub;
					}
					
					ignore_whitespace();
					d = getc(stdin);
				} else {
					if (tok2 != NULL) free(tok2);
					d = next_token(&tok2);
					
					if (strcmp(tok1, "name") == 0) {
						ps->name = tok2;
						tok2 = NULL;
					}
					else if (strcmp(tok1, "owner") == 0) {
						ps->owner = atoi(tok2);
					}
					else error(BAD_BRANCH_FIELD, tok1);
				}
			}
		}
		while (p != ']' && d != ']');

		break;

	////////// Parse Files \\\\\\\\\\/
	case 'f':
		ps->flags = 0;

		do {
			if (tok1 != NULL) free(tok1);
			d = next_token(&tok1);

			if (tok1[0] == '#') {
				if (strcmp(tok1, "#protected") == 0) ps->flags |= FL_PROTECTED;
				else if (strcmp(tok1, "#executable") == 0) ps->flags |= FL_EXECUTABLE;
				else error(BAD_FILE_FLAG, tok1);
			} else {
				if (d != '=') error(EXPECTED_EQUALS, tok1);

				if (tok2 != NULL) free(tok2);
				d = next_token(&tok2);
				
				if (strcmp(tok1, "name") == 0) {
					ps->name = tok2;
					tok2 = NULL;
				}
				else if (strcmp(tok1, "owner") == 0) {
					ps->owner = atoi(tok2);
				}
				else if (strcmp(tok1, "actual") == 0) {
					ps->u.actual_file = tok2;
					tok2 = NULL;
				}
				else error(BAD_FILE_FIELD, tok1);
			}
		}
		while (p != ']' && d != ']');
		
		break;

	////////// Parse Indirects \\\\\\\\\\/
	case 'i':
		ps->flags = FL_INDIRECT;

		break;
	
	default:
		error(UNRECOGNIZED_TYPE, &type);
	}
	
	if (tok1 == NULL) free(tok1);
	if (tok2 == NULL) free(tok2);
	
	ps->valid = 1;
}