25
25
26
26
#include < functional>
27
27
#include < limits>
28
+ #include < unordered_map>
28
29
#include < utility>
30
+ #include " ast.h"
29
31
#include " basic/bitset.h"
30
32
#include " basic/exception.h"
31
33
#include " basic/mem.h"
37
39
namespace lps ::parser {
38
40
39
41
namespace details {
40
-
41
42
class Context {
42
43
public:
43
44
friend class ContextTrait ;
45
+ static constexpr basic::mem::TraceTag::tag_type kTag = " Context" ;
44
46
using executed_func_type = std::function<void (Context*)>;
45
47
void with (const executed_func_type& func) { func (this ); }
46
48
token::TokenLists& token_lists () { return token_lists_; }
@@ -49,10 +51,128 @@ class Context {
49
51
size_t len_from_start (const token::Token& cur_token) {
50
52
return token_lists_.len (start_token_, cur_token);
51
53
}
54
+ void paint (size_t calling_depth, const token::Token& start,
55
+ const token::Token& end, ParseFunctionKind kind,
56
+ token::details::TokenKind token_kind =
57
+ token::details::TokenKind::unknown) {
58
+ lps_assert (kTag , token_lists_.has (start) && token_lists_.has (end));
59
+ const auto * p_start = &token_lists_.at (start);
60
+ const auto * p_end = &token_lists_.at (end);
61
+ if (path_.contains (p_start)) {
62
+ for (const auto & line : path_[p_start]) {
63
+ if (line.end_ == p_end && line.kind_ == kind) {
64
+ return ;
65
+ }
66
+ }
67
+ }
68
+ path_[p_start].append ({p_start, p_end, kind, token_kind,
69
+ token::TokenLists::len (p_start, p_end),
70
+ calling_depth});
71
+ }
72
+
73
+ Line longest_line (const auto & start) {
74
+ size_t max_l = 0 ;
75
+ const auto * p_start = &token_lists_.at (start);
76
+ auto cmp = [](size_t a, size_t b) {
77
+ return a > b;
78
+ };
79
+ return find_line<cmp>(p_start, max_l);
80
+ }
81
+
82
+ Line shortest_line (const token::Token& start) {
83
+ size_t min_l = std::numeric_limits<size_t >::max ();
84
+ const auto * p_start = &token_lists_.at (start);
85
+ auto cmp = [](size_t a, size_t b) {
86
+ return a < b;
87
+ };
88
+ return find_line<cmp>(p_start, min_l);
89
+ }
90
+
91
+ Tree l2t (const Line& root_line) { // tree to line
92
+ Tree tree;
93
+ auto l2t_impl = [this , &tree](const Line& root_line) -> bool {
94
+ auto run = [this , &tree](Tree::Node& root, const Line& root_line,
95
+ auto func) -> bool {
96
+ const auto * tmp_start = root_line.start_ ;
97
+ if (!path_.contains (tmp_start)) {
98
+ return false ;
99
+ }
100
+ basic::Vector<8 , Tree::Node> ns;
101
+ for (const auto & l0 : path_[root_line.start_ ]) {
102
+ if (l0.calling_depth_ == root_line.calling_depth_ - 1 ) {
103
+ do {
104
+ bool flg = false ;
105
+ for (const auto & l : path_[tmp_start]) {
106
+ if (l.calling_depth_ == root_line.calling_depth_ - 1 ) {
107
+ tmp_start = l.end_ ;
108
+ flg = true ;
109
+ break ;
110
+ }
111
+ }
112
+ if (!flg || !path_.contains (tmp_start)) {
113
+ break ;
114
+ }
115
+ } while (tmp_start != root_line.end_ );
116
+ }
117
+ }
118
+ // for (const auto& l : path_[root_line.start_]) {
119
+ // if (l.calling_depth_ == root_line.calling_depth_ - 1) {
120
+ // Tree::Node n;
121
+ // n.line_ = l;
122
+ // do {
123
+ // if (func(n, l, func)) {
124
+ // if ((!ns.empty() && ns.back().line_.end_ == l.start_) ||
125
+ // ns.empty()) {
126
+ // ns.append(n);
127
+ // tmp_start = l.end_;
128
+ // break;
129
+ // }
130
+ // }
131
+ // break;
132
+ // } while (tmp_start != root_line.end_);
133
+ // }
134
+ // }
135
+ if (ns.back ().line_ .end_ == root_line.end_ ) {
136
+ for (const auto & n : ns) {
137
+ root.children_ .append (tree.append (n));
138
+ }
139
+ return true ;
140
+ }
141
+ return false ;
142
+ };
143
+ return run (tree.root (), root_line, run);
144
+ };
145
+
146
+ if (l2t_impl (root_line)) {
147
+ int dummy = -1 ;
148
+ }
149
+
150
+ return tree;
151
+ }
52
152
53
153
private:
154
+ Line shortest_line (const token::Token* p_start, size_t min_l) {
155
+ return find_line<[](size_t a, size_t b) {
156
+ return a < b;
157
+ }>(p_start, min_l);
158
+ }
159
+
160
+ template <auto F>
161
+ Line find_line (const token::archived_type* p_start, size_t the_l) {
162
+ Line the_line;
163
+ lps_assert (kTag , path_.contains (p_start));
164
+ for (const auto & line : path_[p_start]) {
165
+ if (F (line.len_ , the_l)) {
166
+ the_line = line;
167
+ }
168
+ }
169
+ lps_assert (kTag , the_line.len_ > 0 );
170
+ return the_line;
171
+ }
172
+
54
173
token::TokenLists token_lists_;
55
174
token::Token start_token_;
175
+ std::unordered_map<const token::Token*, basic::Vector<16 , Line>> path_;
56
176
};
57
177
58
178
class ContextTrait {
@@ -64,62 +184,6 @@ class ContextTrait {
64
184
Context* context_;
65
185
};
66
186
67
- enum class ParseFunctionKind : uint16_t {
68
- kUnknown = 0 ,
69
- kExpectedToken = 1 ,
70
- #define PARSE_FUNC (FUNC ) FUNC,
71
- #include " parse_function/kinds.def"
72
- kNum ,
73
- };
74
-
75
- namespace kind {
76
-
77
- static constexpr std::array<std::pair<ParseFunctionKind, const char *>,
78
- static_cast <uint16_t >(ParseFunctionKind::kNum )>
79
- kLists = {{
80
- #define PARSE_FUNC (X ) {ParseFunctionKind::X, #X},
81
- #include " parse_function/kinds.def"
82
- }};
83
-
84
- static constexpr lps::basic::map::Map<ParseFunctionKind, const char *,
85
- static_cast <uint16_t >(
86
- ParseFunctionKind::kNum )>
87
- kMap {kLists };
88
-
89
- } // namespace kind
90
-
91
- inline std::ostream& operator <<(std::ostream& s, ParseFunctionKind kind) {
92
- s << kind::kMap .at (kind);
93
- return s;
94
- }
95
-
96
- class Tree {
97
- public:
98
- static Tree& instance () {
99
- static Tree tree;
100
- return tree;
101
- }
102
-
103
- struct Node {
104
- using sub_nodes_type = basic::Vector<4 , Node*>;
105
- using token_pts_type = basic::Vector<8 , token::archived_type*>;
106
- ParseFunctionKind kind_{ParseFunctionKind::kUnknown };
107
- sub_nodes_type sub_nodes_;
108
- token_pts_type token_pts_;
109
- token::details::TokenKind expected_token_kind_{
110
- token::details::TokenKind::unknown};
111
- };
112
-
113
- Node* append (const Node& node) {
114
- nodes_.append (node);
115
- return &nodes_.back ();
116
- }
117
- [[nodiscard]] size_t size () const { return nodes_.size (); }
118
-
119
- private:
120
- basic::Vector<4 , Node> nodes_;
121
- };
122
-
123
187
struct ParseFunctionOutputs {
124
188
explicit ParseFunctionOutputs () = default;
125
189
@@ -355,6 +419,10 @@ class ParseFunction : public ContextTrait {
355
419
output.work_ = true ;
356
420
output.cur_token_ = next_tok;
357
421
++output.len_ ;
422
+
423
+ func->context ()->paint (func->calling_depth (), output.last_token_ ,
424
+ output.cur_token_ , ParseFunctionKind::kUnknown ,
425
+ token_kind);
358
426
}
359
427
360
428
return output;
0 commit comments