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 |