Spicy
parser-builder.h
1 // Copyright (c) 2020-2021 by the Zeek Project. See LICENSE for details.
2 
3 #pragma once
4 
5 #include <functional>
6 #include <map>
7 #include <memory>
8 #include <string>
9 #include <utility>
10 #include <vector>
11 
12 #include <hilti/compiler/context.h>
13 
14 #include <spicy/ast/aliases.h>
15 #include <spicy/ast/types/unit.h>
16 #include <spicy/compiler/detail/codegen/production.h>
17 
18 namespace hilti::type {
19 class Struct;
20 } // namespace hilti::type
21 namespace hilti::builder {
22 class Builder;
23 } // namespace hilti::builder
24 
25 namespace spicy::detail {
26 
27 class CodeGen;
28 
29 namespace codegen {
30 
31 struct ProductionVisitor;
32 
38 enum class LiteralMode {
40  Default,
41 
46  Try,
47 
52  Search,
53 };
54 
55 namespace detail {
56 constexpr hilti::util::enum_::Value<LiteralMode> literal_modes[] = {{LiteralMode::Default, "default"},
57  {LiteralMode::Try, "try"},
58  {LiteralMode::Search, "search"}};
59 } // namespace detail
60 
61 constexpr auto to_string(LiteralMode cc) { return hilti::util::enum_::to_string(cc, detail::literal_modes); }
62 
63 namespace look_ahead {
64 
66 extern const hilti::Type Type;
67 
73 extern const hilti::Expression None;
74 
79 extern const hilti::Expression Eod;
80 
81 } // namespace look_ahead
82 
92 struct ParserState {
93  ParserState(const type::Unit& unit, const Grammar& grammar, Expression data, Expression cur);
94  ParserState(const ParserState& other) = default;
95  ParserState(ParserState&& other) = default;
96  ParserState& operator=(const ParserState& other) = default;
97  ParserState& operator=(ParserState&& other) = default;
98  ~ParserState() = default;
99 
106  void printDebug(const std::shared_ptr<hilti::builder::Builder>& b) const;
107 
109  std::reference_wrapper<const type::Unit> unit;
110 
113 
116 
118  Expression self;
119 
121  Expression data;
122 
124  Expression cur;
125 
127  std::optional<Expression> ncur;
128 
133  Expression trim;
134 
139  Expression lahead = look_ahead::None;
140 
145  Expression lahead_end;
146 
148  LiteralMode literal_mode = LiteralMode::Default;
149 
154  std::optional<Expression> captures;
155 
159  Expression error;
160 };
161 
164 public:
165  ParserBuilder(CodeGen* cg) : _cg(cg) {}
166 
171  void pushState(ParserState p) { _states.push_back(std::move(p)); }
172 
177  void popState() { _states.pop_back(); }
178 
180  ParserState state() const { return _states.back(); }
181 
188  Expression parseMethodExternalOverload1(const type::Unit& t);
189 
196  Expression parseMethodExternalOverload2(const type::Unit& t);
197 
205  Expression parseMethodExternalOverload3(const type::Unit& t);
206 
212  Expression contextNewFunction(const type::Unit& t);
213 
218  hilti::type::Struct addParserMethods(hilti::type::Struct s, const type::Unit& t, bool declare_only);
219 
221  auto builder() { return _builders.back(); }
222 
224  auto pushBuilder(std::shared_ptr<hilti::builder::Builder> b) {
225  _builders.emplace_back(b);
226  return b;
227  }
228 
230  std::shared_ptr<hilti::builder::Builder> pushBuilder();
231 
233  auto popBuilder() {
234  auto x = _builders.back();
235  _builders.pop_back();
236  return x;
237  }
238 
240  struct ScopeGuard {
241  ScopeGuard(ParserBuilder* self) { this->self = self; }
242  ScopeGuard(ScopeGuard&&) = default;
243  ~ScopeGuard() { self->popBuilder(); }
244 
245  ScopeGuard() = delete;
246  ScopeGuard(const ScopeGuard&) = delete;
247  ScopeGuard& operator=(const ScopeGuard&) = delete;
248  ScopeGuard& operator=(ScopeGuard&&) noexcept = delete;
249 
250  ParserBuilder* self;
251  };
252 
255 
257  auto pushBuilder(std::shared_ptr<hilti::builder::Builder> b, const std::function<void()>& func) {
258  pushBuilder(b);
259  func();
260  popBuilder();
261  return b;
262  }
263 
265  Expression parseType(const Type& t, const production::Meta& meta, const std::optional<Expression>& dst);
266 
268  Expression parseTypeTry(const Type& t, const production::Meta& meta, const std::optional<Expression>& dst);
269 
271  hilti::type::Function parseMethodFunctionType(std::optional<type::function::Parameter> addl_param = {},
272  const Meta& m = {});
273 
289  Expression parseLiteral(const Production& p, const std::optional<Expression>& dst);
290 
302  void waitForInput(const Expression& min, const std::string& error_msg, const Meta& location);
303 
315  Expression waitForInputOrEod(const Expression& min);
316 
324  void waitForInput(const std::string& error_msg, const Meta& location);
325 
334  Expression waitForInputOrEod();
335 
340  void waitForEod();
341 
343  Expression atEod();
344 
349  void advanceToNextData();
350 
358  void advanceInput(const Expression& i);
359 
365  void setInput(const Expression& i);
366 
372  void saveParsePosition();
373 
375  void beforeHook();
376 
378  void afterHook();
379 
387  void consumeLookAhead(std::optional<Expression> dst = {});
388 
390  void parseError(const std::string& error_msg, const Meta& location);
391 
393  void parseError(const Expression& error_msg, const Meta& location);
394 
396  void parseError(const std::string& fmt, std::vector<Expression> args, const Meta& location);
397 
399  void newValueForField(const production::Meta& meta, const Expression& value, const Expression& dd);
400 
405  void enableDefaultNewValueForField(bool enable) { _report_new_value_for_field = enable; };
406 
411  bool isEnabledDefaultNewValueForField() { return _report_new_value_for_field; }
412 
417  Expression newContainerItem(const type::unit::item::Field& field, const Expression& self, const Expression& item,
418  bool need_value);
419 
427  Expression applyConvertExpression(const type::unit::item::Field& field, const Expression& value,
428  std::optional<Expression> dst = {});
429 
437  void trimInput(bool force = false);
438 
445  void initializeUnit(const Location& l);
446 
454  void finalizeUnit(bool success, const Location& l);
455 
457  void initBacktracking();
458 
460  void finishBacktracking();
461 
468  Expression initLoopBody();
469 
478  void finishLoopBody(const Expression& cookie, const Location& l);
479 
489  void guardFeatureCode(const type::Unit& unit, const std::vector<std::string_view>& features,
490  const std::function<void()>& f);
491 
492  CodeGen* cg() const { return _cg; }
493  std::shared_ptr<hilti::Context> context() const;
494  const hilti::Options& options() const;
495 
496 private:
498  CodeGen* _cg;
499 
500  Expression _parseType(const Type& t, const production::Meta& meta, const std::optional<Expression>& dst,
501  bool is_try);
502 
503  std::vector<ParserState> _states;
504  std::vector<std::shared_ptr<hilti::builder::Builder>> _builders;
505  std::map<ID, Expression> _functions;
506  bool _report_new_value_for_field = true;
507 };
508 
509 } // namespace codegen
510 } // namespace spicy::detail
Definition: function.h:71
void enableDefaultNewValueForField(bool enable)
Definition: parser-builder.h:405
Definition: util.h:596
Definition: context.h:33
auto builder()
Definition: parser-builder.h:221
bool isEnabledDefaultNewValueForField()
Definition: parser-builder.h:411
Expression trim
Definition: parser-builder.h:133
std::optional< Expression > captures
Definition: parser-builder.h:154
Expression data
Definition: parser-builder.h:121
Definition: unit.h:57
Definition: production.h:120
Definition: parser-builder.h:92
ParserState state() const
Definition: parser-builder.h:180
Definition: parser-builder.h:163
Definition: struct.h:33
Definition: field.h:22
void pushState(ParserState p)
Definition: parser-builder.h:171
Definition: meta.h:18
void popState()
Definition: parser-builder.h:177
auto popBuilder()
Definition: parser-builder.h:233
Expression lahead_end
Definition: parser-builder.h:145
auto pushBuilder(std::shared_ptr< hilti::builder::Builder > b)
Definition: parser-builder.h:224
Definition: engine.h:16
Definition: type.h:159
bool needs_look_ahead
Definition: parser-builder.h:115
Definition: production.h:40
ID unit_id
Definition: parser-builder.h:112
Definition: builder.h:20
Expression cur
Definition: parser-builder.h:124
Definition: codegen.h:30
auto pushBuilder(std::shared_ptr< hilti::builder::Builder > b, const std::function< void()> &func)
Definition: parser-builder.h:257
Definition: location.h:17
Definition: parser-builder.cc:70
Definition: grammar.h:21
Expression error
Definition: parser-builder.h:159
Definition: location.h:93
std::reference_wrapper< const type::Unit > unit
Definition: parser-builder.h:109
Definition: type.h:26
Definition: id.h:18
ScopeGuard makeScopeGuard()
Definition: parser-builder.h:254