Improved error reporting in the expression parser
Fixes 15A80F68-F233-49D9-AF0C-9908BB6903BA
This commit is contained in:
parent
3e1ec40551
commit
a3482606dc
4 changed files with 45 additions and 23 deletions
|
|
@ -79,9 +79,7 @@ expr_t::parser_t::parse_value_term(std::istream& in,
|
|||
case token_t::LPAREN:
|
||||
node = parse_value_expr(in, tflags.plus_flags(PARSE_PARTIAL)
|
||||
.minus_flags(PARSE_SINGLE));
|
||||
tok = next_token(in, tflags);
|
||||
if (tok.kind != token_t::RPAREN)
|
||||
tok.expected(')');
|
||||
tok = next_token(in, tflags, ')');
|
||||
|
||||
if (node->kind == op_t::O_CONS) {
|
||||
ptr_op_t prev(node);
|
||||
|
|
@ -383,10 +381,7 @@ expr_t::parser_t::parse_querycolon_expr(std::istream& in,
|
|||
throw_(parse_error,
|
||||
_("%1 operator not followed by argument") << tok.symbol);
|
||||
|
||||
token_t& next_tok = next_token(in, tflags.plus_flags(PARSE_OP_CONTEXT));
|
||||
if (next_tok.kind != token_t::COLON)
|
||||
next_tok.expected(':');
|
||||
|
||||
next_token(in, tflags.plus_flags(PARSE_OP_CONTEXT), ':');
|
||||
prev = node->right();
|
||||
ptr_op_t subnode = new op_t(op_t::O_COLON);
|
||||
subnode->set_left(prev);
|
||||
|
|
|
|||
|
|
@ -52,11 +52,12 @@ class expr_t::parser_t : public noncopyable
|
|||
mutable token_t lookahead;
|
||||
mutable bool use_lookahead;
|
||||
|
||||
token_t& next_token(std::istream& in, const parse_flags_t& tflags) const {
|
||||
token_t& next_token(std::istream& in, const parse_flags_t& tflags,
|
||||
const char expecting = '\0') const {
|
||||
if (use_lookahead)
|
||||
use_lookahead = false;
|
||||
else
|
||||
lookahead.next(in, tflags);
|
||||
lookahead.next(in, tflags, expecting);
|
||||
return lookahead;
|
||||
}
|
||||
|
||||
|
|
|
|||
47
src/token.cc
47
src/token.cc
|
|
@ -138,7 +138,8 @@ void expr_t::token_t::parse_ident(std::istream& in)
|
|||
value.set_string(buf);
|
||||
}
|
||||
|
||||
void expr_t::token_t::next(std::istream& in, const parse_flags_t& pflags)
|
||||
void expr_t::token_t::next(std::istream& in, const parse_flags_t& pflags,
|
||||
const char expecting)
|
||||
{
|
||||
if (in.eof()) {
|
||||
kind = TOK_EOF;
|
||||
|
|
@ -423,6 +424,13 @@ void expr_t::token_t::next(std::istream& in, const parse_flags_t& pflags)
|
|||
expected('\0', c);
|
||||
|
||||
parse_ident(in);
|
||||
|
||||
if (value.as_string().length() == 0) {
|
||||
kind = ERROR;
|
||||
symbol[0] = c;
|
||||
symbol[1] = '\0';
|
||||
unexpected(expecting);
|
||||
}
|
||||
} else {
|
||||
kind = VALUE;
|
||||
value = temp;
|
||||
|
|
@ -447,21 +455,38 @@ void expr_t::token_t::rewind(std::istream& in)
|
|||
}
|
||||
|
||||
|
||||
void expr_t::token_t::unexpected()
|
||||
void expr_t::token_t::unexpected(const char wanted)
|
||||
{
|
||||
kind_t prev_kind = kind;
|
||||
|
||||
kind = ERROR;
|
||||
|
||||
switch (prev_kind) {
|
||||
case TOK_EOF:
|
||||
throw_(parse_error, _("Unexpected end of expression"));
|
||||
case IDENT:
|
||||
throw_(parse_error, _("Unexpected symbol '%1'") << value);
|
||||
case VALUE:
|
||||
throw_(parse_error, _("Unexpected value '%1'") << value);
|
||||
default:
|
||||
throw_(parse_error, _("Unexpected token '%1'") << symbol);
|
||||
if (wanted == '\0') {
|
||||
switch (prev_kind) {
|
||||
case TOK_EOF:
|
||||
throw_(parse_error, _("Unexpected end of expression"));
|
||||
case IDENT:
|
||||
throw_(parse_error, _("Unexpected symbol '%1'") << value);
|
||||
case VALUE:
|
||||
throw_(parse_error, _("Unexpected value '%1'") << value);
|
||||
default:
|
||||
throw_(parse_error, _("Unexpected expression token '%1'") << symbol);
|
||||
}
|
||||
} else {
|
||||
switch (prev_kind) {
|
||||
case TOK_EOF:
|
||||
throw_(parse_error,
|
||||
_("Unexpected end of expression (wanted '%1')" << wanted));
|
||||
case IDENT:
|
||||
throw_(parse_error,
|
||||
_("Unexpected symbol '%1' (wanted '%2')") << value << wanted);
|
||||
case VALUE:
|
||||
throw_(parse_error,
|
||||
_("Unexpected value '%1' (wanted '%2')") << value << wanted);
|
||||
default:
|
||||
throw_(parse_error, _("Unexpected expression token '%1' (wanted '%2')")
|
||||
<< symbol << wanted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -124,10 +124,11 @@ struct expr_t::token_t : public noncopyable
|
|||
|
||||
int parse_reserved_word(std::istream& in);
|
||||
void parse_ident(std::istream& in);
|
||||
void next(std::istream& in, const parse_flags_t& flags);
|
||||
void next(std::istream& in, const parse_flags_t& flags,
|
||||
const char expecting = '\0');
|
||||
void rewind(std::istream& in);
|
||||
void unexpected();
|
||||
void expected(char wanted, char c = '\0');
|
||||
void unexpected(const char wanted = '\0');
|
||||
void expected(const char wanted, char c = '\0');
|
||||
};
|
||||
|
||||
} // namespace ledger
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue