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()); }
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); }
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; }
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); } }
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()); }
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; }