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 };
48 
49 namespace detail {
50 constexpr hilti::util::enum_::Value<LiteralMode> literal_modes[] = {{LiteralMode::Default, "default"},
51  {LiteralMode::Try, "try"}};
52 } // namespace detail
53 
54 constexpr auto to_string(LiteralMode cc) { return hilti::util::enum_::to_string(cc, detail::literal_modes); }
55 
56 namespace look_ahead {
57 
59 extern const hilti::Type Type;
60 
66 extern const hilti::Expression None;
67 
72 extern const hilti::Expression Eod;
73 
74 } // namespace look_ahead
75 
85 struct ParserState {
86  ParserState(const type::Unit& unit, const Grammar& grammar, Expression data, Expression cur);
87  ParserState(const ParserState& other) = default;
88  ParserState(ParserState&& other) = default;
89  ParserState& operator=(const ParserState& other) = default;
90  ParserState& operator=(ParserState&& other) = default;
91  ~ParserState() = default;
92 
99  void printDebug(const std::shared_ptr<hilti::builder::Builder>& b) const;
100 
102  std::reference_wrapper<const type::Unit> unit;
103 
106 
109 
111  Expression self;
112 
114  Expression data;
115 
117  Expression cur;
118 
120  std::optional<Expression> ncur;
121 
126  Expression trim;
127 
132  Expression lahead = look_ahead::None;
133 
138  Expression lahead_end;
139 
141  LiteralMode literal_mode = LiteralMode::Default;
142 
147  std::optional<Expression> captures;
148 };
149 
152 public:
153  ParserBuilder(CodeGen* cg) : _cg(cg) {}
154 
159  void pushState(ParserState p) { _states.push_back(std::move(p)); }
160 
165  void popState() { _states.pop_back(); }
166 
168  ParserState state() const { return _states.back(); }
169 
176  Expression parseMethodExternalOverload1(const type::Unit& t);
177 
184  Expression parseMethodExternalOverload2(const type::Unit& t);
185 
193  Expression parseMethodExternalOverload3(const type::Unit& t);
194 
200  Expression contextNewFunction(const type::Unit& t);
201 
206  hilti::type::Struct addParserMethods(hilti::type::Struct s, const type::Unit& t, bool declare_only,
207  bool always_emit);
208 
210  auto builder() { return _builders.back(); }
211 
213  auto pushBuilder(std::shared_ptr<hilti::builder::Builder> b) {
214  _builders.emplace_back(b);
215  return b;
216  }
217 
219  std::shared_ptr<hilti::builder::Builder> pushBuilder();
220 
222  auto popBuilder() {
223  auto x = _builders.back();
224  _builders.pop_back();
225  return x;
226  }
227 
229  struct ScopeGuard {
230  ScopeGuard(ParserBuilder* self) { this->self = self; }
231  ScopeGuard(ScopeGuard&&) = default;
232  ~ScopeGuard() { self->popBuilder(); }
233 
234  ScopeGuard() = delete;
235  ScopeGuard(const ScopeGuard&) = delete;
236  ScopeGuard& operator=(const ScopeGuard&) = delete;
237  ScopeGuard& operator=(ScopeGuard&&) noexcept = delete;
238 
239  ParserBuilder* self;
240  };
241 
244 
246  auto pushBuilder(std::shared_ptr<hilti::builder::Builder> b, const std::function<void()>& func) {
247  pushBuilder(b);
248  func();
249  popBuilder();
250  return b;
251  }
252 
254  Expression parseType(const Type& t, const production::Meta& meta, const std::optional<Expression>& dst);
255 
257  Expression parseTypeTry(const Type& t, const production::Meta& meta, const std::optional<Expression>& dst);
258 
260  hilti::type::Function parseMethodFunctionType(std::optional<type::function::Parameter> addl_param = {},
261  const Meta& m = {});
262 
272  Expression parseLiteral(const Production& p, const std::optional<Expression>& dst);
273 
285  void waitForInput(const Expression& min, const std::string& error_msg, const Meta& location);
286 
298  Expression waitForInputOrEod(const Expression& min);
299 
307  void waitForInput(const std::string& error_msg, const Meta& location);
308 
317  Expression waitForInputOrEod();
318 
323  void waitForEod();
324 
326  Expression atEod();
327 
335  void advanceInput(const Expression& i);
336 
342  void setInput(const Expression& i);
343 
349  void saveParsePosition();
350 
352  void beforeHook();
353 
355  void afterHook();
356 
364  void consumeLookAhead(std::optional<Expression> dst = {});
365 
367  void parseError(const std::string& error_msg, const Meta& location);
368 
370  void parseError(const Expression& error_msg, const Meta& location);
371 
373  void parseError(const std::string& fmt, std::vector<Expression> args, const Meta& location);
374 
376  void newValueForField(const production::Meta& meta, const Expression& value, const Expression& dd);
377 
382  void enableDefaultNewValueForField(bool enable) { _report_new_value_for_field = enable; };
383 
388  bool isEnabledDefaultNewValueForField() { return _report_new_value_for_field; }
389 
394  Expression newContainerItem(const type::unit::item::Field& field, const Expression& self, const Expression& item,
395  bool need_value);
396 
404  Expression applyConvertExpression(const type::unit::item::Field& field, const Expression& value,
405  std::optional<Expression> dst = {});
406 
414  void trimInput(bool force = false);
415 
422  void initializeUnit(const Location& l);
423 
431  void finalizeUnit(bool success, const Location& l);
432 
434  void initBacktracking();
435 
437  void finishBacktracking();
438 
445  Expression initLoopBody();
446 
455  void finishLoopBody(const Expression& cookie, const Location& l);
456 
466  void guardFeatureCode(const type::Unit& unit, std::string_view feature, std::function<void()> f);
467 
468  CodeGen* cg() const { return _cg; }
469  std::shared_ptr<hilti::Context> context() const;
470  const hilti::Options& options() const;
471 
472 private:
474  CodeGen* _cg;
475 
476  Expression _parseType(const Type& t, const production::Meta& meta, const std::optional<Expression>& dst,
477  bool is_try);
478 
479  std::vector<ParserState> _states;
480  std::vector<std::shared_ptr<hilti::builder::Builder>> _builders;
481  std::map<ID, Expression> _functions;
482  bool _report_new_value_for_field = true;
483 };
484 
485 } // namespace codegen
486 } // namespace spicy::detail
Definition: function.h:71
void enableDefaultNewValueForField(bool enable)
Definition: parser-builder.h:382
Definition: util.h:596
Definition: context.h:33
auto builder()
Definition: parser-builder.h:210
bool isEnabledDefaultNewValueForField()
Definition: parser-builder.h:388
Expression trim
Definition: parser-builder.h:126
std::optional< Expression > captures
Definition: parser-builder.h:147
Expression data
Definition: parser-builder.h:114
Definition: unit.h:57
Definition: production.h:120
Definition: parser-builder.h:85
ParserState state() const
Definition: parser-builder.h:168
Definition: parser-builder.h:151
Definition: struct.h:33
Definition: field.h:22
void pushState(ParserState p)
Definition: parser-builder.h:159
Definition: meta.h:18
void popState()
Definition: parser-builder.h:165
auto popBuilder()
Definition: parser-builder.h:222
Expression lahead_end
Definition: parser-builder.h:138
auto pushBuilder(std::shared_ptr< hilti::builder::Builder > b)
Definition: parser-builder.h:213
Definition: engine.h:16
Definition: type.h:159
bool needs_look_ahead
Definition: parser-builder.h:108
Definition: production.h:40
ID unit_id
Definition: parser-builder.h:105
Definition: builder.h:20
Expression cur
Definition: parser-builder.h:117
Definition: codegen.h:30
auto pushBuilder(std::shared_ptr< hilti::builder::Builder > b, const std::function< void()> &func)
Definition: parser-builder.h:246
Definition: location.h:17
Definition: parser-builder.cc:67
Definition: grammar.h:21
Definition: location.h:93
std::reference_wrapper< const type::Unit > unit
Definition: parser-builder.h:102
Definition: type.h:26
Definition: id.h:18
ScopeGuard makeScopeGuard()
Definition: parser-builder.h:243