From 61c37144043df7047f17d7ee9357e913d9fc3a04 Mon Sep 17 00:00:00 2001 From: Lephenixnoir Date: Wed, 23 Aug 2023 15:39:23 +0200 Subject: [PATCH] shell: fix syntax error + autocompletion exception Somehow there were two types of syntax errors, and the autocompletion code was not catching the correct one. --- shell/i.cpp | 3 ++- shell/lexer.l | 17 +++++++++++------ shell/main.cpp | 3 ++- shell/parser.cpp | 9 ++++----- shell/parser.h | 8 ++------ 5 files changed, 21 insertions(+), 19 deletions(-) diff --git a/shell/i.cpp b/shell/i.cpp index 1cb80b1..6b7ca93 100644 --- a/shell/i.cpp +++ b/shell/i.cpp @@ -443,7 +443,8 @@ marked as part of functions, data, interrupt handlers, etc. )"); static ShellCommand _if_cmd( - "if", [](Session &s, Parser &p) { + "if", + [](Session &s, Parser &p) { auto args = parse_if(s, p); _if(s, args); }, diff --git a/shell/lexer.l b/shell/lexer.l index 971a38b..d586d15 100644 --- a/shell/lexer.l +++ b/shell/lexer.l @@ -94,7 +94,7 @@ static bool lex_pop() } /* Error messages and exceptions */ -static void err(char const *format, ...) +void lex_err(char const *format, ...) { static char buf[1024]; @@ -103,8 +103,13 @@ static void err(char const *format, ...) vsnprintf(buf, 1024, format, args); va_end(args); - Input const &in = lex_current_input(); - throw SyntaxError(in.filename.c_str(), in.line, buf); + if(lex_idle()) { + throw SyntaxError("(idle)", 0, buf); + } + else { + Input const &in = lex_current_input(); + throw SyntaxError(in.filename.c_str(), in.line, buf); + } } /* Parse numerical values */ @@ -194,9 +199,9 @@ space [ \t]+ <*>"?" { return '?'; } /* Generic error and word boundaries violations */ -<*>{syscall}{letter} { err("invalid syscall number '%s'", yytext); } -<*>{num}{letter} { err("invalid numerical value '%s'", yytext); } -<*>. { err("invalid token near '%s'", yytext); } +<*>{syscall}{letter} { lex_err("invalid syscall number '%s'", yytext); } +<*>{num}{letter} { lex_err("invalid numerical value '%s'", yytext); } +<*>. { lex_err("invalid token near '%s'", yytext); } <> { if(lex_pop()) return T::END; } %% diff --git a/shell/main.cpp b/shell/main.cpp index 07821f7..a52e45a 100644 --- a/shell/main.cpp +++ b/shell/main.cpp @@ -15,6 +15,7 @@ #include "shell.h" #include "theme.h" #include "parser.h" +#include "errors.h" #include "commands.h" #include #include @@ -106,7 +107,7 @@ Parser::CompletionRequest parse_until_autocomplete( catch(Parser::CompletionRequest r) { return r; } - catch(Parser::SyntaxError &e) { + catch(SyntaxError &e) { /* Ignore syntax errors, just don't autocomplete */ } diff --git a/shell/parser.cpp b/shell/parser.cpp index d4d4574..7a5953e 100644 --- a/shell/parser.cpp +++ b/shell/parser.cpp @@ -107,7 +107,7 @@ void Parser::end() { m_options.clear(); if(!at_end()) - throw SyntaxError("expected end of command"); + lex_err("expected end of command"); } void Parser::exhaust() @@ -166,16 +166,15 @@ Token Parser::expect(std::initializer_list types, bool ignore_spaces) if(!correct_type) { static char err[128]; - int offset = sprintf(err, "expected "); + int offset = 0; for(auto it = types.begin(); it != types.end(); it++) { offset += sprintf(err + offset, "%s%s%s", (it != types.begin() && it + 1 == types.end() ? "or " : ""), - (*it).str().c_str(), (it + 1 == types.end() ? "; " : ", ")); + (*it).str().c_str(), (it + 1 == types.end() ? "" : ", ")); } - sprintf(err + offset, "instead found %s", m_la.str().c_str()); - throw SyntaxError(err); + lex_err("expected %s; instead found %s", err, m_la.str().c_str()); } Token t = feed(ignore_spaces); diff --git a/shell/parser.h b/shell/parser.h index 693df9f..9887029 100644 --- a/shell/parser.h +++ b/shell/parser.h @@ -95,6 +95,8 @@ void lex_repl(std::string input); /* Lex the input coming from these files, sequentially */ void lex_include(std::vector files); +/* For the parser: format and throw a syntax error at current location */ +void lex_err(char const *format, ...); /* For the parser: get one token from the current source */ Token lex_read(); @@ -166,12 +168,6 @@ public: // Completion system //--- - class SyntaxError: public std::invalid_argument - { - public: - SyntaxError(char const *what): std::invalid_argument(what) {} - }; - /* A completion request is thrown by the parser when in completion mode to signal the expected next element */ struct CompletionRequest