| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #ifndef LYTHON_PARSER_ERROR_H | ||
| 2 | #define LYTHON_PARSER_ERROR_H | ||
| 3 | |||
| 4 | #include "ast/nodes.h" | ||
| 5 | #include "dtypes.h" | ||
| 6 | #include "lexer/token.h" | ||
| 7 | #include "printer/error_printer.h" | ||
| 8 | #include "compatibility/compatibility.h" | ||
| 9 | |||
| 10 | namespace lython { | ||
| 11 | |||
| 12 | struct ParsingError { | ||
| 13 | Array<int> expected_tokens; | ||
| 14 | Token received_token; | ||
| 15 | StmtNode* stmt = nullptr; | ||
| 16 | ExprNode* expr = nullptr; | ||
| 17 | Pattern* pat = nullptr; | ||
| 18 | String error_kind; | ||
| 19 | String message; | ||
| 20 | CodeLocation loc; | ||
| 21 | Array<Token> remaining; // Remaining token we have eaten to recover | ||
| 22 | // in practice we just eat all tokens until next line | ||
| 23 | |||
| 24 | Array<Token> line; // Line as a stream of tokens | ||
| 25 | ParsingError(): received_token(dummy()), loc(LOC) {} | ||
| 26 | |||
| 27 | ParsingError(Array<int> expected, Token token, CodeLocation loc_): | ||
| 28 | ✗ | expected_tokens(expected), received_token(token), loc(loc_) {} | |
| 29 | |||
| 30 | ParsingError(Array<int> expected, Token token, Node* obj, CodeLocation loc); | ||
| 31 | }; | ||
| 32 | |||
| 33 | class ParsingException: public LythonException { | ||
| 34 | public: | ||
| 35 | }; | ||
| 36 | |||
| 37 | class EndOfFileError: public ParsingException {}; | ||
| 38 | |||
| 39 | class ParsingErrorPrinter: public BaseErrorPrinter { | ||
| 40 | public: | ||
| 41 | ParsingErrorPrinter(std::ostream& out, class AbstractLexer* lexer = nullptr): | ||
| 42 | 561 | BaseErrorPrinter(out, lexer) // | |
| 43 | 561 | {} | |
| 44 | |||
| 45 | void print(ParsingError const& err); | ||
| 46 | void print_ast(ParsingError const& error, Node* node, CommonAttributes* srcloc); | ||
| 47 | void print_tok(ParsingError const& error, CommonAttributes* srcloc); | ||
| 48 | |||
| 49 | bool with_compiler_code_loc = false; | ||
| 50 | }; | ||
| 51 | |||
| 52 | class SyntaxError: public ParsingException { | ||
| 53 | public: | ||
| 54 | SyntaxError(String const& message = ""): msg(message) {} | ||
| 55 | |||
| 56 | virtual const char* what() const LY_NOEXCEPT { return msg.c_str(); } | ||
| 57 | |||
| 58 | String msg; | ||
| 59 | }; | ||
| 60 | |||
| 61 | String shortprint(Node const* node); | ||
| 62 | Node const* get_parent(Node const* parent); | ||
| 63 | |||
| 64 | void add_wip_expr(ParsingError& err, StmtNode* stmt); | ||
| 65 | void add_wip_expr(ParsingError& err, ExprNode* expr); | ||
| 66 | void add_wip_expr(ParsingError& err, Node* expr); | ||
| 67 | |||
| 68 | // Supresses newlines from a a stream | ||
| 69 | class NoNewLine: public std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char>> { | ||
| 70 | public: | ||
| 71 | NoNewLine(std::ostream& out): out(out) {} | ||
| 72 | |||
| 73 | virtual int sync() { | ||
| 74 |
1/2✓ Branch 1 taken 136 times.
✗ Branch 2 not taken.
|
136 | std::string data = str(); |
| 75 | 136 | int val = int(data.size()); | |
| 76 | |||
| 77 | // this might be too simplistic | ||
| 78 | // what if the new line is in the middle of the expression | ||
| 79 |
2/2✓ Branch 5 taken 3720 times.
✓ Branch 6 taken 136 times.
|
3856 | for (char c: data) { |
| 80 |
2/2✓ Branch 0 taken 151 times.
✓ Branch 1 taken 3569 times.
|
3720 | if (c == '\n') |
| 81 | 151 | continue; | |
| 82 | |||
| 83 |
1/2✓ Branch 1 taken 3569 times.
✗ Branch 2 not taken.
|
3569 | out << c; |
| 84 | } | ||
| 85 | // clear buffer | ||
| 86 |
2/4✓ Branch 2 taken 136 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 136 times.
✗ Branch 6 not taken.
|
136 | str(""); |
| 87 | 136 | return val; | |
| 88 | 136 | } | |
| 89 | |||
| 90 | std::ostream& out; | ||
| 91 | }; | ||
| 92 | |||
| 93 | } // namespace lython | ||
| 94 | |||
| 95 | #endif | ||
| 96 |