/
parser.cpp
196 lines (177 loc) · 4.14 KB
/
parser.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
#include <iostream>
#include <ostream>
#include <fstream>
#include <sstream>
#include <string>
#include <regex.h>
#include "design.h"
#include "gate.h"
#include "net.h"
using namespace std;
enum {COMMENT, BLANK, MODULE, INPUT, OUTPUT, WIRE, GATE, END, ERROR};
#define ID "[A-Za-z_][A-Za-z0-9_]*"
#define NUM "[0-9]+"
#define GATE_TYPE ""and" | "or" | "nand" | "nor" | "xor" | "not""
int lineType(string currentline);
string getID(string characters);
void parenParser(vector<string> *ports, string input);
void gateInfo(string type, string info, map<string, vector<string> > *gates);
Design *parseThatShit(string ifilename)
{
string designName;
vector<string> port_list;
vector<string> inputs;
vector<string> outputs;
vector<string> wires;
map<string, vector<string> > gates;
ifstream ifile(ifilename.c_str(), ifstream::in);
while(ifile.good())
{
string currentline;
getline(ifile, currentline);
stringstream ss(currentline);
string firsttoken;
ss >> firsttoken;
switch(lineType(firsttoken))
{
case COMMENT :
// comment line
break;
case BLANK :
break;
case MODULE :
{
// line defining a module
string possibleIDModule;
getline(ss ,possibleIDModule, '(');
designName = getID(possibleIDModule); // get name
string possiblePortsModule;
getline(ss, possiblePortsModule, ')');
parenParser(&port_list, possiblePortsModule);
break;
}
case INPUT :
{
// input line
string possibleIDInput;
getline(ss,possibleIDInput,';'); // get up to semicolon
inputs.push_back(getID(possibleIDInput)); // get id from selection and add it to the list of inputs
break;
}
case OUTPUT :
{
// output line
string possibleIDOutput;
getline(ss,possibleIDOutput,';'); // get up to semicolon
outputs.push_back(getID(possibleIDOutput)); // get id from selection and add it to the list of outputs
break;
}
case WIRE :
{
// wire line
string possibleIDWire;
getline(ss,possibleIDWire,';'); // get up to semicolon
wires.push_back(getID(possibleIDWire)); // get id from selection and add it to the list of wires
break;
}
case GATE :
{
// gate line
string possibleGateInfo;
getline(ss,possibleGateInfo,'('); // get up to the port list stuff
gateInfo(firsttoken, possibleGateInfo, &gates);
vector<string> currentGatePuts;
string possiblePorts;
getline(ss,possiblePorts, ')');
parenParser(¤tGatePuts,possiblePorts);
// create the gate here
break;
}
case END :
{
// done!
break;
}
case ERROR :
{
// error...
break;
}
}
}
}
int lineType(string identifier) // going line by line, so decide what kind of line this is
{
if(identifier == "//")
{
return COMMENT;
}
else if(identifier == "module")
{
return MODULE;
}
else if(identifier == "input")
{
return INPUT;
}
else if(identifier == "output")
{
return OUTPUT;
}
else if(identifier == "wire")
{
return WIRE;
}
else if((identifier == "and") | (identifier == "or") | (identifier == "nand") | (identifier == "nor") | (identifier == "xor") | (identifier == "not"))
{
return GATE;
}
else if(identifier == "endmodule")
{
return END;
}
else
{
return ERROR;
}
}
string getID(string input)
{
regex rgx(ID);
smatch result;
regex_search(input, result, rgx);
return result.str();
}
void parenParser(vector<string>* ports, string input)
{
stringstream ss(input);
while(!ss.fail()) // runs last time when eof bit is set!
{
string port;
if(ss.eof()) { // time to grab last num and leave!
ss.unget();
port = ss.get();
ports->push_back(port);
break;
}
getline(ss, port, ',');
ports->push_back(port);
}
}
void gateInfo(string type, string info, map<string, vector<string> > *gates)
{
// looking for type of gate and delay info (if there) and gate name
stringstream ss(info);
string delay, name;
if(ss.peek() == '#') { // a gate delay is defined!!
ss.seekg(ios::cur + 1);
ss >> delay >> name;
(*gates)[name].push_back(type);
(*gates)[name].push_back(delay);
}
else {
ss >> name;
(*gates)[name].push_back(type);
(*gates)[name].push_back("1");
}
}