Clean up some error handling

This commit is contained in:
ridiculousfish 2013-07-28 15:44:09 -07:00
parent b133137a1f
commit 680ac41bb1
3 changed files with 34 additions and 33 deletions

View file

@ -30,6 +30,9 @@ static bool production_is_valid(const production_options_t production_list, prod
#define RESOLVE(sym) static production_option_idx_t resolve_##sym (parse_token_type_t token_type, parse_keyword_t token_keyword, production_tag_t *tag)
#define RESOLVE_ONLY(sym) static production_option_idx_t resolve_##sym (parse_token_type_t token_type, parse_keyword_t token_keyword, production_tag_t *tag) { return 0; }
#define PRODUCE_KEYWORD(x) ((x) + LAST_TOKEN_OR_SYMBOL + 1)
/* A job_list is a list of jobs, separated by semicolons or newlines */
PRODUCTIONS(job_list) =
{
@ -409,7 +412,7 @@ RESOLVE(optional_background)
}
#define TEST(sym) case (symbol_##sym): production_list = & productions_ ## sym ; resolver = resolve_ ## sym ; break;
const production_t *parse_productions::production_for_token(parse_token_type_t node_type, parse_token_type_t input_type, parse_keyword_t input_keyword, production_option_idx_t *out_which_production, production_tag_t *out_tag)
const production_t *parse_productions::production_for_token(parse_token_type_t node_type, parse_token_type_t input_type, parse_keyword_t input_keyword, production_option_idx_t *out_which_production, production_tag_t *out_tag, wcstring *out_error_text)
{
bool log_it = false;
if (log_it)
@ -477,8 +480,11 @@ const production_t *parse_productions::production_for_token(parse_token_type_t n
if (which == NO_PRODUCTION)
{
if (log_it)
{
fprintf(stderr, "Token type '%ls' has no production for input type '%ls', keyword '%ls' (in %s)\n", token_type_description(node_type).c_str(), token_type_description(input_type).c_str(), keyword_description(input_keyword).c_str(), __FUNCTION__);
}
result = NULL;
}
else

View file

@ -23,6 +23,13 @@ typedef uint8_t production_element_t;
/* An index into a production option list */
typedef uint8_t production_option_idx_t;
/* A production is an array of production elements */
typedef production_element_t const production_t[MAX_SYMBOLS_PER_PRODUCTION];
/* A production options is an array of (possible) productions */
typedef production_t production_options_t[MAX_PRODUCTIONS];
/* Resolve the type from a production element */
inline parse_token_type_t production_element_type(production_element_t elem)
{
if (elem > LAST_TOKEN_OR_SYMBOL)
@ -35,6 +42,7 @@ inline parse_token_type_t production_element_type(production_element_t elem)
}
}
/* Resolve the keyword from a production element */
inline parse_keyword_t production_element_keyword(production_element_t elem)
{
if (elem > LAST_TOKEN_OR_SYMBOL)
@ -48,19 +56,14 @@ inline parse_keyword_t production_element_keyword(production_element_t elem)
}
}
/* Check if an element is valid */
inline bool production_element_is_valid(production_element_t elem)
{
return elem != token_type_invalid;
}
typedef production_element_t const production_t[MAX_SYMBOLS_PER_PRODUCTION];
typedef production_t production_options_t[MAX_PRODUCTIONS];
#define PRODUCE_KEYWORD(x) ((x) + LAST_TOKEN_OR_SYMBOL + 1)
const production_t *production_for_token(parse_token_type_t node_type, parse_token_type_t input_type, parse_keyword_t input_keyword, production_option_idx_t *out_idx, production_tag_t *out_tag);
/* Fetch a production */
const production_t *production_for_token(parse_token_type_t node_type, parse_token_type_t input_type, parse_keyword_t input_keyword, production_option_idx_t *out_idx, production_tag_t *out_tag, wcstring *out_error_text);
}

View file

@ -14,7 +14,7 @@ wcstring parse_error_t::describe(const wcstring &src) const
// Look for a newline prior to source_start. If we don't find one, start at the beginning of the string; otherwise start one past the newline
size_t newline = src.find_last_of(L'\n', source_start);
fprintf(stderr, "newline: %lu, source_start %lu, source_length %lu\n", newline, source_start, source_length);
//fprintf(stderr, "newline: %lu, source_start %lu, source_length %lu\n", newline, source_start, source_length);
if (newline != wcstring::npos)
{
line_start = newline;// + 1;
@ -26,7 +26,7 @@ wcstring parse_error_t::describe(const wcstring &src) const
line_end = src.size();
}
assert(line_end >= line_start);
fprintf(stderr, "source start: %lu, line start %lu\n", source_start, line_start);
//fprintf(stderr, "source start: %lu, line start %lu\n", source_start, line_start);
assert(source_start >= line_start);
// Append the line of text
@ -320,8 +320,6 @@ class parse_ll_t
void accept_token(parse_token_t token, const wcstring &src);
void token_unhandled(parse_token_t token, const char *function);
void parse_error(const wchar_t *expected, parse_token_t token);
void parse_error(parse_token_t token, const wchar_t *format, ...);
void append_error_callout(wcstring &error_message, parse_token_t token);
@ -455,18 +453,6 @@ void parse_ll_t::dump_stack(void) const
}
}
void parse_ll_t::token_unhandled(parse_token_t token, const char *function)
{
fprintf(stderr, "Unhandled token with type %ls in function %s\n", token_type_description(token.type).c_str(), function);
this->dump_stack();
parse_error_t err;
err.text = format_string(L"Unhandled token with type %ls in function %s", token_type_description(token.type).c_str(), function);
err.source_start = token.source_start;
err.source_length = token.source_length;
this->errors.push_back(err);
this->fatal_errored = true;
}
void parse_ll_t::parse_error(parse_token_t token, const wchar_t *fmt, ...)
{
this->dump_stack();
@ -551,13 +537,19 @@ void parse_ll_t::accept_token(parse_token_t token, const wcstring &src)
// Get the production for the top of the stack
parse_stack_element_t &stack_elem = symbol_stack.back();
parse_node_t &node = nodes.at(stack_elem.node_idx);
const production_t *production = production_for_token(stack_elem.type, token.type, token.keyword, &node.production_idx, &node.tag);
PARSE_ASSERT(production != NULL);
const production_t *production = production_for_token(stack_elem.type, token.type, token.keyword, &node.production_idx, &node.tag, NULL /* error text */);
if (production == NULL)
{
this->parse_error(token, L"Unable to produce a '%ls' from input '%ls'", stack_elem.describe().c_str(), token.describe().c_str());
// parse_error sets fatal_errored, which ends the loop
}
else
{
// Manipulate the symbol stack.
// Note that stack_elem is invalidated by popping the stack.
symbol_stack_pop_push_production(production);
}
}
}
parse_t::parse_t() : parser(new parse_ll_t())
@ -632,7 +624,7 @@ bool parse_t::parse(const wcstring &str, parse_node_tree_t *output, parse_error_
break;
}
wcstring result = L"";//dump_tree(this->parser->nodes, str);
wcstring result = dump_tree(this->parser->nodes, str);
fprintf(stderr, "Tree (%ld nodes):\n%ls", this->parser->nodes.size(), result.c_str());
fprintf(stderr, "%lu nodes, node size %lu, %lu bytes\n", this->parser->nodes.size(), sizeof(parse_node_t), this->parser->nodes.size() * sizeof(parse_node_t));