Spicy
production.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 #include <utility>
8 #include <vector>
9 
10 #include <hilti/ast/location.h>
11 #include <hilti/base/result.h>
12 #include <hilti/global.h>
13 
14 namespace spicy {
15 
16 using hilti::Location;
17 using hilti::Nothing;
18 using hilti::Result;
19 namespace location = hilti::location;
20 
21 namespace trait {
22 class isProduction {};
23 class isTerminal {};
24 class isNonTerminal {};
25 class isLiteral : public isTerminal {};
26 } // namespace trait
27 } // namespace spicy
28 
29 #include <hilti/base/type_erase.h>
30 
31 #include <spicy/ast/types/unit-items/field.h>
32 
33 namespace spicy::detail::codegen {
34 
35 class Production;
36 
37 namespace production {
38 
39 /* Meta data that the parser builder associates with a production. */
40 class Meta {
41 public:
43  auto field() const { return _value<type::unit::item::Field>(_field); }
44 
50  bool isFieldProduction() const { return _field && _is_field_production; }
51 
56  auto container() const { return _value<type::unit::item::Field>(_container); }
57 
62  auto forEach() const { return _value<type::unit::item::Field>(_for_each); }
63 
64  void setField(const NodeRef& n, bool is_field_production) {
65  assert(n);
66  _is_field_production = is_field_production;
67  _field = n;
68  }
69 
70  void setContainer(const NodeRef& n) {
71  assert(n);
72  _container = n;
73  }
74 
75  void setForEach(const NodeRef& n) {
76  assert(n);
77  _for_each = n;
78  }
79 
80  NodeRef fieldRef() const { return NodeRef(_field); }
81  NodeRef containerRef() const { return NodeRef(_container); }
82 
83 private:
84  template<class T>
85  hilti::optional_ref<const T> _value(const NodeRef& n) const {
86  if ( n )
87  return n->as<T>();
88 
89  return {};
90  }
91 
92  bool _is_field_production = false;
93  NodeRef _field;
94  NodeRef _container;
95  NodeRef _for_each;
96 };
97 
98 #include <spicy/autogen/__production.h>
99 
103 extern std::string to_string(const Production& p);
104 
109 extern int64_t tokenID(const std::string& p);
110 
111 } // namespace production
112 
120 class Production final : public production::Production_ {
121 public:
123  template<typename T, typename std::enable_if_t<std::is_base_of<trait::isProduction, T>::value>* = nullptr>
124  Production(T t) : codegen::production::Production_(std::move(t)) {}
125 
126  ~Production() final = default;
127  Production() = default;
128  Production(const Production&) = default;
129  Production(Production&&) noexcept = default;
130  Production& operator=(const Production&) = default;
131  Production& operator=(Production&&) = default;
132 
136  explicit operator std::string() const { return to_string(*this); }
137 };
138 
140 inline std::ostream& operator<<(std::ostream& out, const Production& p) {
141  out << to_string(p);
142  return out;
143 }
144 
146 inline bool operator==(const Production& p1, const Production& p2) {
147  if ( &p1 == &p2 )
148  return true;
149 
150  return p1.symbol() == p2.symbol();
151 }
152 
154 inline bool operator<(const Production& p1, const Production& p2) { return p1.symbol() < p2.symbol(); }
155 
156 namespace production {
161 extern bool nullable(const std::vector<std::vector<Production>>& rhss);
162 
163 } // namespace production
164 
171 public:
181  ProductionBase(std::string symbol, Location l = location::None)
182  : _symbol(std::move(symbol)), _location(std::move(l)), _meta(new production::Meta()) {}
183 
185  bool hasSize() const { return meta().field() && AttributeSet::find(meta().field()->attributes(), "&size"); }
186 
188  bool maySynchronize() const {
189  return meta().field() && AttributeSet::find(meta().field()->attributes(), "&synchronize");
190  }
191 
193  const Location& location() const { return _location; }
194 
196  const std::string& symbol() const { return _symbol; }
197 
199  void setSymbol(const std::string& s) { _symbol = s; }
200 
202  std::optional<Expression> filter() const { return _filter; }
203 
205  void setFilter(const Expression& filter) { _filter = filter; }
206 
208  std::optional<Expression> sink() const { return _sink; }
209 
211  void setSink(const Expression& sink) { _sink = sink; }
212 
214  const production::Meta& meta() const { return *_meta; }
215 
217  void setMeta(production::Meta m) { *_meta = std::move(m); }
218 
220  std::shared_ptr<production::Meta> _metaInstance() const { return _meta; }
221 
222  void _setMetaInstance(std::shared_ptr<production::Meta> m) { _meta = std::move(m); }
223 
224 private:
225  std::string _symbol;
226  Location _location;
227  std::optional<Expression> _filter;
228  std::optional<Expression> _sink;
229  std::shared_ptr<production::Meta> _meta;
230 };
231 
232 } // namespace spicy::detail::codegen
auto forEach() const
Definition: production.h:62
Definition: production.h:22
const production::Meta & meta() const
Definition: production.h:214
auto field() const
Definition: production.h:43
void setSink(const Expression &sink)
Definition: production.h:211
auto container() const
Definition: production.h:56
Definition: production.h:24
void setSymbol(const std::string &s)
Definition: production.h:199
Definition: production.h:120
Definition: optional.h:79
void setMeta(production::Meta m)
Definition: production.h:217
const std::string & symbol() const
Definition: production.h:196
bool maySynchronize() const
Definition: production.h:188
bool hasSize() const
Definition: production.h:185
Definition: production.h:170
Definition: meta.h:18
Production(T t)
Definition: production.h:124
Definition: production.h:25
Definition: production.h:23
Definition: optional-ref.h:22
void setFilter(const Expression &filter)
Definition: production.h:205
Definition: production.h:40
std::optional< Expression > sink() const
Definition: production.h:208
bool isFieldProduction() const
Definition: production.h:50
std::shared_ptr< production::Meta > _metaInstance() const
Definition: production.h:220
const Location & location() const
Definition: production.h:193
Definition: unit.h:22
std::optional< Attribute > find(std::string_view tag) const
Definition: attribute.h:190
std::optional< Expression > filter() const
Definition: production.h:202
Definition: node_ref.h:44
Definition: location.h:17
Definition: location.h:86
Definition: result.h:57
ProductionBase(std::string symbol, Location l=location::None)
Definition: production.h:181
Definition: result.h:67