Spicy
resolved.h
1 // Copyright (c) 2020-2021 by the Zeek Project. See LICENSE for details.
2 
3 #pragma once
4 
5 #include <memory>
6 #include <string>
7 
8 #include <spicy/compiler/detail/codegen/production.h>
9 
10 namespace spicy::detail::codegen {
11 class Grammar;
12 } // namespace spicy::detail::codegen
13 
15 
16 /*
17  * Place-holder production that's resolved through a `Grammar` later. This
18  * can used to be create to self-recursive grammars.
19  *
20  * @note This option doesn't actually implement most of the `Production` API
21  * (meaniningfully).
22  */
23 class Resolved : public ProductionBase {
24 public:
25  Resolved(const Location& l = location::None)
26  : ProductionBase("", l),
27  _symbol(std::make_shared<std::string>("<unresolved>")),
28  _rsymbol(hilti::util::fmt("ref:%d", ++_cnt)) {}
29  std::string render() const { return symbol(); }
30 
31  const std::string& symbol() const { return *_symbol; }
32  const std::string& referencedSymbol() const { return _rsymbol; }
33 
34  void resolve(const std::string& symbol) { *_symbol = symbol; }
35 
36  // Production API methods are meaningless for this one.
37  bool nullable() const { return false; }
38  bool eodOk() const { return false; }
39  bool atomic() const { return true; }
40  std::optional<spicy::Type> type() const { return {}; }
41 
42 public:
43  std::shared_ptr<std::string> _symbol;
44  std::string _rsymbol;
45 
46  inline static int _cnt = 0;
47 };
48 
49 // Alias the name for clarity. The idea is that initiallu one creates
50 // `Unresolved` instances. Once they have been resolved, one then operates on
51 // `Resolved` instances. Internally, however, the two are the same.
52 using Unresolved = Resolved;
53 
54 } // namespace spicy::detail::codegen::production
Definition: production.h:170
Definition: grammar.h:15
std::string fmt(const char *fmt, const Args &... args)
Definition: util.h:80
Definition: unit.h:28
Definition: location.h:17
ProductionBase(std::string symbol, Location l=location::None)
Definition: production.h:181