Static Value-Flow Analysis
GrammarBuilder.cpp
Go to the documentation of this file.
1 //===----- GrammarBuilder.cpp -- Grammar Builder--------------//
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  * GrammarBuilder.h
25  *
26  * Created on: April 27, 2022
27  * Author: Pei Xu
28  */
29 
30 #include <string>
31 #include <fstream>
32 #include <regex>
33 #include <sstream>
34 #include <iostream>
35 #include "CFL/GrammarBuilder.h"
36 
37 namespace SVF
38 {
40 {
41  std::ifstream textFile(fileName);
42  if (!textFile.is_open())
43  {
44  std::cerr << "Can't open CFL grammar file `" << fileName << "`" << std::endl;
45  abort();
46  }
47  std::string lineString;
48  std::string lines = "";
49  std::string startString;
50  std::string symbolString;
51  const std::string WHITESPACE = " \n\r\t\f\v";
52  int lineNum = 0;
53  while (getline(textFile, lineString))
54  {
55  if(lineNum == 1)
56  {
57  startString = stripSpace(lineString);
58  }
59  if(lineNum == 3)
60  {
61  symbolString = lineString.substr(lineString.find_first_not_of(WHITESPACE), lineString.find_last_not_of(WHITESPACE)+1);
62  }
63 
64  lines.append(lineString.substr(lineString.find_first_not_of(WHITESPACE), lineString.find_last_not_of(WHITESPACE)+1));
65  lineNum++;
66  }
67 
68  std::regex reg("Start:([\\s\\S]*)Terminal:(.*)Productions:([\\s\\S]*)");
69  std::smatch matches;
70  if (std::regex_search(lines, matches, reg))
71  {
72  lines = matches.str(3);
73  }
74  std::string sString;
75  size_t pos = 0;
76  while ((pos = symbolString.find(" ")) != std::string::npos)
77  {
78  sString = stripSpace(symbolString.substr(0, pos));
79  symbolString.erase(0, pos + 1); //Capital is Nonterminal, Otherwise is terminal
80  grammar->insertSymbol(sString);
81  }
82  grammar->insertSymbol(symbolString);
83  grammar->setStartKind(grammar->insertSymbol(startString));
84  grammar->insertTerminalKind("epsilon");
85 
86  return lines;
87 }
88 
89 const inline std::vector<std::string> GrammarBuilder::loadWordProductions() const
90 {
91  size_t pos = 0;
93  std::string word = "";
94  std::vector<std::string> wordProds;
95  std::string delimiter = ";";
96  while ((pos = lines.find(";")) != std::string::npos)
97  {
98  word = lines.substr(0, pos);
99  wordProds.push_back(word);
100  lines.erase(0, pos + delimiter.length());
101  }
102  return wordProds;
103 }
104 
106 {
107  std::smatch matches;
108  std::regex stripReg("\\s*(\\S*)\\s*");
109  std::regex_search(s, matches, stripReg);
110  return matches.str(1);
111 }
112 
113 
116 {
117  std::smatch matches;
118  std::string delimiter = " ";
119  std::string delimiter1 = "->";
120  std::string word = "";
121  size_t pos;
123  std::vector<std::string> wordProdVec = loadWordProductions();
124 
125  for (auto wordProd : wordProdVec)
126  {
127  if ((pos = wordProd.find(delimiter1)) != std::string::npos)
128  {
129  std::string RHS = stripSpace(wordProd.substr(0, pos));
130  std::string LHS = wordProd.substr(pos + delimiter1.size(), wordProd.size() - 1);
131  GrammarBase::Symbol RHSSymbol = grammar->insertSymbol(RHS);
132  prod.push_back(RHSSymbol);
133  if (grammar->getRawProductions().find(RHSSymbol) == grammar->getRawProductions().end()) grammar->getRawProductions().insert({RHSSymbol, {}});
134  std::regex LHSRegEx("\\s*(.*)");
135  std::regex_search(LHS, matches, LHSRegEx);
136  LHS = matches.str(1);
137  while ((pos = LHS.find(delimiter)) != std::string::npos)
138  {
139  word = LHS.substr(0, pos);
140  LHS.erase(0, pos + delimiter.length()); //Capital is Nonterminal, Otherwise is terminal
141  prod.push_back(grammar->insertSymbol(word));
142  }
143  prod.push_back(grammar->insertSymbol(LHS));
144  grammar->getRawProductions().at(RHSSymbol).insert(prod);
145  prod = {};
146  }
147  }
148 
149  return grammar;
150 };
151 
152 }
const char *const string
Definition: cJSON.h:172
void setStartKind(Kind startKind)
Definition: CFGrammar.h:210
Symbol insertSymbol(std::string strLit)
Definition: CFGrammar.cpp:231
SymbolMap< Symbol, Productions > & getRawProductions()
Definition: CFGrammar.h:190
Kind insertTerminalKind(std::string strLit)
Definition: CFGrammar.cpp:177
std::vector< Symbol > Production
Definition: CFGrammar.h:156
GrammarBase * build() const
Build grammarBase from fileName.
const std::string parseProductionsString() const
Parse start symbol and production from file string.
const std::string stripSpace(std::string s) const
Strip front and tail space.
GrammarBase * grammar
std::string fileName
const std::vector< std::string > loadWordProductions() const
Parse whole production string to production vector.
for isBitcode
Definition: BasicTypes.h:68