Bitstream Interpretation Library (BIL)  0.1
XDLParserImp2.cpp
Go to the documentation of this file.
1 
10 
11 using namespace bil;
12 using namespace bil::xdlparser_detail;
13 
14 
15 void XDLParserImp::parseInstance()
16 {
17  // read instance name and create new instance
18  parseQuotedString();
19  addInstance(m_quoteBuffer);
20 
21  // read primitive type name
22  parseQuotedString();
23  m_instance->primitiveTypeIndex(findPrimitiveType(m_quoteBuffer));
24 
25  // skip comma
26  if (StreamTokenizer::TT_SEPARATOR != m_tok->nextToken()) throw Exception();
27  if (',' != m_tok->separatorToken()) throw Exception();
28 
29  // read placement flag
30  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
31  const char* keyword = m_tok->wordToken();
32  if (strcmp(keyword, XDLKeywords::PLACED) == 0)
33  {
34  // set placement flag
35  m_instance->placed(true);
36  m_instance->bonded(false);
37 
38  // read tile name
39  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
40  size_t tileIndex = findTile(m_tok->wordToken());
41  m_instance->tileIndex(tileIndex);
42 
43  // read primitive site name
44  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
45  size_t siteIndex = findPrimitiveSite(m_tok->wordToken(), tileIndex);
46  m_instance->primitiveSiteIndex(siteIndex);
47 
48  // skip comma
49  if (StreamTokenizer::TT_SEPARATOR != m_tok->nextToken()) throw Exception();
50  if (',' != m_tok->separatorToken()) throw Exception();
51  }
52  else if (strcmp(keyword, XDLKeywords::UNPLACED) == 0)
53  {
54  // set placement flag
55  m_instance->placed(false);
56 
57  StreamTokenizer::token_t tokenType = m_tok->nextToken();
58  if (StreamTokenizer::TT_SEPARATOR == tokenType)
59  {
60  // no bonded flag, just comma
61  m_instance->bonded(true);
62  if (',' != m_tok->separatorToken()) throw Exception();
63  }
64  else if (StreamTokenizer::TT_WORD == tokenType)
65  {
66  // bonded flag present, check it
67  keyword = m_tok->wordToken();
68  if (strcmp(keyword, XDLKeywords::BONDED) == 0) m_instance->bonded(true);
69  else if (strcmp(keyword, XDLKeywords::UNBONDED) == 0) m_instance->bonded(false);
70  else throw Exception();
71 
72  // skip comma
73  if (StreamTokenizer::TT_SEPARATOR != m_tok->nextToken()) throw Exception();
74  if (',' != m_tok->separatorToken()) throw Exception();
75  }
76  else throw Exception();
77  }
78  else throw Exception();
79 
80  // skip keyword
81  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
82  if (strcmp(m_tok->wordToken(), XDLKeywords::CFG) != 0) throw Exception();
83 
84  // skip cfg string
85  parseQuotedString();
86  (m_instance->attributes()).assign(m_quoteBuffer);
87 
88  // skip semicolon
89  if (StreamTokenizer::TT_SEPARATOR != m_tok->nextToken()) throw Exception();
90  if (';' != m_tok->separatorToken()) throw Exception();
91 }
92 
93 
94 void XDLParserImp::parseNet()
95 {
96  // read net name and create new net
97  parseQuotedString();
98  addNet(m_quoteBuffer);
99  // cache references to its pins and pips
100  PinRefs& pinRefs = m_net->pinRefs();
101  PIPRefs& pipRefs = m_net->pipRefs();
102 
103  // check if net type present
104  StreamTokenizer::token_t tokenType = m_tok->nextToken();
105  if (StreamTokenizer::TT_WORD == tokenType)
106  {
107  // read net type and set it
108  m_net->type(NetType::fromString(m_tok->wordToken()));
109  // skip comma
110  if (StreamTokenizer::TT_SEPARATOR != m_tok->nextToken()) throw Exception();
111  if (',' != m_tok->separatorToken()) throw Exception();
112  }
113  else
114  {
115  // default net type
116  m_net->type(NetType::WIRE);
117  // skip comma
118  if (StreamTokenizer::TT_SEPARATOR != tokenType) throw Exception();
119  if (',' != m_tok->separatorToken()) throw Exception();
120  }
121 
122  // parse out pins
123  const char* keyword = 0;
124  PinRef pinRef;
125  for (;;)
126  {
127  // get next token
128  tokenType = m_tok->nextToken();
129  if (StreamTokenizer::TT_WORD != tokenType) break;
130  keyword = m_tok->wordToken();
131 
132  // check if current token is out pin keyword
133  if (strcmp(keyword, XDLKeywords::OUTPIN)) break;
134 
135  // parse instance name
136  parseQuotedString();
137  size_t instanceIndex = findInstance(m_quoteBuffer);
138  pinRef.instanceIndex(instanceIndex);
139 
140  // read pin name
141  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
142  size_t pinIndex = findPin(m_tok->wordToken(), instanceIndex);
143  pinRef.pinIndex(pinIndex);
144 
145  // add pin to net
146  pinRefs.push_back(pinRef);
147 
148  // skip comma
149  if (StreamTokenizer::TT_SEPARATOR != m_tok->nextToken()) throw Exception();
150  if (',' != m_tok->separatorToken()) throw Exception();
151  }
152 
153  // parse in pins
154  for (;;)
155  {
156  // check if current token is in pin keyword
157  if (StreamTokenizer::TT_WORD != tokenType) break;
158  if (strcmp(keyword, XDLKeywords::INPIN) != 0) break;
159 
160  // parse instance name
161  parseQuotedString();
162  size_t instanceIndex = findInstance(m_quoteBuffer);
163  pinRef.instanceIndex(instanceIndex);
164 
165  // read pin name
166  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
167  size_t pinIndex = findPin(m_tok->wordToken(), instanceIndex);
168  pinRef.pinIndex(pinIndex);
169 
170  // add pin to net
171  pinRefs.push_back(pinRef);
172 
173  // skip comma
174  if (StreamTokenizer::TT_SEPARATOR != m_tok->nextToken()) throw Exception();
175  if (',' != m_tok->separatorToken()) throw Exception();
176 
177  // get next token
178  tokenType = m_tok->nextToken();
179  if (StreamTokenizer::TT_WORD != tokenType) break;
180  keyword = m_tok->wordToken();
181  }
182 
183  // parse PIPs
184  PIPRef pipRef;
185  PIP pip;
186  for (;;)
187  {
188  // check if current token is in PIP keyword
189  if (StreamTokenizer::TT_WORD != tokenType) break;
190  if (strcmp(keyword, XDLKeywords::PIP) != 0) break;
191 
192  // read tile name
193  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
194  size_t tileIndex = findTile(m_tok->wordToken());
195  pipRef.tileIndex(tileIndex);
196  // get tile
197  const Tile& tile = m_tiles->at(tileIndex);
198  // get tile type and its maps
199  TileTypeEx& tileTypeEx = m_wirePIPMaps.at(tile.typeIndex());
200  nameIndexMap_t& wireMap = tileTypeEx.wireMap;
201  pipIndexMap_t& pipMap = tileTypeEx.pipMap;
202 
203  // read start wire
204  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
205  size_t wireIndex = findWire(m_tok->wordToken(), wireMap);
206  pip.startWireIndex(static_cast<unsigned short>(wireIndex));
207 
208  // read PIP direction keyword
209  m_tok->wordChar('=');
210  m_tok->wordChar('>');
211  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
212  pip.direction(PIPDirection::fromString(m_tok->wordToken()));
213  m_tok->separatorChar('=');
214  m_tok->separatorChar('>');
215 
216  // read end wire
217  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
218  wireIndex = findWire(m_tok->wordToken(), wireMap);
219  pip.endWireIndex(static_cast<unsigned short>(wireIndex));
220 
221  // lookup PIP index, and add PIPRef to net
222  pipRef.pipIndex(findPIP(pip, pipMap));
223  pipRefs.push_back(pipRef);
224 
225  // skip comma
226  if (StreamTokenizer::TT_SEPARATOR != m_tok->nextToken()) throw Exception();
227  if (',' != m_tok->separatorToken()) throw Exception();
228 
229  // get next token
230  tokenType = m_tok->nextToken();
231  if (StreamTokenizer::TT_WORD != tokenType) break;
232  keyword = m_tok->wordToken();
233  }
234 
235  // parse cfg node
236  if (StreamTokenizer::TT_WORD == tokenType)
237  {
238  // skip keyword
239  if (strcmp(keyword, XDLKeywords::CFG) != 0) throw Exception();
240  // parse cfg string
241  parseQuotedString();
242  (m_net->attributes()).assign(m_quoteBuffer);
243  // skip comma
244  if (StreamTokenizer::TT_SEPARATOR != m_tok->nextToken()) throw Exception();
245  if (',' != m_tok->separatorToken()) throw Exception();
246  // read next token
247  tokenType = m_tok->nextToken();
248  }
249 
250  // skip semicolon
251  if (StreamTokenizer::TT_SEPARATOR != tokenType) throw Exception();
252  if (';' != m_tok->separatorToken()) throw Exception();
253 }
254 
255 
256 void XDLParserImp::parseQuotedString()
257 {
258  // clear buffer
259  char* quotePtr = m_quoteBuffer;
260  char* quoteBufferEnd = quotePtr + QUOTE_BUFFER_SIZE;
261 
262  // skip double quote beginning
263  if (StreamTokenizer::TT_SEPARATOR != m_tok->nextToken()) throw Exception();
264  if ('"' != m_tok->separatorToken()) throw Exception();
265 
266  // parse contents char by char
267  m_tok->resetSyntax();
268  bool escapeChar = false;
269  for (;;)
270  {
271  // get next char
272  if (StreamTokenizer::TT_SEPARATOR != m_tok->nextToken())
273  throw Exception();
274  char c = m_tok->separatorToken();
275 
276  // examine current char based on escape state
277  if (escapeChar)
278  {
279  escapeChar = false;
280  if ('"' == c)
281  {
282  if (quotePtr < quoteBufferEnd) *(quotePtr++) = '"';
283  }
284  else
285  {
286  if (quotePtr < quoteBufferEnd) *(quotePtr++) = '\\';
287  if (quotePtr < quoteBufferEnd) *(quotePtr++) = c;
288  }
289  }
290  else
291  {
292  if ('"' == c) break;
293  else if ('\\' == c) escapeChar = true;
294  else
295  {
296  if (quotePtr < quoteBufferEnd) *(quotePtr++) = c;
297  }
298  }
299  }
300 
301  // terminate quote
302  *quotePtr = 0;
303  // restore normal syntax
304  setupSyntax();
305 }