mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-13 05:28:49 +00:00
Clean up some error handling
This commit is contained in:
parent
b133137a1f
commit
680ac41bb1
3 changed files with 34 additions and 33 deletions
|
@ -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)
|
||||
|
@ -478,7 +481,10 @@ const production_t *parse_productions::production_for_token(parse_token_type_t n
|
|||
|
||||
if (which == NO_PRODUCTION)
|
||||
{
|
||||
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__);
|
||||
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
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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,12 +537,18 @@ 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);
|
||||
|
||||
// Manipulate the symbol stack.
|
||||
// Note that stack_elem is invalidated by popping the stack.
|
||||
symbol_stack_pop_push_production(production);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
||||
|
|
Loading…
Reference in a new issue