Static Value-Flow Analysis
CFGrammar.h
Go to the documentation of this file.
1 //===----- CFGrammar.h -- Context-free grammar --------------------------//
2 //
3 // SVF: Static Value-Flow Analysis
4 //
5 // Copyright (C) <2013-> <Yulei Sui>
6 //
7 
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as published by
10 // the Free Software Foundation, either version 3 of the License, or
11 // (at your option) any later version.
12 
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
17 
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 //
21 //===----------------------------------------------------------------------===//
22 
23 /*
24  * CFGrammar.h
25  *
26  * Created on: March 5, 2022
27  * Author: Yulei Sui
28  */
29 #ifndef CFLGrammar_H_
30 #define CFLGrammar_H_
31 #include "SVFIR/SVFType.h"
32 
33 namespace SVF
34 {
35 
37 {
38 public:
39  typedef u32_t Kind;
40  typedef u32_t Attribute;
42  typedef struct Symbol
43  {
44  Kind kind: 8;
47 
50 
52  Symbol(const u32_t& num) : kind(num & 0xFF), attribute((num >> 8 ) & 0xFFFF), variableAttribute((num >> 24)) {}
53 
55  operator u32_t()
56  {
57  static_assert(sizeof(struct Symbol)==sizeof(u32_t), "sizeof(struct Symbol)!=sizeof(u32_t)");
58  u32_t num = 0;
59  num += this->variableAttribute << 24;
60  num += this->attribute << 8;
61  num += this->kind;
62  return num;
63  }
64 
65  operator u32_t() const
66  {
67  static_assert(sizeof(struct Symbol)==sizeof(u32_t), "sizeof(struct Symbol)!=sizeof(u32_t)");
68  u32_t num = 0;
69  num += this->variableAttribute << 24;
70  num += this->attribute << 8;
71  num += this->kind;
72  return num;
73  }
74 
75  bool operator<(const Symbol& rhs)
76  {
77  return u32_t(*this) < u32_t(rhs);
78  }
79 
80  void operator=(const u32_t& i)
81  {
82  this->kind = EdgeKindMask & i;
83  this->attribute = i >> EdgeKindMaskBits;
85  }
86 
87  void operator=(unsigned long long num)
88  {
89  this->kind = num & 0xFF;
90  this->attribute = (num >> 8 ) & 0xFFFF;
91  this->variableAttribute = num >> 24;
92  }
93 
94  bool operator==(const Symbol& s)
95  {
96  return ((this->kind == s.kind) && (this->attribute == s.attribute) && (this->variableAttribute == s.variableAttribute));
97  }
98 
99  bool operator==(const Symbol& s) const
100  {
101  return ((kind == s.kind) && (attribute == s.attribute) && (variableAttribute == s.variableAttribute));
102  }
103 
104  bool operator!=(const Symbol& s) const
105  {
106  return ! (*this == s) ;
107  }
108 
109  bool operator==(const u32_t& i)
110  {
111  return u32_t(*this) == u32_t(i);
112  }
113 
114  bool operator==(const Kind& k) const
115  {
116  return (this->kind == k);
117  }
119 
121  {
122  public:
123  size_t operator()(const Symbol &s) const
124  {
125  std::hash<u32_t> h;
126  return h(u32_t(s));
127  }
128  };
129 
130 
132  {
133  size_t operator()(const std::vector<Symbol> &v) const
134  {
135  size_t h = v.size();
136 
137  SymbolHash hf;
138  for (const Symbol &t : v)
139  {
140  h ^= hf(t) + 0x9e3779b9 + (h << 6) + (h >> 2);
141  }
142 
143  return h;
144  }
145  };
146 
147  template<typename Key, typename Value, typename Hash = SymbolHash,
148  typename KeyEqual = std::equal_to<Key>,
149  typename Allocator = std::allocator<std::pair<const Key, Value>>>
150  using SymbolMap = std::unordered_map<Key, Value, Hash, KeyEqual, Allocator>;
151 
152  template <typename Key, typename Hash = SymbolVectorHash, typename KeyEqual = std::equal_to<Key>,
153  typename Allocator = std::allocator<Key>>
154  using SymbolSet = std::unordered_set<Key, Hash, KeyEqual, Allocator>;
155 
156  typedef std::vector<Symbol> Production;
158 
159 
161  {
162  return this->nonterminals;
163  }
164 
166  {
167  this->nonterminals = nonterminals;
168  }
169 
171  {
172  return this->terminals;
173  }
174 
176  {
177  this->terminals = terminals;
178  }
179 
181  {
182  return this->EBNFSigns;
183  }
184 
186  {
187  this->EBNFSigns = EBNFSigns;
188  }
189 
191  {
192  return this->rawProductions;
193  }
194 
196  {
197  return this->kindToAttrsMap;
198  }
199 
200  inline Kind getTotalKind()
201  {
202  return this->totalKind;
203  }
204 
205  inline Kind getStartKind()
206  {
207  return this->startKind;
208  }
209 
210  inline void setStartKind(Kind startKind)
211  {
212  this->startKind = startKind;
213  }
214 
216  {
217  this->totalKind = totalKind;
218  }
219 
220  std::string extractKindStrFromSymbolStr(const std::string& symbolStr) const;
221 
223 
224  void setRawProductions(SymbolMap<Symbol, Productions>& rawProductions);
225 
227 
228  void setAttributeKinds(const Set<Kind>& attributeKind);
229 
230  Kind strToKind(std::string str) const;
231 
232  Symbol strToSymbol(const std::string str) const;
233 
234  std::string kindToStr(Kind kind) const;
235 
236  std::string symToStrDump(Symbol sym) const;
237 
238  Symbol getSymbol(const Production& prod, u32_t pos)
239  {
240  return prod.at(pos);
241  }
242 
243  inline const Set<Kind>& getAttrSyms() const
244  {
245  return this->attributeKinds;
246  }
247 
249  Kind insertNonterminalKind(std::string const kindStr);
250 
254 
256 
258 
260 
262 
263  void insertAttribute(Kind kind, Attribute a);
264 
265  inline static Kind getAttributedKind(Attribute attribute, Kind kind)
266  {
267  return ((attribute << EdgeKindMaskBits)| kind );
268  }
269 
270  inline static Kind getVariabledKind(VariableAttribute variableAttribute, Kind kind)
271  {
272  return ((variableAttribute << AttributedKindMaskBits) | kind);
273  }
274 
275 protected:
276  static constexpr unsigned char EdgeKindMaskBits = 8;
277  static constexpr unsigned char AttributedKindMaskBits = 24;
278  static constexpr u64_t EdgeKindMask = (~0ULL) >> (64 - EdgeKindMaskBits);
280 private:
288 };
289 
290 class CFGrammar : public GrammarBase
291 {
292 
293 public:
294  CFGrammar();
295 
297 
298  static inline bool classof(const CFGrammar *)
299  {
300  return true;
301  }
302 
303  static inline bool classof(const GrammarBase *node)
304  {
305  return true;
306  }
307 
309  {
310  return epsilonProds;
311  }
312 
314  {
315  return singleRHSToProds;
316  }
317 
319  {
320  return firstRHSToProds;
321  }
322 
324  {
325  return secondRHSToProds;
326  }
327 
328  const bool hasProdsFromFirstRHS(const Symbol sym) const
329  {
330  auto it = firstRHSToProds.find(sym);
331  return it!=firstRHSToProds.end();
332  }
333 
334  const bool hasProdsFromSingleRHS(const Symbol sym) const
335  {
336  auto it = singleRHSToProds.find(sym);
337  return it!=singleRHSToProds.end();
338  }
339 
340  const bool hasProdsFromSecondRHS(const Symbol sym) const
341  {
342  auto it = secondRHSToProds.find(sym);
343  return it!=secondRHSToProds.end();
344  }
345 
346  const Productions& getProdsFromSingleRHS(const Symbol sym) const
347  {
348  auto it = singleRHSToProds.find(sym);
349  assert(it!=singleRHSToProds.end() && "production (X -> sym) not found for sym!!");
350  return it->second;
351  }
352 
353  const Productions& getProdsFromFirstRHS(const Symbol sym) const
354  {
355  auto it = firstRHSToProds.find(sym);
356  assert(it!=firstRHSToProds.end() && "production (X -> sym Y ) not found for sym!!");
357  return it->second;
358  }
359 
360  const Productions& getProdsFromSecondRHS(const Symbol sym) const
361  {
362  auto it = secondRHSToProds.find(sym);
363  assert(it!=secondRHSToProds.end() && "production (X -> Y sym) not found for sym!!");
364  return it->second;
365  }
366 
367 
368  const Symbol& getLHSSymbol(const Production& prod) const
369  {
370  return prod.at(0);
371  }
372 
373  const Symbol& getFirstRHSSymbol(const Production& prod) const
374  {
375  return prod.at(1);
376  }
377 
378  const Symbol& getSecondRHSSymbol(const Production& prod) const
379  {
380  return prod.at(2);
381  }
382 
383  void dump() const;
384 
385  void dump(std::string fileName) const;
386 
387 
388  const inline u32_t num_generator()
389  {
390  return newTerminalSubscript++;
391  }
392 
393 private:
399 };
400 
406 template<class Data>
408 {
410  typedef std::deque<Data> DataDeque;
411 public:
413 
415 
416  inline bool empty() const
417  {
418  return data_list.empty();
419  }
420 
421  inline bool find(Data data) const
422  {
423  return (data_set.find(data) == data_set.end() ? false : true);
424  }
425 
429  inline bool push(Data data)
430  {
431  if (data_set.find(data) == data_set.end())
432  {
433  data_list.push_back(data);
434  data_set.insert(data);
435  return true;
436  }
437  else
438  return false;
439  }
440 
444  inline Data pop()
445  {
446  assert(!empty() && "work list is empty");
447  Data data = data_list.front();
448  data_list.pop_front();
449  data_set.erase(data);
450  return data;
451  }
452 
456  inline void clear()
457  {
458  data_list.clear();
459  data_set.clear();
460  }
461 
462 private:
465 };
466 
467 }
468 #endif /* CFLGrammar_H_ */
cJSON * a
Definition: cJSON.cpp:2560
const char *const string
Definition: cJSON.h:172
SymbolMap< Symbol, Productions > firstRHSToProds
Definition: CFGrammar.h:396
void dump() const
Definition: CFGrammar.cpp:346
const Productions & getProdsFromSingleRHS(const Symbol sym) const
Definition: CFGrammar.h:346
const Productions & getProdsFromFirstRHS(const Symbol sym) const
Definition: CFGrammar.h:353
SymbolMap< Symbol, Productions > & getSecondRHSToProds()
Definition: CFGrammar.h:323
const Productions & getProdsFromSecondRHS(const Symbol sym) const
Definition: CFGrammar.h:360
const Symbol & getFirstRHSSymbol(const Production &prod) const
Definition: CFGrammar.h:373
const u32_t num_generator()
Definition: CFGrammar.h:388
const Symbol & getLHSSymbol(const Production &prod) const
Definition: CFGrammar.h:368
SymbolSet< Production > epsilonProds
Definition: CFGrammar.h:394
const bool hasProdsFromFirstRHS(const Symbol sym) const
Definition: CFGrammar.h:328
const bool hasProdsFromSecondRHS(const Symbol sym) const
Definition: CFGrammar.h:340
SymbolMap< Symbol, Productions > singleRHSToProds
Definition: CFGrammar.h:395
Productions & getEpsilonProds()
Definition: CFGrammar.h:308
SymbolMap< Symbol, Productions > & getSingleRHSToProds()
Definition: CFGrammar.h:313
static bool classof(const GrammarBase *node)
Definition: CFGrammar.h:303
static bool classof(const CFGrammar *)
Methods for support type inquiry through isa, cast, and dyn_cast:
Definition: CFGrammar.h:298
SymbolMap< Symbol, Productions > secondRHSToProds
Definition: CFGrammar.h:397
SymbolMap< Symbol, Productions > & getFirstRHSToProds()
Definition: CFGrammar.h:318
u32_t newTerminalSubscript
Definition: CFGrammar.h:398
const Symbol & getSecondRHSSymbol(const Production &prod) const
Definition: CFGrammar.h:378
const bool hasProdsFromSingleRHS(const Symbol sym) const
Definition: CFGrammar.h:334
GrammarBase::SymbolSet< Data > DataSet
Definition: CFGrammar.h:409
bool find(Data data) const
Definition: CFGrammar.h:421
DataDeque data_list
work list using std::vector.
Definition: CFGrammar.h:464
DataSet data_set
store all data in the work list.
Definition: CFGrammar.h:463
bool empty() const
Definition: CFGrammar.h:416
std::deque< Data > DataDeque
Definition: CFGrammar.h:410
bool push(Data data)
Definition: CFGrammar.h:429
size_t operator()(const Symbol &s) const
Definition: CFGrammar.h:123
Map< std::string, Kind > & getNonterminals()
Definition: CFGrammar.h:160
Map< std::string, Kind > terminals
Definition: CFGrammar.h:282
void setKindToAttrsMap(const Map< Kind, Set< Attribute >> &kindToAttrsMap)
Definition: CFGrammar.cpp:45
std::string extractAttributeStrFromSymbolStr(const std::string &symbolStr) const
Definition: CFGrammar.cpp:219
void setStartKind(Kind startKind)
Definition: CFGrammar.h:210
void setAttributeKinds(const Set< Kind > &attributeKind)
Definition: CFGrammar.cpp:50
const Set< Kind > & getAttrSyms() const
Definition: CFGrammar.h:243
Symbol insertEBNFSigns(std::string strLit)
Definition: CFGrammar.cpp:311
static constexpr unsigned char AttributedKindMaskBits
We use the lower 24 bits to denote attributed kind.
Definition: CFGrammar.h:277
void setRawProductions(SymbolMap< Symbol, Productions > &rawProductions)
Definition: CFGrammar.cpp:40
std::string extractKindStrFromSymbolStr(const std::string &symbolStr) const
Definition: CFGrammar.cpp:207
void setTotalKind(Kind totalKind)
Definition: CFGrammar.h:215
Kind strToKind(std::string str) const
Definition: CFGrammar.cpp:55
Symbol insertSymbol(std::string strLit)
Definition: CFGrammar.cpp:231
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > SymbolMap
Definition: CFGrammar.h:150
Map< std::string, Kind > & getTerminals()
Definition: CFGrammar.h:170
SymbolMap< Symbol, Productions > & getRawProductions()
Definition: CFGrammar.h:190
Symbol strToSymbol(const std::string str) const
Definition: CFGrammar.cpp:74
std::string symToStrDump(Symbol sym) const
Definition: CFGrammar.cpp:139
Map< std::string, Kind > & getEBNFSigns()
Definition: CFGrammar.h:180
SymbolMap< Symbol, Productions > rawProductions
Definition: CFGrammar.h:286
Symbol insertNonTerminalSymbol(std::string strLit)
Definition: CFGrammar.cpp:249
u32_t VariableAttribute
Definition: CFGrammar.h:41
SymbolSet< Production > Productions
Definition: CFGrammar.h:157
Symbol insertTerminalSymbol(std::string strLit)
Definition: CFGrammar.cpp:280
struct SVF::GrammarBase::Symbol Symbol
Kind getTotalKind()
Definition: CFGrammar.h:200
Map< Kind, Set< Attribute > > kindToAttrsMap
Definition: CFGrammar.h:285
Map< std::string, Kind > EBNFSigns
Definition: CFGrammar.h:283
std::unordered_set< Key, Hash, KeyEqual, Allocator > SymbolSet
Definition: CFGrammar.h:154
Kind getStartKind()
Definition: CFGrammar.h:205
static constexpr u64_t EdgeKindMask
Definition: CFGrammar.h:278
void insertAttribute(Kind kind, Attribute a)
Definition: CFGrammar.cpp:327
Map< std::string, Kind > nonterminals
Definition: CFGrammar.h:281
Kind insertNonterminalKind(std::string const kindStr)
Insert kind to nonterminal and return kind.
Definition: CFGrammar.cpp:192
Set< Kind > attributeKinds
Map contains Signs' String and associated Symbols.
Definition: CFGrammar.h:284
std::string kindToStr(Kind kind) const
Definition: CFGrammar.cpp:103
Kind insertTerminalKind(std::string strLit)
Definition: CFGrammar.cpp:177
const Map< Kind, Set< Attribute > > & getKindToAttrsMap() const
Definition: CFGrammar.h:195
static Kind getVariabledKind(VariableAttribute variableAttribute, Kind kind)
Definition: CFGrammar.h:270
void setEBNFSigns(Map< std::string, Kind > &EBNFSigns)
Definition: CFGrammar.h:185
static constexpr unsigned char EdgeKindMaskBits
We use the lower 8 bits to denote edge kind.
Definition: CFGrammar.h:276
void setTerminals(Map< std::string, Kind > &terminals)
Definition: CFGrammar.h:175
std::vector< Symbol > Production
Definition: CFGrammar.h:156
static Kind getAttributedKind(Attribute attribute, Kind kind)
Definition: CFGrammar.h:265
Symbol getSymbol(const Production &prod, u32_t pos)
Definition: CFGrammar.h:238
void setNonterminals(Map< std::string, Kind > &nonterminals)
Definition: CFGrammar.h:165
for isBitcode
Definition: BasicTypes.h:68
unsigned long long u64_t
Definition: GeneralType.h:48
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map
Definition: GeneralType.h:101
llvm::Value Value
LLVM Basic classes.
Definition: BasicTypes.h:82
unsigned u32_t
Definition: GeneralType.h:46
std::unordered_set< Key, Hash, KeyEqual, Allocator > Set
Definition: GeneralType.h:96
size_t operator()(const std::vector< Symbol > &v) const
Definition: CFGrammar.h:133
bool operator<(const Symbol &rhs)
Definition: CFGrammar.h:75
bool operator==(const Symbol &s)
Definition: CFGrammar.h:94
bool operator!=(const Symbol &s) const
Definition: CFGrammar.h:104
void operator=(const u32_t &i)
Definition: CFGrammar.h:80
bool operator==(const Kind &k) const
Definition: CFGrammar.h:114
bool operator==(const Symbol &s) const
Definition: CFGrammar.h:99
Symbol(const u32_t &num)
Construct from u32_t move the bit to right field.
Definition: CFGrammar.h:52
void operator=(unsigned long long num)
Definition: CFGrammar.h:87
bool operator==(const u32_t &i)
Definition: CFGrammar.h:109
Symbol()
Default Value for Symbol is 0.
Definition: CFGrammar.h:49
VariableAttribute variableAttribute
Definition: CFGrammar.h:46
provide extra hash function for std::pair handling
Definition: GeneralType.h:85