Static Value-Flow Analysis
Loading...
Searching...
No Matches
CFGNormalizer.cpp
Go to the documentation of this file.
1//===----- CFGNormalizer.cpp -- Context Free Grammar Normalizer--------------//
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 * CFGNormalizer.cpp
25 *
26 * Created on: April 19 , 2022
27 * Author: Pei Xu
28 */
29
30#include "CFL/CFGNormalizer.h"
31
32#include <algorithm>
33#include <string>
34#include <fstream>
35#include <sstream>
36#include <iostream>
37
38using namespace SVF;
39
41{
42 CFGrammar *grammar = new CFGrammar();
43 grammar->setStartKind(generalGrammar->getStartKind());
44 grammar->setTerminals(generalGrammar->getTerminals());
45 grammar->setNonterminals(generalGrammar->getNonterminals());
46 grammar->setEBNFSigns(generalGrammar->getEBNFSigns());
47 grammar->setTotalKind(generalGrammar->getTotalKind());
48 grammar->setAttributeKinds(generalGrammar->getAttrSyms());
49 grammar->setKindToAttrsMap(generalGrammar->getKindToAttrsMap());
50 grammar->setRawProductions(generalGrammar->getRawProductions());
51 barReplace(grammar);
52 ebnfSignReplace('*', grammar);
53 ebnfSignReplace('?', grammar);
54 ebnf_bin(grammar);
55 fillAttribute(grammar, grammar->getKindToAttrsMap());
56 return grammar;
57}
58
59
61{
62 NodeSet nodeSet = {};
63 for (auto pair: kindToAttrsMap)
64 {
65 for (auto attri: pair.second)
66 {
67 nodeSet.insert(attri);
68 }
69 }
70 for(auto symProdsPair: grammar->getRawProductions())
71 {
72 for(auto prod: symProdsPair.second)
73 {
77 tempP.insert(tempP.begin(), symProdsPair.first);
79 getFilledProductions(tempP, nodeSet, grammar, normalProds);
80 for (auto filledProd : normalProds)
81 {
83 }
84 }
85 }
86
87 return grammar;
88}
89
91{
93 std::string tempStr = "";
94 removeFirstSymbol(grammar);
95
96 auto rawProductions = grammar->getRawProductions();
97
98 for(auto itr : rawProductions)
99 {
100 auto head = *(grammar->getRawProductions().find(itr.first));
101 for(auto rule: head.second)
102 {
103 if (rule.size() < 3) continue;
104
106 GrammarBase::Production long_run(rule.begin() + 1, rule.end());
107 auto it = grammar->getRawProductions()[head.first].find(rule);
108 grammar->getRawProductions()[head.first].erase(it);
110 if (X == u32_t(-1))
111 {
112 X = check_head(grammar->getRawProductions(), long_run);
113 }
114 if ((X == u32_t(-1)) == false)
115 {
116 rule = {first, X};
117 grammar->getRawProductions()[head.first].insert(rule);
118 }
119 else
120 {
121 tempStr = "X";
122 std::ostringstream ss;
123 ss << grammar->num_generator();
124 tempStr.append(ss.str());
130 for (unsigned i = 0; i < long_run.size(); i++)
131 {
132 GrammarBase::VariableAttribute variableAttribute = long_run[i].variableAttribute;
133 if ( variableAttribute != 0)
134 {
135 variableAttributeSet.insert(variableAttribute);
136 }
137 }
138 if ( variableAttributeSet.size() == 1)
139 {
140 tempStr += "_";
141 tempStr += char(*variableAttributeSet.begin());
142 }
144 rule = {first, tempSym};
145 grammar->getRawProductions()[head.first].insert(rule);
146 X = tempSym;
147 }
148 new_grammar[X] = {};
151 if (long_run.size() ==2)
152 {
153 new_grammar[X].insert(temp_p);
154 long_run.clear();
155 }
156 else
157 {
158 new_grammar[X].insert(long_run);
159 RHX = X;
160 }
161 while (long_run.size() > 2)
162 {
163 first = long_run[0];
165 long_run.erase(long_run.begin());
166
167 X = RHX;
169
171 if (RHX == u32_t(-1))
172 {
174 }
175 if(RHX == u32_t(-1))
176 {
177 tempStr = "X";
178 std::ostringstream ss;
179 ss << grammar->num_generator();
180 tempStr.append(ss.str());
182 for (unsigned i = 0; i < long_run.size(); i++)
183 {
184 GrammarBase::VariableAttribute variableAttribute = long_run[i].variableAttribute;
185 if ( variableAttribute != 0)
186 {
187 variableAttributeSet.insert(variableAttribute);
188 }
189 }
190 if ( variableAttributeSet.size() == 1)
191 {
192 tempStr += "_";
193 tempStr += char(*variableAttributeSet.begin());
194 }
196 auto it = new_grammar[X].find(prev_rule);
197 new_grammar[X].erase(it);
198 new_grammar[X].insert({first, tempSym});
200 RHX = tempSym;
201 }
202 }
203 }
204 }
205 for (auto new_head : new_grammar)
206 {
207 for (auto prod : new_head.second)
208 {
209 auto it = grammar->getRawProductions()[new_head.first].find(prod);
210 if (it == grammar->getRawProductions()[new_head.first].end())
211 {
212 grammar->getRawProductions()[new_head.first].insert(prod);
213 }
214 }
215 }
216}
217
223{
224 normalProds.clear();
226 worklist.push(prod);
227 while( worklist.empty() == false )
228 {
232 // GrammarBase::Kind baseKind;
234 {
235 if ( currentVariableAttribute == 0 )
236 {
237 currentVariableAttribute = symbol.variableAttribute;
238 // baseKind = symbol.kind;
239 }
240 }
241 if ( currentVariableAttribute == 0)
242 {
244 continue;
245 }
246 //*(kindToAttriMap.find(baseKind));
247 //for (auto attribute : nodeSet.second)
248 for (auto attribute : nodeSet)
249 {
252 {
253 if ( symbol.variableAttribute == currentVariableAttribute)
254 {
255 symbol.attribute = attribute;
256 symbol.variableAttribute = 0;
257 }
258 }
260 bool continueToFill = false;
262 {
263 if ( symbol.variableAttribute != 0 )
264 {
265 continueToFill = true;
266 }
267 }
268 if ( continueToFill == false)
269 {
271 }
272 else
273 {
274 worklist.push(fillingProduction);
275 }
276 }
277 }
278}
279
281{
282 int index = i;
283 while (index >= 0)
284 {
285 if (grammar->kindToStr(prod[index].kind) == "(")
286 {
287 return index;
288 }
289 index--;
290 }
291 return 0;
292}
293
295{
296 for (auto &symbolToProductionsPair : grammar->getRawProductions())
297 {
299 //GrammarBase::Productions Originalproductions = symbolToProductionsPair.second;
300 for (auto ebnfProduction : symbolToProductionsPair.second)
301 {
302 size_t i = 1;
303 size_t j = 1;
304 while (i < ebnfProduction.size())
305 {
306 if (grammar->kindToStr(ebnfProduction[i].kind) == "|")
307 {
309 tempPro.insert(tempPro.begin(), symbolToProductionsPair.first );
310 productions.insert(tempPro);
311 j = i+1;
312 }
313 i++;
314 }
316 tempPro.insert(tempPro.begin(), symbolToProductionsPair.first );
317 productions.insert(tempPro);
318 }
319 symbolToProductionsPair.second.clear();
321 }
322}
323
325{
329 std::string tempNonterminal = "X";
330
331 for (auto &symbolToProductionsPair : grammar->getRawProductions())
332 {
334 for (auto ebnfProduction : symbolToProductionsPair.second)
335 {
336 size_t i = 1;
337 while (i < ebnfProduction.size())
338 {
340 if (grammar->kindToStr(ebnfProduction[i].kind) == std::string(1, sign))
341 {
343 assert(i != 1 && "sign in grammar associate with no symbol");
344 if (grammar->kindToStr(ebnfProduction[i - 1].kind) != std::string(1, ')'))
345 {
346 signGroupStart = i - 1;
347 }
349 else
350 {
352 }
353 std::string groupString = "";
354 for (size_t j = signGroupStart; j < i; j++)
355 {
356 groupString.append(grammar->kindToStr(ebnfProduction[j].kind));
357 groupString.append(" ");
358 }
359 groupString.append(grammar->kindToStr(ebnfProduction[i].kind));
360 if (newProductions.find(groupString) != newProductions.end())
361 {
363 ebnfProduction.erase(ebnfProduction.begin() + signGroupStart, ebnfProduction.begin() + i + 1);
366 }
367 else if ( (signGroupStart == 1) && (i == ebnfProduction.size() -1))
368 {
371 ebnfProduction.erase(ebnfProduction.begin() + signGroupStart, ebnfProduction.begin() + i + 1);
372
373 }
374 else
375 {
376 tempNonterminal = "X";
377 std::ostringstream ss;
378 ss << grammar->num_generator();
379 tempNonterminal.append(ss.str());
382 ebnfProduction.erase(ebnfProduction.begin() + signGroupStart, ebnfProduction.begin() + i + 1);
386 }
387
389 }
390 i++;
391 }
392 }
394 }
395 for(auto rep: newProductions)
396 {
398 std::string new_nonterminal = rep.second;
400 grammar->getRawProductions()[grammar->strToSymbol(new_nonterminal)].insert(temp_list);
403 if (sign == '*' || sign == '?')
404 {
407 strTrans(rep.first, grammar, normalProd);
409 if (sign == '*')
410 {
411 for (auto &word : normalProd)
412 {
413 if (word != grammar->strToSymbol("*") && word != grammar->strToSymbol("(") && word != grammar->strToSymbol(")"))
414 {
415 withoutSign.push_back(word);
416 }
417 }
418 withoutSign.push_back(grammar->strToSymbol(rep.second));
419 }
420 if (sign == '?')
421 {
422 for (auto &word : normalProd)
423 {
424 if (word != grammar->strToSymbol("?") && word != grammar->strToSymbol("(") && word != grammar->strToSymbol(")"))
425 {
426 withoutSign.push_back(word);
427 }
428 }
429 }
430 temp_list.insert(temp_list.end(), withoutSign.begin(), withoutSign.end());
431 }
432 grammar->getRawProductions()[grammar->strToSymbol(new_nonterminal)].insert(temp_list);
433 }
434}
435
437{
438 // Find the position of the first non-whitespace character
439 size_t start = LHS.find_first_not_of(" \t\n\r");
440 // If the string contains non-whitespace characters, remove leading spaces
441 if (start != std::string::npos)
442 {
443 LHS = LHS.substr(start);
444 }
445 else
446 {
447 // If the string contains only spaces, clear it
448 LHS.clear();
449 }
450
451 std::string delimiter;
452 size_t pos;
453 std::string word;
454
455 delimiter = " ";
456 while ((pos = LHS.find(delimiter)) != std::string::npos)
457 {
458 word = LHS.substr(0, pos);
459 LHS.erase(0, pos + delimiter.length());
460 normalProd.push_back(grammar->strToSymbol(word));
461 }
462 normalProd.push_back(grammar->strToSymbol(LHS));
463}
464
465
467{
468 for(auto symProdPair: grammar)
469 {
470 for(auto prod: symProdPair.second)
471 {
472 if (rule == prod)
473 {
474 return symProdPair.first;
475 }
476 }
477 }
479 return symbol;
480}
481
484{
485 if (prod.size() == 2)
486 {
487 if ((std::find(prod.begin(), prod.end(), grammar->strToKind("epsilon")) != prod.end()))
488 {
489 if (std::find(grammar->getEpsilonProds().begin(), grammar->getEpsilonProds().end(), prod) == grammar->getEpsilonProds().end())
490 {
491 grammar->getEpsilonProds().insert(prod);
492 }
493 }
494 else
495 {
496 grammar->getSingleRHSToProds()[prod[1]].insert(prod);
497 }
498 }
499 if (prod.size() == 3)
500 {
501 grammar->getFirstRHSToProds()[prod[1]].insert(prod);
502 grammar->getSecondRHSToProds()[prod[2]].insert(prod);
503 }
504}
505
507{
508 // Remove First Terminal
509 for(auto head : grammar->getRawProductions())
510 {
511 for(auto rule: head.second)
512 {
513
515 long_run.erase(long_run.begin());
516 auto it = grammar->getRawProductions().at(head.first).find(rule);
517 grammar->getRawProductions().at(head.first).erase(it);
518 grammar->getRawProductions()[head.first].insert(long_run);
519 }
520 }
521}
int index
Definition cJSON.h:170
void barReplace(CFGrammar *grammar)
void ebnf_bin(CFGrammar *grammar)
Add nonterminal to tranfer long rules to binary rules.
void ebnfSignReplace(char sign, CFGrammar *grammar)
void insertToCFLGrammar(CFGrammar *grammar, GrammarBase::Production &prod)
Based on prod size to add on suitable member field of grammar.
void removeFirstSymbol(CFGrammar *grammar)
CFGrammar * fillAttribute(CFGrammar *grammar, const Map< CFGrammar::Kind, Set< CFGrammar::Attribute > > &kindToAttrsMap)
Expand every variable attribute in rawProductions of grammarbase.
CFGrammar * normalize(GrammarBase *generalGrammar)
Binary Normal Form(BNF) normalization with variable attribute expanded.
int ebnfBracketMatch(GrammarBase::Production &prod, int i, CFGrammar *grammar)
void getFilledProductions(GrammarBase::Production &prod, const NodeSet &nodeSet, CFGrammar *grammar, GrammarBase::Productions &normalProds)
void strTrans(std::string strPro, CFGrammar *grammar, GrammarBase::Production &normalProd)
GrammarBase::Symbol check_head(GrammarBase::SymbolMap< GrammarBase::Symbol, GrammarBase::Productions > &grammar, GrammarBase::Production &rule)
SymbolMap< Symbol, Productions > & getFirstRHSToProds()
Definition CFGrammar.h:322
SymbolMap< Symbol, Productions > & getSingleRHSToProds()
Definition CFGrammar.h:317
const u32_t num_generator()
Definition CFGrammar.h:392
SymbolMap< Symbol, Productions > & getSecondRHSToProds()
Definition CFGrammar.h:327
Productions & getEpsilonProds()
Definition CFGrammar.h:312
bool empty() const
Definition CFGrammar.h:420
bool push(Data data)
Definition CFGrammar.h:433
void setStartKind(Kind startKind)
Definition CFGrammar.h:214
void setAttributeKinds(const Set< Kind > &attributeKind)
Definition CFGrammar.cpp:52
const Map< Kind, Set< Attribute > > & getKindToAttrsMap() const
Definition CFGrammar.h:199
void setRawProductions(SymbolMap< Symbol, Productions > &rawProductions)
Definition CFGrammar.cpp:42
void setTotalKind(Kind totalKind)
Definition CFGrammar.h:219
Kind strToKind(std::string str) const
Definition CFGrammar.cpp:57
Symbol strToSymbol(const std::string str) const
Definition CFGrammar.cpp:76
Symbol insertNonTerminalSymbol(std::string strLit)
SymbolMap< Symbol, Productions > & getRawProductions()
Definition CFGrammar.h:194
u32_t VariableAttribute
Definition CFGrammar.h:45
SymbolSet< Production > Productions
Definition CFGrammar.h:161
Map< Key, Value, Hash, KeyEqual, Allocator > SymbolMap
Definition CFGrammar.h:154
void setKindToAttrsMap(const Map< Kind, Set< Attribute > > &kindToAttrsMap)
Definition CFGrammar.cpp:47
std::string kindToStr(Kind kind) const
void setEBNFSigns(Map< std::string, Kind > &EBNFSigns)
Definition CFGrammar.h:189
void setTerminals(Map< std::string, Kind > &terminals)
Definition CFGrammar.h:179
std::vector< Symbol > Production
Definition CFGrammar.h:160
void setNonterminals(Map< std::string, Kind > &nonterminals)
Definition CFGrammar.h:169
for isBitcode
Definition BasicTypes.h:70
Set< NodeID > NodeSet
Definition GeneralType.h:87
std::unordered_map< Key, Value, Hash, KeyEqual, Allocator > Map
Definition GeneralType.h:56
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76
signed s32_t
Definition GeneralType.h:68
unsigned u32_t
Definition GeneralType.h:67