mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-13 13:39:02 +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(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 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 */
|
/* A job_list is a list of jobs, separated by semicolons or newlines */
|
||||||
PRODUCTIONS(job_list) =
|
PRODUCTIONS(job_list) =
|
||||||
{
|
{
|
||||||
|
@ -409,7 +412,7 @@ RESOLVE(optional_background)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TEST(sym) case (symbol_##sym): production_list = & productions_ ## sym ; resolver = resolve_ ## sym ; break;
|
#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;
|
bool log_it = false;
|
||||||
if (log_it)
|
if (log_it)
|
||||||
|
@ -478,7 +481,10 @@ const production_t *parse_productions::production_for_token(parse_token_type_t n
|
||||||
|
|
||||||
if (which == NO_PRODUCTION)
|
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;
|
result = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -23,6 +23,13 @@ typedef uint8_t production_element_t;
|
||||||
/* An index into a production option list */
|
/* An index into a production option list */
|
||||||
typedef uint8_t production_option_idx_t;
|
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)
|
inline parse_token_type_t production_element_type(production_element_t elem)
|
||||||
{
|
{
|
||||||
if (elem > LAST_TOKEN_OR_SYMBOL)
|
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)
|
inline parse_keyword_t production_element_keyword(production_element_t elem)
|
||||||
{
|
{
|
||||||
if (elem > LAST_TOKEN_OR_SYMBOL)
|
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)
|
inline bool production_element_is_valid(production_element_t elem)
|
||||||
{
|
{
|
||||||
return elem != token_type_invalid;
|
return elem != token_type_invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef production_element_t const production_t[MAX_SYMBOLS_PER_PRODUCTION];
|
/* 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);
|
||||||
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);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
// 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);
|
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)
|
if (newline != wcstring::npos)
|
||||||
{
|
{
|
||||||
line_start = newline;// + 1;
|
line_start = newline;// + 1;
|
||||||
|
@ -26,7 +26,7 @@ wcstring parse_error_t::describe(const wcstring &src) const
|
||||||
line_end = src.size();
|
line_end = src.size();
|
||||||
}
|
}
|
||||||
assert(line_end >= line_start);
|
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);
|
assert(source_start >= line_start);
|
||||||
|
|
||||||
// Append the line of text
|
// Append the line of text
|
||||||
|
@ -320,8 +320,6 @@ class parse_ll_t
|
||||||
|
|
||||||
void accept_token(parse_token_t token, const wcstring &src);
|
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(const wchar_t *expected, parse_token_t token);
|
||||||
void parse_error(parse_token_t token, const wchar_t *format, ...);
|
void parse_error(parse_token_t token, const wchar_t *format, ...);
|
||||||
void append_error_callout(wcstring &error_message, parse_token_t token);
|
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, ...)
|
void parse_ll_t::parse_error(parse_token_t token, const wchar_t *fmt, ...)
|
||||||
{
|
{
|
||||||
this->dump_stack();
|
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
|
// Get the production for the top of the stack
|
||||||
parse_stack_element_t &stack_elem = symbol_stack.back();
|
parse_stack_element_t &stack_elem = symbol_stack.back();
|
||||||
parse_node_t &node = nodes.at(stack_elem.node_idx);
|
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);
|
const production_t *production = production_for_token(stack_elem.type, token.type, token.keyword, &node.production_idx, &node.tag, NULL /* error text */);
|
||||||
PARSE_ASSERT(production != NULL);
|
if (production == NULL)
|
||||||
|
{
|
||||||
// Manipulate the symbol stack.
|
this->parse_error(token, L"Unable to produce a '%ls' from input '%ls'", stack_elem.describe().c_str(), token.describe().c_str());
|
||||||
// Note that stack_elem is invalidated by popping the stack.
|
// parse_error sets fatal_errored, which ends the loop
|
||||||
symbol_stack_pop_push_production(production);
|
}
|
||||||
|
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;
|
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, "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));
|
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