/src/jsonnet/core/lexer.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | Copyright 2015 Google Inc. All rights reserved. |
3 | | |
4 | | Licensed under the Apache License, Version 2.0 (the "License"); |
5 | | you may not use this file except in compliance with the License. |
6 | | You may obtain a copy of the License at |
7 | | |
8 | | http://www.apache.org/licenses/LICENSE-2.0 |
9 | | |
10 | | Unless required by applicable law or agreed to in writing, software |
11 | | distributed under the License is distributed on an "AS IS" BASIS, |
12 | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | | See the License for the specific language governing permissions and |
14 | | limitations under the License. |
15 | | */ |
16 | | |
17 | | #ifndef JSONNET_LEXER_H |
18 | | #define JSONNET_LEXER_H |
19 | | |
20 | | #include <cassert> |
21 | | #include <cstdlib> |
22 | | |
23 | | #include <iostream> |
24 | | #include <list> |
25 | | #include <sstream> |
26 | | #include <string> |
27 | | #include <vector> |
28 | | |
29 | | #include "static_error.h" |
30 | | #include "unicode.h" |
31 | | |
32 | | namespace jsonnet::internal { |
33 | | |
34 | | /** Whitespace and comments. |
35 | | * |
36 | | * "Fodder" (as in cannon fodder) implies this data is expendable. |
37 | | */ |
38 | | struct FodderElement { |
39 | | enum Kind { |
40 | | /** The next token, paragraph, or interstitial should be on a new line. |
41 | | * |
42 | | * A single comment string is allowed, which flows before the new line. |
43 | | * |
44 | | * The LINE_END fodder specifies the indentation level and vertical spacing before whatever |
45 | | * comes next. |
46 | | */ |
47 | | LINE_END, |
48 | | |
49 | | /** A C-style comment that begins and ends on the same line. |
50 | | * |
51 | | * If it follows a token (i.e., it is the first fodder element) then it appears after the |
52 | | * token on the same line. If it follows another interstitial, it will also flow after it |
53 | | * on the same line. If it follows a new line or a paragraph, it is the first thing on the |
54 | | * following line, after the blank lines and indentation specified by the previous fodder. |
55 | | * |
56 | | * There is exactly one comment string. |
57 | | */ |
58 | | INTERSTITIAL, |
59 | | |
60 | | /** A comment consisting of at least one line. |
61 | | * |
62 | | * // and # style commes have exactly one line. C-style comments can have more than one |
63 | | * line. |
64 | | * |
65 | | * All lines of the comment are indented according to the indentation level of the previous |
66 | | * new line / paragraph fodder. |
67 | | * |
68 | | * The PARAGRAPH fodder specifies the indentation level and vertical spacing before whatever |
69 | | * comes next. |
70 | | */ |
71 | | PARAGRAPH, |
72 | | }; |
73 | | Kind kind; |
74 | | |
75 | | /** How many blank lines (vertical space) before the next fodder / token. */ |
76 | | unsigned blanks; |
77 | | |
78 | | /** How far the next fodder / token should be indented. */ |
79 | | unsigned indent; |
80 | | |
81 | | /** Whatever comments are part of this fodder. |
82 | | * |
83 | | * Constraints apply. See Kind, above. |
84 | | * |
85 | | * The strings include any delimiting characters, e.g. // # and C-style comment delimiters but |
86 | | * not newline characters or indentation. |
87 | | */ |
88 | | std::vector<std::string> comment; |
89 | | |
90 | | FodderElement(Kind kind, unsigned blanks, unsigned indent, |
91 | | const std::vector<std::string> &comment) |
92 | 35.7M | : kind(kind), blanks(blanks), indent(indent), comment(comment) |
93 | 35.7M | { |
94 | 35.7M | assert(kind != LINE_END || comment.size() <= 1); |
95 | 35.7M | assert(kind != INTERSTITIAL || (blanks == 0 && indent == 0 && comment.size() == 1)); |
96 | 35.7M | assert(kind != PARAGRAPH || comment.size() >= 1); |
97 | 35.7M | } |
98 | | }; |
99 | | |
100 | | static inline std::ostream &operator<<(std::ostream &o, const FodderElement &f) |
101 | 0 | { |
102 | 0 | switch (f.kind) { |
103 | 0 | case FodderElement::LINE_END: |
104 | 0 | o << "END(" << f.blanks << ", " << f.indent; |
105 | 0 | if (!f.comment.empty()) { |
106 | 0 | o << ", " << f.comment[0]; |
107 | 0 | } |
108 | 0 | o << ")"; |
109 | 0 | break; |
110 | 0 | case FodderElement::INTERSTITIAL: |
111 | 0 | o << "INT(" << f.blanks << ", " << f.indent << ", " << f.comment[0] << ")"; |
112 | 0 | break; |
113 | 0 | case FodderElement::PARAGRAPH: |
114 | 0 | o << "PAR(" << f.blanks << ", " << f.indent << ", " << f.comment[0] << "...)"; |
115 | 0 | break; |
116 | 0 | } |
117 | 0 | return o; |
118 | 0 | } Unexecuted instantiation: libjsonnet.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, jsonnet::internal::FodderElement const&) Unexecuted instantiation: parser.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, jsonnet::internal::FodderElement const&) Unexecuted instantiation: pass.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, jsonnet::internal::FodderElement const&) Unexecuted instantiation: static_analysis.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, jsonnet::internal::FodderElement const&) Unexecuted instantiation: string_utils.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, jsonnet::internal::FodderElement const&) Unexecuted instantiation: vm.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, jsonnet::internal::FodderElement const&) Unexecuted instantiation: desugarer.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, jsonnet::internal::FodderElement const&) Unexecuted instantiation: formatter.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, jsonnet::internal::FodderElement const&) Unexecuted instantiation: lexer.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, jsonnet::internal::FodderElement const&) |
119 | | |
120 | | /** A sequence of fodder elements, typically between two tokens. |
121 | | * |
122 | | * A LINE_END is not allowed to follow a PARAGRAPH or a LINE_END. This can be represented by |
123 | | * replacing the indent of the prior fodder and increasing the number of blank lines if necessary. |
124 | | * If there was a comment, it can be represented by changing the LINE_END to a paragraph containing |
125 | | * the same single comment string. |
126 | | * |
127 | | * There must be a LINE_END or a PARAGRAPH before a PARAGRAPH. |
128 | | * |
129 | | * TODO(sbarzowski) Make it a proper class |
130 | | */ |
131 | | typedef std::vector<FodderElement> Fodder; |
132 | | |
133 | | static inline bool fodder_has_clean_endline(const Fodder &fodder) |
134 | 578k | { |
135 | 578k | return !fodder.empty() && fodder.back().kind != FodderElement::INTERSTITIAL; |
136 | 578k | } Unexecuted instantiation: libjsonnet.cpp:jsonnet::internal::fodder_has_clean_endline(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) Unexecuted instantiation: parser.cpp:jsonnet::internal::fodder_has_clean_endline(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) Unexecuted instantiation: pass.cpp:jsonnet::internal::fodder_has_clean_endline(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) Unexecuted instantiation: static_analysis.cpp:jsonnet::internal::fodder_has_clean_endline(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) Unexecuted instantiation: string_utils.cpp:jsonnet::internal::fodder_has_clean_endline(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) Unexecuted instantiation: vm.cpp:jsonnet::internal::fodder_has_clean_endline(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) Unexecuted instantiation: desugarer.cpp:jsonnet::internal::fodder_has_clean_endline(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) Unexecuted instantiation: formatter.cpp:jsonnet::internal::fodder_has_clean_endline(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) lexer.cpp:jsonnet::internal::fodder_has_clean_endline(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) Line | Count | Source | 134 | 578k | { | 135 | 578k | return !fodder.empty() && fodder.back().kind != FodderElement::INTERSTITIAL; | 136 | 578k | } |
|
137 | | |
138 | | /** As a.push_back(elem) but preserves constraints. |
139 | | * |
140 | | * See concat_fodder below. |
141 | | */ |
142 | | static inline void fodder_push_back(Fodder &a, const FodderElement &elem) |
143 | 289k | { |
144 | 289k | if (fodder_has_clean_endline(a) && elem.kind == FodderElement::LINE_END) { |
145 | 0 | if (elem.comment.size() > 0) { |
146 | | // The line end had a comment, so create a single line paragraph for it. |
147 | 0 | a.emplace_back(FodderElement::PARAGRAPH, elem.blanks, elem.indent, elem.comment); |
148 | 0 | } else { |
149 | | // Merge it into the previous line end. |
150 | 0 | a.back().indent = elem.indent; |
151 | 0 | a.back().blanks += elem.blanks; |
152 | 0 | } |
153 | 289k | } else { |
154 | 289k | if (!fodder_has_clean_endline(a) && elem.kind == FodderElement::PARAGRAPH) { |
155 | 37.7k | a.emplace_back(FodderElement::LINE_END, 0, elem.indent, std::vector<std::string>()); |
156 | 37.7k | } |
157 | 289k | a.push_back(elem); |
158 | 289k | } |
159 | 289k | } Unexecuted instantiation: libjsonnet.cpp:jsonnet::internal::fodder_push_back(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, jsonnet::internal::FodderElement const&) Unexecuted instantiation: parser.cpp:jsonnet::internal::fodder_push_back(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, jsonnet::internal::FodderElement const&) Unexecuted instantiation: pass.cpp:jsonnet::internal::fodder_push_back(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, jsonnet::internal::FodderElement const&) Unexecuted instantiation: static_analysis.cpp:jsonnet::internal::fodder_push_back(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, jsonnet::internal::FodderElement const&) Unexecuted instantiation: string_utils.cpp:jsonnet::internal::fodder_push_back(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, jsonnet::internal::FodderElement const&) Unexecuted instantiation: vm.cpp:jsonnet::internal::fodder_push_back(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, jsonnet::internal::FodderElement const&) Unexecuted instantiation: desugarer.cpp:jsonnet::internal::fodder_push_back(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, jsonnet::internal::FodderElement const&) Unexecuted instantiation: formatter.cpp:jsonnet::internal::fodder_push_back(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, jsonnet::internal::FodderElement const&) lexer.cpp:jsonnet::internal::fodder_push_back(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, jsonnet::internal::FodderElement const&) Line | Count | Source | 143 | 289k | { | 144 | 289k | if (fodder_has_clean_endline(a) && elem.kind == FodderElement::LINE_END) { | 145 | 0 | if (elem.comment.size() > 0) { | 146 | | // The line end had a comment, so create a single line paragraph for it. | 147 | 0 | a.emplace_back(FodderElement::PARAGRAPH, elem.blanks, elem.indent, elem.comment); | 148 | 0 | } else { | 149 | | // Merge it into the previous line end. | 150 | 0 | a.back().indent = elem.indent; | 151 | 0 | a.back().blanks += elem.blanks; | 152 | 0 | } | 153 | 289k | } else { | 154 | 289k | if (!fodder_has_clean_endline(a) && elem.kind == FodderElement::PARAGRAPH) { | 155 | 37.7k | a.emplace_back(FodderElement::LINE_END, 0, elem.indent, std::vector<std::string>()); | 156 | 37.7k | } | 157 | 289k | a.push_back(elem); | 158 | 289k | } | 159 | 289k | } |
|
160 | | |
161 | | /** As a + b but preserves constraints. |
162 | | * |
163 | | * Namely, a LINE_END is not allowed to follow a PARAGRAPH or a LINE_END. |
164 | | */ |
165 | | static inline Fodder concat_fodder(const Fodder &a, const Fodder &b) |
166 | 0 | { |
167 | 0 | if (a.size() == 0) |
168 | 0 | return b; |
169 | 0 | if (b.size() == 0) |
170 | 0 | return a; |
171 | 0 | Fodder r = a; |
172 | | // Carefully add the first element of b. |
173 | 0 | fodder_push_back(r, b[0]); |
174 | | // Add the rest of b. |
175 | 0 | for (unsigned i = 1; i < b.size(); ++i) { |
176 | 0 | r.push_back(b[i]); |
177 | 0 | } |
178 | 0 | return r; |
179 | 0 | } Unexecuted instantiation: libjsonnet.cpp:jsonnet::internal::concat_fodder(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) Unexecuted instantiation: parser.cpp:jsonnet::internal::concat_fodder(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) Unexecuted instantiation: pass.cpp:jsonnet::internal::concat_fodder(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) Unexecuted instantiation: static_analysis.cpp:jsonnet::internal::concat_fodder(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) Unexecuted instantiation: string_utils.cpp:jsonnet::internal::concat_fodder(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) Unexecuted instantiation: vm.cpp:jsonnet::internal::concat_fodder(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) Unexecuted instantiation: desugarer.cpp:jsonnet::internal::concat_fodder(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) Unexecuted instantiation: formatter.cpp:jsonnet::internal::concat_fodder(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) Unexecuted instantiation: lexer.cpp:jsonnet::internal::concat_fodder(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) |
180 | | |
181 | | /** Move b to the front of a. */ |
182 | | static inline void fodder_move_front(Fodder &a, Fodder &b) |
183 | 0 | { |
184 | 0 | a = concat_fodder(b, a); |
185 | 0 | b.clear(); |
186 | 0 | } Unexecuted instantiation: libjsonnet.cpp:jsonnet::internal::fodder_move_front(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&) Unexecuted instantiation: parser.cpp:jsonnet::internal::fodder_move_front(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&) Unexecuted instantiation: pass.cpp:jsonnet::internal::fodder_move_front(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&) Unexecuted instantiation: static_analysis.cpp:jsonnet::internal::fodder_move_front(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&) Unexecuted instantiation: string_utils.cpp:jsonnet::internal::fodder_move_front(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&) Unexecuted instantiation: vm.cpp:jsonnet::internal::fodder_move_front(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&) Unexecuted instantiation: desugarer.cpp:jsonnet::internal::fodder_move_front(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&) Unexecuted instantiation: formatter.cpp:jsonnet::internal::fodder_move_front(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&) Unexecuted instantiation: lexer.cpp:jsonnet::internal::fodder_move_front(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&) |
187 | | |
188 | | static inline Fodder make_fodder(const FodderElement &elem) |
189 | 0 | { |
190 | 0 | Fodder fodder; |
191 | 0 | fodder_push_back(fodder, elem); |
192 | 0 | return fodder; |
193 | 0 | } Unexecuted instantiation: libjsonnet.cpp:jsonnet::internal::make_fodder(jsonnet::internal::FodderElement const&) Unexecuted instantiation: parser.cpp:jsonnet::internal::make_fodder(jsonnet::internal::FodderElement const&) Unexecuted instantiation: pass.cpp:jsonnet::internal::make_fodder(jsonnet::internal::FodderElement const&) Unexecuted instantiation: static_analysis.cpp:jsonnet::internal::make_fodder(jsonnet::internal::FodderElement const&) Unexecuted instantiation: string_utils.cpp:jsonnet::internal::make_fodder(jsonnet::internal::FodderElement const&) Unexecuted instantiation: vm.cpp:jsonnet::internal::make_fodder(jsonnet::internal::FodderElement const&) Unexecuted instantiation: desugarer.cpp:jsonnet::internal::make_fodder(jsonnet::internal::FodderElement const&) Unexecuted instantiation: formatter.cpp:jsonnet::internal::make_fodder(jsonnet::internal::FodderElement const&) Unexecuted instantiation: lexer.cpp:jsonnet::internal::make_fodder(jsonnet::internal::FodderElement const&) |
194 | | |
195 | | static inline void ensureCleanNewline(Fodder &fodder) |
196 | 0 | { |
197 | 0 | if (!fodder_has_clean_endline(fodder)) { |
198 | 0 | fodder_push_back(fodder, FodderElement(FodderElement::Kind::LINE_END, 0, 0, {})); |
199 | 0 | } |
200 | 0 | } Unexecuted instantiation: libjsonnet.cpp:jsonnet::internal::ensureCleanNewline(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&) Unexecuted instantiation: parser.cpp:jsonnet::internal::ensureCleanNewline(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&) Unexecuted instantiation: pass.cpp:jsonnet::internal::ensureCleanNewline(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&) Unexecuted instantiation: static_analysis.cpp:jsonnet::internal::ensureCleanNewline(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&) Unexecuted instantiation: string_utils.cpp:jsonnet::internal::ensureCleanNewline(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&) Unexecuted instantiation: vm.cpp:jsonnet::internal::ensureCleanNewline(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&) Unexecuted instantiation: desugarer.cpp:jsonnet::internal::ensureCleanNewline(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&) Unexecuted instantiation: formatter.cpp:jsonnet::internal::ensureCleanNewline(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&) Unexecuted instantiation: lexer.cpp:jsonnet::internal::ensureCleanNewline(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> >&) |
201 | | |
202 | | static inline int countNewlines(const FodderElement &elem) |
203 | 0 | { |
204 | 0 | switch (elem.kind) { |
205 | 0 | case FodderElement::INTERSTITIAL: return 0; |
206 | 0 | case FodderElement::LINE_END: return 1; |
207 | 0 | case FodderElement::PARAGRAPH: return elem.comment.size() + elem.blanks; |
208 | 0 | } |
209 | 0 | std::cerr << "Unknown FodderElement kind" << std::endl; |
210 | 0 | abort(); |
211 | 0 | } Unexecuted instantiation: libjsonnet.cpp:jsonnet::internal::countNewlines(jsonnet::internal::FodderElement const&) Unexecuted instantiation: parser.cpp:jsonnet::internal::countNewlines(jsonnet::internal::FodderElement const&) Unexecuted instantiation: pass.cpp:jsonnet::internal::countNewlines(jsonnet::internal::FodderElement const&) Unexecuted instantiation: static_analysis.cpp:jsonnet::internal::countNewlines(jsonnet::internal::FodderElement const&) Unexecuted instantiation: string_utils.cpp:jsonnet::internal::countNewlines(jsonnet::internal::FodderElement const&) Unexecuted instantiation: vm.cpp:jsonnet::internal::countNewlines(jsonnet::internal::FodderElement const&) Unexecuted instantiation: desugarer.cpp:jsonnet::internal::countNewlines(jsonnet::internal::FodderElement const&) Unexecuted instantiation: formatter.cpp:jsonnet::internal::countNewlines(jsonnet::internal::FodderElement const&) Unexecuted instantiation: lexer.cpp:jsonnet::internal::countNewlines(jsonnet::internal::FodderElement const&) |
212 | | |
213 | | static inline int countNewlines(const Fodder &fodder) |
214 | 0 | { |
215 | 0 | int sum = 0; |
216 | 0 | for (const auto &elem : fodder) { |
217 | 0 | sum += countNewlines(elem); |
218 | 0 | } |
219 | 0 | return sum; |
220 | 0 | } Unexecuted instantiation: libjsonnet.cpp:jsonnet::internal::countNewlines(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) Unexecuted instantiation: parser.cpp:jsonnet::internal::countNewlines(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) Unexecuted instantiation: pass.cpp:jsonnet::internal::countNewlines(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) Unexecuted instantiation: static_analysis.cpp:jsonnet::internal::countNewlines(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) Unexecuted instantiation: string_utils.cpp:jsonnet::internal::countNewlines(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) Unexecuted instantiation: vm.cpp:jsonnet::internal::countNewlines(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) Unexecuted instantiation: desugarer.cpp:jsonnet::internal::countNewlines(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) Unexecuted instantiation: formatter.cpp:jsonnet::internal::countNewlines(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) Unexecuted instantiation: lexer.cpp:jsonnet::internal::countNewlines(std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) |
221 | | |
222 | | static inline std::ostream &operator<<(std::ostream &o, const Fodder &fodder) |
223 | 0 | { |
224 | 0 | bool first = true; |
225 | 0 | for (const auto &f : fodder) { |
226 | 0 | o << (first ? "[" : ", "); |
227 | 0 | first = false; |
228 | 0 | o << f; |
229 | 0 | } |
230 | 0 | o << (first ? "[]" : "]"); |
231 | 0 | return o; |
232 | 0 | } Unexecuted instantiation: libjsonnet.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) Unexecuted instantiation: parser.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) Unexecuted instantiation: pass.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) Unexecuted instantiation: static_analysis.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) Unexecuted instantiation: string_utils.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) Unexecuted instantiation: vm.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) Unexecuted instantiation: desugarer.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) Unexecuted instantiation: formatter.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) Unexecuted instantiation: lexer.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, std::__1::vector<jsonnet::internal::FodderElement, std::__1::allocator<jsonnet::internal::FodderElement> > const&) |
233 | | |
234 | | struct Token { |
235 | | enum Kind { |
236 | | // Symbols |
237 | | BRACE_L, |
238 | | BRACE_R, |
239 | | BRACKET_L, |
240 | | BRACKET_R, |
241 | | COMMA, |
242 | | DOLLAR, |
243 | | DOT, |
244 | | PAREN_L, |
245 | | PAREN_R, |
246 | | SEMICOLON, |
247 | | |
248 | | // Arbitrary length lexemes |
249 | | IDENTIFIER, |
250 | | NUMBER, |
251 | | OPERATOR, |
252 | | STRING_DOUBLE, |
253 | | STRING_SINGLE, |
254 | | STRING_BLOCK, |
255 | | VERBATIM_STRING_SINGLE, |
256 | | VERBATIM_STRING_DOUBLE, |
257 | | |
258 | | // Keywords |
259 | | ASSERT, |
260 | | ELSE, |
261 | | ERROR, |
262 | | FALSE, |
263 | | FOR, |
264 | | FUNCTION, |
265 | | IF, |
266 | | IMPORT, |
267 | | IMPORTSTR, |
268 | | IMPORTBIN, |
269 | | IN, |
270 | | LOCAL, |
271 | | NULL_LIT, |
272 | | TAILSTRICT, |
273 | | THEN, |
274 | | SELF, |
275 | | SUPER, |
276 | | TRUE, |
277 | | |
278 | | // A special token that holds line/column information about the end of the file. |
279 | | END_OF_FILE |
280 | | } kind; |
281 | | |
282 | | /** Fodder before this token. */ |
283 | | Fodder fodder; |
284 | | |
285 | | /** Content of the token if it wasn't a keyword. */ |
286 | | std::string data; |
287 | | |
288 | | /** If kind == STRING_BLOCK then stores the sequence of whitespace that indented the block. */ |
289 | | std::string stringBlockIndent; |
290 | | |
291 | | /** If kind == STRING_BLOCK then stores the sequence of whitespace that indented the end of |
292 | | * the block. |
293 | | * |
294 | | * This is always fewer whitespace characters than in stringBlockIndent. |
295 | | */ |
296 | | std::string stringBlockTermIndent; |
297 | | |
298 | | UString data32(void) const |
299 | 77.6M | { |
300 | 77.6M | return decode_utf8(data); |
301 | 77.6M | } |
302 | | |
303 | | LocationRange location; |
304 | | |
305 | | Token(Kind kind, const Fodder &fodder, const std::string &data, |
306 | | const std::string &string_block_indent, const std::string &string_block_term_indent, |
307 | | const LocationRange &location) |
308 | 222M | : kind(kind), |
309 | 222M | fodder(fodder), |
310 | 222M | data(data), |
311 | 222M | stringBlockIndent(string_block_indent), |
312 | 222M | stringBlockTermIndent(string_block_term_indent), |
313 | 222M | location(location) |
314 | 222M | { |
315 | 222M | } |
316 | | |
317 | 0 | Token(Kind kind, const std::string &data = "") : kind(kind), data(data) {} |
318 | | |
319 | | static const char *toString(Kind v) |
320 | 2.77k | { |
321 | 2.77k | switch (v) { |
322 | 34 | case BRACE_L: return "\"{\""; |
323 | 94 | case BRACE_R: return "\"}\""; |
324 | 8 | case BRACKET_L: return "\"[\""; |
325 | 279 | case BRACKET_R: return "\"]\""; |
326 | 117 | case COMMA: return "\",\""; |
327 | 44 | case DOLLAR: return "\"$\""; |
328 | 25 | case DOT: return "\".\""; |
329 | | |
330 | 3 | case PAREN_L: return "\"(\""; |
331 | 119 | case PAREN_R: return "\")\""; |
332 | 67 | case SEMICOLON: return "\";\""; |
333 | | |
334 | 381 | case IDENTIFIER: return "IDENTIFIER"; |
335 | 110 | case NUMBER: return "NUMBER"; |
336 | 357 | case OPERATOR: return "OPERATOR"; |
337 | 40 | case STRING_SINGLE: return "STRING_SINGLE"; |
338 | 40 | case STRING_DOUBLE: return "STRING_DOUBLE"; |
339 | 4 | case VERBATIM_STRING_SINGLE: return "VERBATIM_STRING_SINGLE"; |
340 | 5 | case VERBATIM_STRING_DOUBLE: return "VERBATIM_STRING_DOUBLE"; |
341 | 13 | case STRING_BLOCK: return "STRING_BLOCK"; |
342 | | |
343 | 4 | case ASSERT: return "assert"; |
344 | 4 | case ELSE: return "else"; |
345 | 0 | case ERROR: return "error"; |
346 | 3 | case FALSE: return "false"; |
347 | 6 | case FOR: return "for"; |
348 | 2 | case FUNCTION: return "function"; |
349 | 7 | case IF: return "if"; |
350 | 0 | case IMPORT: return "import"; |
351 | 0 | case IMPORTSTR: return "importstr"; |
352 | 1 | case IMPORTBIN: return "importbin"; |
353 | 36 | case IN: return "in"; |
354 | 3 | case LOCAL: return "local"; |
355 | 3 | case NULL_LIT: return "null"; |
356 | 1 | case SELF: return "self"; |
357 | 0 | case SUPER: return "super"; |
358 | 3 | case TAILSTRICT: return "tailstrict"; |
359 | 20 | case THEN: return "then"; |
360 | 2 | case TRUE: return "true"; |
361 | | |
362 | 936 | case END_OF_FILE: return "end of file"; |
363 | 0 | default: |
364 | 0 | std::cerr << "INTERNAL ERROR: Unknown token kind: " << v << std::endl; |
365 | 0 | std::abort(); |
366 | 2.77k | } |
367 | 2.77k | } |
368 | | }; |
369 | | |
370 | | /** The result of lexing. |
371 | | * |
372 | | * Because of the EOF token, this will always contain at least one token. So element 0 can be used |
373 | | * to get the filename. |
374 | | */ |
375 | | typedef std::list<Token> Tokens; |
376 | | |
377 | | static inline bool operator==(const Token &a, const Token &b) |
378 | 0 | { |
379 | 0 | if (a.kind != b.kind) |
380 | 0 | return false; |
381 | 0 | if (a.data != b.data) |
382 | 0 | return false; |
383 | 0 | return true; |
384 | 0 | } Unexecuted instantiation: libjsonnet.cpp:jsonnet::internal::operator==(jsonnet::internal::Token const&, jsonnet::internal::Token const&) Unexecuted instantiation: parser.cpp:jsonnet::internal::operator==(jsonnet::internal::Token const&, jsonnet::internal::Token const&) Unexecuted instantiation: pass.cpp:jsonnet::internal::operator==(jsonnet::internal::Token const&, jsonnet::internal::Token const&) Unexecuted instantiation: static_analysis.cpp:jsonnet::internal::operator==(jsonnet::internal::Token const&, jsonnet::internal::Token const&) Unexecuted instantiation: string_utils.cpp:jsonnet::internal::operator==(jsonnet::internal::Token const&, jsonnet::internal::Token const&) Unexecuted instantiation: vm.cpp:jsonnet::internal::operator==(jsonnet::internal::Token const&, jsonnet::internal::Token const&) Unexecuted instantiation: desugarer.cpp:jsonnet::internal::operator==(jsonnet::internal::Token const&, jsonnet::internal::Token const&) Unexecuted instantiation: formatter.cpp:jsonnet::internal::operator==(jsonnet::internal::Token const&, jsonnet::internal::Token const&) Unexecuted instantiation: lexer.cpp:jsonnet::internal::operator==(jsonnet::internal::Token const&, jsonnet::internal::Token const&) |
385 | | |
386 | | static inline std::ostream &operator<<(std::ostream &o, Token::Kind v) |
387 | 1.56k | { |
388 | 1.56k | o << Token::toString(v); |
389 | 1.56k | return o; |
390 | 1.56k | } Unexecuted instantiation: libjsonnet.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, jsonnet::internal::Token::Kind) parser.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, jsonnet::internal::Token::Kind) Line | Count | Source | 387 | 1.56k | { | 388 | 1.56k | o << Token::toString(v); | 389 | 1.56k | return o; | 390 | 1.56k | } |
Unexecuted instantiation: pass.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, jsonnet::internal::Token::Kind) Unexecuted instantiation: static_analysis.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, jsonnet::internal::Token::Kind) Unexecuted instantiation: string_utils.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, jsonnet::internal::Token::Kind) Unexecuted instantiation: vm.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, jsonnet::internal::Token::Kind) Unexecuted instantiation: desugarer.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, jsonnet::internal::Token::Kind) Unexecuted instantiation: formatter.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, jsonnet::internal::Token::Kind) Unexecuted instantiation: lexer.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, jsonnet::internal::Token::Kind) |
391 | | |
392 | | static inline std::ostream &operator<<(std::ostream &o, const Token &v) |
393 | 1.29k | { |
394 | 1.29k | if (v.data == "") { |
395 | 818 | o << Token::toString(v.kind); |
396 | 818 | } else if (v.kind == Token::OPERATOR) { |
397 | 89 | o << "\"" << v.data << "\""; |
398 | 390 | } else { |
399 | 390 | o << "(" << Token::toString(v.kind) << ", \"" << v.data << "\")"; |
400 | 390 | } |
401 | 1.29k | return o; |
402 | 1.29k | } Unexecuted instantiation: libjsonnet.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, jsonnet::internal::Token const&) parser.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, jsonnet::internal::Token const&) Line | Count | Source | 393 | 1.29k | { | 394 | 1.29k | if (v.data == "") { | 395 | 818 | o << Token::toString(v.kind); | 396 | 818 | } else if (v.kind == Token::OPERATOR) { | 397 | 89 | o << "\"" << v.data << "\""; | 398 | 390 | } else { | 399 | 390 | o << "(" << Token::toString(v.kind) << ", \"" << v.data << "\")"; | 400 | 390 | } | 401 | 1.29k | return o; | 402 | 1.29k | } |
Unexecuted instantiation: pass.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, jsonnet::internal::Token const&) Unexecuted instantiation: static_analysis.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, jsonnet::internal::Token const&) Unexecuted instantiation: string_utils.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, jsonnet::internal::Token const&) Unexecuted instantiation: vm.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, jsonnet::internal::Token const&) Unexecuted instantiation: desugarer.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, jsonnet::internal::Token const&) Unexecuted instantiation: formatter.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, jsonnet::internal::Token const&) Unexecuted instantiation: lexer.cpp:jsonnet::internal::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, jsonnet::internal::Token const&) |
403 | | |
404 | | /** IF the given identifier is a keyword, return its kind, otherwise return IDENTIFIER. */ |
405 | | Token::Kind lex_get_keyword_kind(const std::string &identifier); |
406 | | |
407 | | Tokens jsonnet_lex(const std::string &filename, const char *input); |
408 | | |
409 | | std::string jsonnet_unlex(const Tokens &tokens); |
410 | | |
411 | | } // namespace jsonnet::internal |
412 | | |
413 | | #endif // JSONNET_LEXER_H |