Static Value-Flow Analysis
Loading...
Searching...
No Matches
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 <sstream>
33#include <iostream>
34
35#include "CFL/CFGrammar.h"
36#include "CFL/GrammarBuilder.h"
37
38namespace SVF
39{
40const inline std::string GrammarBuilder::parseProductionsString() const
41{
42 std::ifstream textFile(fileName);
43 if (!textFile.is_open())
44 {
45 std::cerr << "Can't open CFL grammar file `" << fileName << "`" << std::endl;
46 abort();
47 }
48
49 std::string lineString;
50 std::string lines = "";
51 std::string startString;
52 std::string symbolString;
53 const std::string WHITESPACE = " \n\r\t\f\v";
54 int lineNum = 0;
55
57 {
58 if (lineNum == 1)
59 {
61 }
62 else if (lineNum == 3)
63 {
64 // Trim leading and trailing whitespace
65 size_t start = lineString.find_first_not_of(WHITESPACE);
66 size_t end = lineString.find_last_not_of(WHITESPACE);
67 if (start != std::string::npos && end != std::string::npos)
68 {
69 symbolString = lineString.substr(start, end - start + 1);
70 }
71 }
72
73 // Append line to `lines` with whitespace trimmed
74 size_t start = lineString.find_first_not_of(WHITESPACE);
75 size_t end = lineString.find_last_not_of(WHITESPACE);
76 if (start != std::string::npos && end != std::string::npos)
77 {
78 lines.append(lineString.substr(start, end - start + 1));
79 }
80
81 lineNum++;
82 }
83
84 // Extract "Productions:" part from `lines` manually
85 size_t productionsPos = lines.find("Productions:");
86 if (productionsPos != std::string::npos)
87 {
88 lines = lines.substr(productionsPos + std::string("Productions:").length());
89 }
90
91 // Parse `symbolString` to insert symbols
92 std::string sString;
93 size_t pos = 0;
94 while ((pos = symbolString.find(" ")) != std::string::npos)
95 {
96 sString = stripSpace(symbolString.substr(0, pos));
97 symbolString.erase(0, pos + 1); // Remove the processed part
99 }
100 // Insert the remaining symbol
102
103 // Set the start kind and add the epsilon terminal
105 grammar->insertTerminalKind("epsilon");
106
107 return lines;
108}
109
110
111const inline std::vector<std::string> GrammarBuilder::loadWordProductions() const
112{
113 size_t pos = 0;
114 std::string lines = parseProductionsString();
115 std::string word = "";
116 std::vector<std::string> wordProds;
117 std::string delimiter = ";";
118 while ((pos = lines.find(";")) != std::string::npos)
119 {
120 word = lines.substr(0, pos);
121 wordProds.push_back(word);
122 lines.erase(0, pos + delimiter.length());
123 }
124 return wordProds;
125}
126
127const inline std::string GrammarBuilder::stripSpace(std::string s) const
128{
129 // Remove leading spaces
130 size_t start = s.find_first_not_of(" ");
131 if (start == std::string::npos)
132 {
133 return ""; // Return an empty string if no non-space character is found
134 }
135
136 // Remove trailing spaces
137 size_t end = s.find_last_not_of(" ");
138 return s.substr(start, end - start + 1);
139}
140
143{
144 std::string delimiter = " ";
145 std::string delimiter1 = "->";
146 std::string word = "";
147 size_t pos;
149 std::vector<std::string> wordProdVec = loadWordProductions();
150
151 for (auto wordProd : wordProdVec)
152 {
153 // Find the position of the '->' delimiter
154 if ((pos = wordProd.find(delimiter1)) != std::string::npos)
155 {
156 // Extract and strip RHS (right-hand side) and LHS (left-hand side)
157 std::string RHS = stripSpace(wordProd.substr(0, pos));
158 std::string LHS = stripSpace(wordProd.substr(pos + delimiter1.size()));
159
160 // Insert RHS symbol into grammar
162 prod.push_back(RHSSymbol);
163
164 // Ensure RHS symbol exists in raw productions
166 {
167 grammar->getRawProductions().insert({RHSSymbol, {}});
168 }
169
170 // Parse LHS string into symbols
171 while ((pos = LHS.find(delimiter)) != std::string::npos)
172 {
173 // Extract each word before the space
174 word = stripSpace(LHS.substr(0, pos));
175 LHS.erase(0, pos + delimiter.length());
176
177 // Insert symbol into production
178 prod.push_back(grammar->insertSymbol(word));
179 }
180
181 // Insert the remaining word (if any) into the production
182 if (!LHS.empty())
183 {
184 prod.push_back(grammar->insertSymbol(stripSpace(LHS)));
185 }
186
187 // Add the production to raw productions
189
190 // Clear the production for the next iteration
191 prod = {};
192 }
193 }
194
195 return grammar;
196}
197
198
199}
char const int length
Definition cJSON.h:163
void setStartKind(Kind startKind)
Definition CFGrammar.h:214
Symbol insertSymbol(std::string strLit)
SymbolMap< Symbol, Productions > & getRawProductions()
Definition CFGrammar.h:194
Kind insertTerminalKind(std::string strLit)
std::vector< Symbol > Production
Definition CFGrammar.h:160
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
const std::vector< std::string > loadWordProductions() const
Parse whole production string to production vector.
for isBitcode
Definition BasicTypes.h:70
llvm::IRBuilder IRBuilder
Definition BasicTypes.h:76