Bitstream Interpretation Library (BIL)  0.1
XDLRCParserImp2.cpp
Go to the documentation of this file.
1 
10 
11 using namespace bil;
12 using namespace bil::xdlrcparser_detail;
13 
14 
15 void XDLRCParserImp::parse1stPrimitiveDefs()
16 {
17  // read primitive definition count
18  size_t count;
19  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
20  if (!m_tok->uintToken(count)) throw Exception();
21  // reserve memory for primitive definitions and pin maps
22  m_primitiveTypes->reserve(count);
23  m_pinMaps.reserve(count);
24 
25  // parse primitive definitions
26  for (;;)
27  {
28  // skip parenthesis
29  if (StreamTokenizer::TT_SEPARATOR != m_tok->nextToken()) throw Exception();
30  if (')' == m_tok->separatorToken()) return;
31  if ('(' != m_tok->separatorToken()) throw Exception();
32 
33  // skip keyword
34  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
35  if (strcmp(m_tok->wordToken(), XDLRCKeywords::PRIMITIVE_DEF) != 0) throw Exception();
36  parse1stPrimitiveDef();
37  }
38 }
39 
40 
41 void XDLRCParserImp::parse1stPrimitiveDef()
42 {
43  // read primitive type name
44  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
45  addPrimitiveType(m_tok->wordToken());
46 
47  // read pin count and reserve pins
48  size_t count;
49  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
50  if (!m_tok->uintToken(count)) throw Exception();
51  m_pins->reserve(count);
52 
53  // read element count and reserve elements
54  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
55  if (!m_tok->uintToken(count)) throw Exception();
56  m_elements->reserve(count);
57 
58  // parse pins
59  for (;;)
60  {
61  // skip parenthesis
62  if (StreamTokenizer::TT_SEPARATOR != m_tok->nextToken()) throw Exception();
63  if (')' == m_tok->separatorToken()) return;
64  if ('(' != m_tok->separatorToken()) throw Exception();
65 
66  // parse pin if keyword matches
67  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
68  if (strcmp(m_tok->wordToken(), XDLRCKeywords::PIN) != 0) break;
69  parse1stPin();
70  }
71 
72  // parse elements
73  for (;;)
74  {
75  // parse an element if keyword matches
76  if (strcmp(m_tok->wordToken(), XDLRCKeywords::ELEMENT) != 0) break;
77  parse1stElement();
78 
79  // skip parenthesis
80  if (StreamTokenizer::TT_SEPARATOR != m_tok->nextToken()) throw Exception();
81  if (')' == m_tok->separatorToken()) return;
82  if ('(' != m_tok->separatorToken()) throw Exception();
83 
84  // skip keyword
85  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
86  }
87 }
88 
89 
90 void XDLRCParserImp::parse1stPin()
91 {
92  // read external pin name and create pin from it
93  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
94  addPin(m_tok->wordToken());
95 
96  // skip internal name
97  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
98 
99  // read input/output keyword
100  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
101  const char* s = m_tok->wordToken();
102  if (strcmp(s, XDLRCKeywords::INPUT) == 0) m_pin->isInput(true);
103  else if (strcmp(s, XDLRCKeywords::OUTPUT) == 0) m_pin->isInput(false);
104  else throw Exception();
105 
106  // skip closing parenthesis
107  if (StreamTokenizer::TT_SEPARATOR != m_tok->nextToken()) throw Exception();
108  if (')' != m_tok->separatorToken()) throw Exception();
109 }
110 
111 
112 void XDLRCParserImp::parse1stElement()
113 {
114  // add element
115  size_t count = m_elements->size();
116  m_elements->push_back(Element());
117  Element& element = (*m_elements)[count];
118  ConfigurationOptions& options = element.options();
119 
120  // read element name
121  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
122  (element.name()).assign(m_tok->wordToken());
123 
124  // skip pin/connection count
125  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
126  if (!m_tok->uintToken(count)) throw Exception();
127 
128  // parse pins
129  for (;;)
130  {
131  // skip parenthesis
132  if (StreamTokenizer::TT_SEPARATOR != m_tok->nextToken()) throw Exception();
133  if (')' == m_tok->separatorToken()) return;
134  if ('(' != m_tok->separatorToken()) throw Exception();
135 
136  // skip keyword
137  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
138  if (strcmp(m_tok->wordToken(), XDLRCKeywords::PIN) != 0) break;
139 
140  // skip name
141  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
142 
143  // skip input/output keyword
144  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
145  const char* s = m_tok->wordToken();
146  if ((strcmp(s, XDLRCKeywords::INPUT) != 0) &&
147  (strcmp(s, XDLRCKeywords::OUTPUT) != 0))
148  throw Exception();
149 
150  // skip closing parenthesis
151  if (StreamTokenizer::TT_SEPARATOR != m_tok->nextToken()) throw Exception();
152  if (')' != m_tok->separatorToken()) throw Exception();
153  }
154 
155  // parse configuration options
156  for (;;)
157  {
158  // parse a configuration option if keyword matches
159  if (strcmp(m_tok->wordToken(), XDLRCKeywords::CFG) != 0) break;
160 
161  // parse option list
162  m_tok->wordChar('#');
163  m_tok->wordChar('<');
164  m_tok->wordChar('>');
165  m_tok->wordChar(':');
166  for (;;)
167  {
168  if (StreamTokenizer::TT_SEPARATOR == m_tok->nextToken()) break;
169  if (StreamTokenizer::TT_WORD != m_tok->tokenType()) throw Exception();
170  options.push_back(m_tok->wordToken());
171  }
172  m_tok->commentChar('#');
173  m_tok->separatorChar('<');
174  m_tok->separatorChar('>');
175  m_tok->separatorChar(':');
176  if (')' != m_tok->separatorToken()) throw Exception();
177 
178  // skip parenthesis
179  if (StreamTokenizer::TT_SEPARATOR != m_tok->nextToken()) throw Exception();
180  if (')' == m_tok->separatorToken()) return;
181  if ('(' != m_tok->separatorToken()) throw Exception();
182 
183  // skip keyword
184  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
185  }
186 
187  // parse connections
188  for (;;)
189  {
190  // parse a connection if keyword matches
191  if (strcmp(m_tok->wordToken(), XDLRCKeywords::CONN) != 0) break;
192 
193  // skip source element name
194  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
195 
196  // skip source element pin
197  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
198 
199  // skip connection symbol
200  m_tok->wordChar('=');
201  m_tok->wordChar('<');
202  m_tok->wordChar('>');
203  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
204  const char* s = m_tok->wordToken();
205  if ((strcmp(s, XDLRCKeywords::CONN_R_SYMBOL) != 0) &&
206  (strcmp(s, XDLRCKeywords::CONN_L_SYMBOL) != 0))
207  throw Exception();
208  m_tok->separatorChar('=');
209  m_tok->separatorChar('<');
210  m_tok->separatorChar('>');
211 
212  // skip destination element name
213  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
214 
215  // skip destination element pin
216  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
217 
218  // skip closing parenthesis
219  if (StreamTokenizer::TT_SEPARATOR != m_tok->nextToken()) throw Exception();
220  if (')' != m_tok->separatorToken()) throw Exception();
221 
222  // skip parenthesis
223  if (StreamTokenizer::TT_SEPARATOR != m_tok->nextToken()) throw Exception();
224  if (')' == m_tok->separatorToken()) return;
225  if ('(' != m_tok->separatorToken()) throw Exception();
226 
227  // skip keyword
228  if (StreamTokenizer::TT_WORD != m_tok->nextToken()) throw Exception();
229  }
230 }