This diff has been collapsed as it changes many lines, (1128 lines changed) Show them Hide them | |||
@@ -0,0 +1,1128 | |||
|
1 | #include "vhdl_element_parser.h" | |
|
2 | #include <QDebug> | |
|
3 | ||
|
4 | #define ERROR_EXPECTING(node,expectedKW) qDebug()<<"Error expected "<< (expectedKW) <<" @line " <<(node)->line <<" column "<<(node)->column<<"\n" | |
|
5 | ||
|
6 | #define CHECK_TOKEN(rootNode,node,expectedType,expectedTypeText) \ | |
|
7 | if(Q_UNLIKELY((node)->type!=(expectedType))) \ | |
|
8 | {\ | |
|
9 | ERROR_EXPECTING((node),expectedTypeText); \ | |
|
10 | } | |
|
11 | ||
|
12 | #define CHECK_TOKEN_EXIT(rootNode,node,expectedType,expectedTypeText) \ | |
|
13 | if(Q_UNLIKELY((node)->type!=(expectedType))) \ | |
|
14 | {\ | |
|
15 | ERROR_EXPECTING((node),expectedTypeText); \ | |
|
16 | *(rootNode)=(node); \ | |
|
17 | return -1; \ | |
|
18 | }\ | |
|
19 | ||
|
20 | ||
|
21 | ||
|
22 | bool VHDL_Tools::isInContext(QStack<VHDL_Tools::VHDL_AST_Node *> openBlocksContext, VHDL_Tools::VHDL_AST_Node_type type) | |
|
23 | { | |
|
24 | while (openBlocksContext.count()) | |
|
25 | { | |
|
26 | //Copy of the stack -> pop() is safe | |
|
27 | if(openBlocksContext.pop()->type==type) | |
|
28 | { | |
|
29 | return true; | |
|
30 | } | |
|
31 | } | |
|
32 | return false; | |
|
33 | } | |
|
34 | ||
|
35 | int VHDL_Tools::parse_Entity(VHDL_Tools::VHDL_AST_Node **rootNode, QStack<VHDL_Tools::VHDL_AST_Node *> *openBlocksContext) | |
|
36 | { | |
|
37 | VHDL_AST_Node *currentNode=*rootNode; | |
|
38 | openBlocksContext->append(currentNode); | |
|
39 | VHDL_AST_Node *startNode = currentNode; | |
|
40 | walk_forward(¤tNode,-1); | |
|
41 | CHECK_TOKEN_EXIT(rootNode,currentNode,identifier,"Type identifier"); | |
|
42 | walk_forward(¤tNode,-1); | |
|
43 | CHECK_TOKEN_EXIT(rootNode,currentNode,is,"\"is\" keyword"); | |
|
44 | walk_forward(¤tNode,-1); | |
|
45 | if(currentNode->type==generic) | |
|
46 | { | |
|
47 | parse_Port_or_Generic(¤tNode,openBlocksContext); | |
|
48 | } | |
|
49 | if(currentNode->type==port) | |
|
50 | { | |
|
51 | parse_Port_or_Generic(¤tNode,openBlocksContext); | |
|
52 | } | |
|
53 | if(currentNode->type!=endKw) | |
|
54 | { | |
|
55 | parse_DeclarativeBlock(¤tNode,openBlocksContext,false); | |
|
56 | do | |
|
57 | { | |
|
58 | walk_forward(¤tNode,-1); | |
|
59 | if(Q_UNLIKELY(currentNode->type==leftParen)) | |
|
60 | { | |
|
61 | openBlocksContext->push(currentNode); | |
|
62 | } | |
|
63 | else | |
|
64 | { | |
|
65 | if(Q_UNLIKELY(currentNode->type==rightParen)) | |
|
66 | { | |
|
67 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()); | |
|
68 | } | |
|
69 | } | |
|
70 | }while(((currentNode->type!=endKw) || (startNode!=openBlocksContext->top())) && currentNode->childs.count()); | |
|
71 | } | |
|
72 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()<<identifier,true,true); | |
|
73 | *rootNode=currentNode; | |
|
74 | return 0; | |
|
75 | } | |
|
76 | ||
|
77 | int VHDL_Tools::parse_Function(VHDL_Tools::VHDL_AST_Node **rootNode, QStack<VHDL_Tools::VHDL_AST_Node *> *openBlocksContext) | |
|
78 | { | |
|
79 | VHDL_AST_Node* startNode = *rootNode; | |
|
80 | VHDL_AST_Node* currentNode = *rootNode; | |
|
81 | openBlocksContext->push(startNode); | |
|
82 | walk_forward(¤tNode,-1); // skip Function | |
|
83 | walk_forward(¤tNode,-1); // skip Name | |
|
84 | parse_InterfaceList(¤tNode,openBlocksContext); | |
|
85 | if(Q_UNLIKELY(currentNode->type!=return_t) ) | |
|
86 | { | |
|
87 | qDebug()<<"Error expected return Keyword @line " <<currentNode->line <<" column "<<currentNode->column<<"\n"; | |
|
88 | } | |
|
89 | walk_forward(¤tNode,-1); | |
|
90 | if(Q_UNLIKELY(currentNode->type!=identifier)) | |
|
91 | { | |
|
92 | qDebug()<<"Error expected return type @line " <<currentNode->line <<" column "<<currentNode->column<<"\n"; | |
|
93 | } | |
|
94 | walk_forward(¤tNode,-1); | |
|
95 | *rootNode=currentNode; | |
|
96 | if(currentNode->type==is) | |
|
97 | { | |
|
98 | walk_forward(rootNode,-1); //skip is | |
|
99 | parse_DeclarativeBlock(rootNode,openBlocksContext); | |
|
100 | startNode->type=static_cast<VHDL_AST_Node_type>(startNode->type | closedByEnd); | |
|
101 | return parse_body(rootNode,openBlocksContext); | |
|
102 | } | |
|
103 | else | |
|
104 | { | |
|
105 | startNode->type=static_cast<VHDL_AST_Node_type>(currentNode->type | closedBySemicolon); | |
|
106 | closeAndMatchBlock(rootNode,openBlocksContext,QList<VHDL_AST_Node_type>()); | |
|
107 | } | |
|
108 | return -1; | |
|
109 | } | |
|
110 | ||
|
111 | int VHDL_Tools::parse_Attribute(VHDL_Tools::VHDL_AST_Node **rootNode, QStack<VHDL_Tools::VHDL_AST_Node *> *openBlocksContext) | |
|
112 | { | |
|
113 | VHDL_AST_Node* startNode = *rootNode; | |
|
114 | VHDL_AST_Node* currentNode = *rootNode; | |
|
115 | openBlocksContext->push(startNode); | |
|
116 | while(currentNode->type!=semicolon) | |
|
117 | { | |
|
118 | walk_forward(¤tNode,-1); | |
|
119 | } | |
|
120 | *rootNode=currentNode; | |
|
121 | closeAndMatchBlock(rootNode,openBlocksContext,QList<VHDL_AST_Node_type>()); | |
|
122 | return 0; | |
|
123 | } | |
|
124 | ||
|
125 | int VHDL_Tools::parse_Package(VHDL_Tools::VHDL_AST_Node **rootNode, QStack<VHDL_Tools::VHDL_AST_Node *> *openBlocksContext) | |
|
126 | { | |
|
127 | VHDL_AST_Node *currentNode=*rootNode; | |
|
128 | openBlocksContext->append(currentNode); | |
|
129 | parse_DeclarativeBlock(¤tNode,openBlocksContext,false); | |
|
130 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()<<identifier,true,true); | |
|
131 | *rootNode =currentNode; | |
|
132 | return 0; | |
|
133 | } | |
|
134 | ||
|
135 | int VHDL_Tools::closeAndMatchBlock(VHDL_Tools::VHDL_AST_Node** currentNode,QStack<VHDL_Tools::VHDL_AST_Node*>* openBlocksContext,QList<VHDL_Tools::VHDL_AST_Node_type>skipTypes,bool skipOpenType,bool endWithSemicolon) | |
|
136 | { | |
|
137 | if(openBlocksContext->size()) | |
|
138 | { | |
|
139 | VHDL_AST_Node* startNode = openBlocksContext->pop(); | |
|
140 | ||
|
141 | if( IS_CLOSED_BY(startNode->type,(*currentNode)->type)) | |
|
142 | { | |
|
143 | walk_forward(currentNode,-1); | |
|
144 | if(skipOpenType) | |
|
145 | { | |
|
146 | skipTokens((*currentNode),(startNode->type)); | |
|
147 | } | |
|
148 | for(int i=0;i<skipTypes.length();i++) | |
|
149 | { | |
|
150 | skipTokens((*currentNode),skipTypes.at(i)); | |
|
151 | } | |
|
152 | if(endWithSemicolon && ((*currentNode)->type==semicolon)) | |
|
153 | { | |
|
154 | if(walk_forward(currentNode,-1)!=-1) | |
|
155 | (*currentNode)->move(startNode->parent()); | |
|
156 | } | |
|
157 | else | |
|
158 | { | |
|
159 | (*currentNode)->move(startNode->parent()); | |
|
160 | } | |
|
161 | } | |
|
162 | else | |
|
163 | { | |
|
164 | // TODO improve message ! | |
|
165 | qDebug() << "Got unexpected close token! @ line:" << (*currentNode)->line << " column:"<< (*currentNode)->column; | |
|
166 | } | |
|
167 | } | |
|
168 | else | |
|
169 | { | |
|
170 | walk_forward(currentNode,-1); | |
|
171 | return -1; | |
|
172 | } | |
|
173 | return 0; | |
|
174 | } | |
|
175 | ||
|
176 | int VHDL_Tools::parse_body(VHDL_Tools::VHDL_AST_Node **rootNode, QStack<VHDL_Tools::VHDL_AST_Node *> *openBlocksContext) | |
|
177 | { | |
|
178 | VHDL_AST_Node *currentNode=*rootNode; | |
|
179 | VHDL_AST_Node *startNode=openBlocksContext->top(); | |
|
180 | if(Q_UNLIKELY(currentNode->type!=begin)) | |
|
181 | { | |
|
182 | qDebug()<<"Error expected begin keyword @line " <<currentNode->line <<" column "<<currentNode->column<<"\n"; | |
|
183 | return -1; | |
|
184 | } | |
|
185 | walk_forward(¤tNode,-1); | |
|
186 | while (currentNode->childs.count()) | |
|
187 | { | |
|
188 | switch (currentNode->type) | |
|
189 | { | |
|
190 | case block: | |
|
191 | if(!isInContext(*openBlocksContext,attribute)) | |
|
192 | openBlocksContext->push(currentNode); | |
|
193 | walk_forward(¤tNode,-1); | |
|
194 | break; | |
|
195 | case process: | |
|
196 | if(!isInContext(*openBlocksContext,attribute)) | |
|
197 | parse_Process(¤tNode,openBlocksContext); | |
|
198 | // openBlocksContext->push(currentNode); | |
|
199 | walk_forward(¤tNode,-1); | |
|
200 | break; | |
|
201 | case wait: | |
|
202 | parse_Wait(¤tNode,openBlocksContext); | |
|
203 | break; | |
|
204 | case component: | |
|
205 | parse_Component(¤tNode,openBlocksContext); | |
|
206 | break; | |
|
207 | case endKw: | |
|
208 | if(openBlocksContext->top()==startNode) | |
|
209 | { | |
|
210 | *rootNode=currentNode; | |
|
211 | closeAndMatchBlock(rootNode,openBlocksContext,QList<VHDL_AST_Node_type>()<<identifier,true,true); | |
|
212 | return 0; | |
|
213 | } | |
|
214 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()<<loop<<block<<identifier,true,true); | |
|
215 | break; | |
|
216 | case attribute: | |
|
217 | parse_Attribute(¤tNode,openBlocksContext); | |
|
218 | break; | |
|
219 | case constant: | |
|
220 | if(!isInContext(*openBlocksContext,procedure) && !isInContext(*openBlocksContext,function) && !isInContext(*openBlocksContext,attribute)) | |
|
221 | openBlocksContext->push(currentNode); | |
|
222 | walk_forward(¤tNode,-1); | |
|
223 | break; | |
|
224 | case signal: | |
|
225 | parse_Signal_or_Constant(¤tNode,openBlocksContext); | |
|
226 | break; | |
|
227 | case variable: | |
|
228 | if(!isInContext(*openBlocksContext,procedure) && !isInContext(*openBlocksContext,function) && !isInContext(*openBlocksContext,attribute)) | |
|
229 | openBlocksContext->push(currentNode); | |
|
230 | walk_forward(¤tNode,-1); | |
|
231 | break; | |
|
232 | case semicolon: | |
|
233 | if( (openBlocksContext->size()) && (IS_CLOSED_BY_SEMICOLON(openBlocksContext->top()->type))) | |
|
234 | { | |
|
235 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>(),false); | |
|
236 | } | |
|
237 | else | |
|
238 | { | |
|
239 | walk_forward(¤tNode,-1); | |
|
240 | } | |
|
241 | break; | |
|
242 | default: | |
|
243 | walk_forward(¤tNode,-1); | |
|
244 | break; | |
|
245 | } | |
|
246 | } | |
|
247 | *rootNode=currentNode; | |
|
248 | return 0; | |
|
249 | } | |
|
250 | ||
|
251 | int VHDL_Tools::parse_InterfaceList(VHDL_Tools::VHDL_AST_Node **rootNode, QStack<VHDL_Tools::VHDL_AST_Node *> *openBlocksContext) | |
|
252 | { | |
|
253 | /* interface-list –› [ constant | signal | file ] identifier { ‘,’ identifier } ‘:’ [ in ] subtype-indication [ := static_expression ]*/ | |
|
254 | VHDL_AST_Node *currentNode=*rootNode; | |
|
255 | openBlocksContext->push(currentNode); | |
|
256 | walk_forward(¤tNode,-1); | |
|
257 | if(currentNode->type!=rightParen) | |
|
258 | { | |
|
259 | FORCE_CLOSETYPE(currentNode, closedBySemicolon); | |
|
260 | openBlocksContext->push(currentNode); | |
|
261 | VHDL_AST_Node *currentLine=currentNode; | |
|
262 | while((currentNode->type!=rightParen) || openBlocksContext->top()!=currentLine) | |
|
263 | { | |
|
264 | switch (currentNode->type) | |
|
265 | { | |
|
266 | case semicolon: | |
|
267 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_Tools::VHDL_AST_Node_type>()); | |
|
268 | if(currentNode->childs.first()->type!=rightParen) | |
|
269 | { | |
|
270 | FORCE_CLOSETYPE(currentNode, closedBySemicolon); | |
|
271 | openBlocksContext->push(currentNode); | |
|
272 | currentLine = currentNode; | |
|
273 | } | |
|
274 | walk_forward(¤tNode,-1); | |
|
275 | break; | |
|
276 | case leftParen: | |
|
277 | openBlocksContext->push(currentNode); | |
|
278 | walk_forward(¤tNode,-1); | |
|
279 | break; | |
|
280 | case rightParen: | |
|
281 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_Tools::VHDL_AST_Node_type>()); | |
|
282 | break; | |
|
283 | default: | |
|
284 | walk_forward(¤tNode,-1); | |
|
285 | break; | |
|
286 | } | |
|
287 | } | |
|
288 | } | |
|
289 | openBlocksContext->pop(); | |
|
290 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_Tools::VHDL_AST_Node_type>()); | |
|
291 | *rootNode=currentNode; | |
|
292 | return 0; | |
|
293 | } | |
|
294 | ||
|
295 | int __private_parse_Architecture_Identifier(VHDL_Tools::VHDL_AST_Node **rootNode, QStack<VHDL_Tools::VHDL_AST_Node *> *openBlocksContext) | |
|
296 | { | |
|
297 | VHDL_Tools::VHDL_AST_Node *currentNode=*rootNode; | |
|
298 | VHDL_Tools::VHDL_AST_Node *startNode = currentNode; | |
|
299 | VHDL_Tools::walk_forward(¤tNode,-1); | |
|
300 | switch (currentNode->type) | |
|
301 | { | |
|
302 | case VHDL_Tools::colon: | |
|
303 | VHDL_Tools::parse_Block(¤tNode,openBlocksContext); | |
|
304 | break; | |
|
305 | case VHDL_Tools::leSym: | |
|
306 | currentNode = currentNode->parent(); | |
|
307 | VHDL_Tools::parse_Assignment(¤tNode,openBlocksContext); | |
|
308 | break; | |
|
309 | case VHDL_Tools::leftParen: //function/procedure call | |
|
310 | FORCE_CLOSETYPE(currentNode->parent(),closedBySemicolon); | |
|
311 | openBlocksContext->push(currentNode->parent()); | |
|
312 | VHDL_Tools::parse_AssociationList(¤tNode,openBlocksContext); | |
|
313 | VHDL_Tools::closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_Tools::VHDL_AST_Node_type>()); | |
|
314 | break; | |
|
315 | case VHDL_Tools::varAsgn: | |
|
316 | VHDL_Tools::parse_Assignment(¤tNode,openBlocksContext); | |
|
317 | break; | |
|
318 | default: | |
|
319 | break; | |
|
320 | } | |
|
321 | *rootNode=currentNode; | |
|
322 | return 0; | |
|
323 | } | |
|
324 | ||
|
325 | int VHDL_Tools::parse_Architecture(VHDL_Tools::VHDL_AST_Node **rootNode, QStack<VHDL_Tools::VHDL_AST_Node *> *openBlocksContext) | |
|
326 | { | |
|
327 | VHDL_AST_Node *currentNode=*rootNode; | |
|
328 | openBlocksContext->append(currentNode); | |
|
329 | VHDL_AST_Node *startNode = currentNode; | |
|
330 | walk_forward(¤tNode,-1); | |
|
331 | CHECK_TOKEN_EXIT(rootNode,currentNode,identifier,"Type identifier"); | |
|
332 | walk_forward(¤tNode,-1); | |
|
333 | CHECK_TOKEN_EXIT(rootNode,currentNode,of,"\"of\" keyword"); | |
|
334 | walk_forward(¤tNode,-1); | |
|
335 | CHECK_TOKEN_EXIT(rootNode,currentNode,identifier,"Type identifier"); | |
|
336 | walk_forward(¤tNode,-1); | |
|
337 | CHECK_TOKEN_EXIT(rootNode,currentNode,is,"\"is\" keyword"); | |
|
338 | walk_forward(¤tNode,-1); | |
|
339 | parse_DeclarativeBlock(¤tNode,openBlocksContext,true); | |
|
340 | /*if(currentNode->type!=endKw) | |
|
341 | { | |
|
342 | do | |
|
343 | { | |
|
344 | walk_forward(¤tNode,-1); | |
|
345 | switch (currentNode->type) { | |
|
346 | case identifier: | |
|
347 | __private_parse_Architecture_Identifier(¤tNode,openBlocksContext); | |
|
348 | case block: | |
|
349 | break; | |
|
350 | default: | |
|
351 | break; | |
|
352 | } | |
|
353 | }while(((currentNode->type!=endKw) || (startNode!=openBlocksContext->top())) && currentNode->childs.count()); | |
|
354 | }*/ | |
|
355 | parse_body(¤tNode,openBlocksContext); | |
|
356 | // closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()<<identifier,true,true); | |
|
357 | *rootNode=currentNode; | |
|
358 | return 0; | |
|
359 | } | |
|
360 | ||
|
361 | int VHDL_Tools::parse_Procedure(VHDL_Tools::VHDL_AST_Node **rootNode, QStack<VHDL_Tools::VHDL_AST_Node *> *openBlocksContext) | |
|
362 | { | |
|
363 | VHDL_AST_Node* startNode = *rootNode; | |
|
364 | VHDL_AST_Node* currentNode = *rootNode; | |
|
365 | openBlocksContext->push(startNode); | |
|
366 | walk_forward(¤tNode,-1); // skip Procedure | |
|
367 | walk_forward(¤tNode,-1); // skip Name | |
|
368 | if(currentNode->type==leftParen) | |
|
369 | { | |
|
370 | parse_InterfaceList(¤tNode,openBlocksContext); | |
|
371 | } | |
|
372 | if(Q_UNLIKELY(currentNode->type!=return_t) ) | |
|
373 | { | |
|
374 | if(Q_UNLIKELY(currentNode->type!=is)) | |
|
375 | { | |
|
376 | if(Q_UNLIKELY(currentNode->type!=semicolon)) | |
|
377 | { | |
|
378 | qDebug()<<"Error expected semicolon or \"return\" or \"is\" Keyword @line " <<currentNode->line <<" column "<<currentNode->column<<"\n"; | |
|
379 | } | |
|
380 | } | |
|
381 | } | |
|
382 | else | |
|
383 | { | |
|
384 | walk_forward(¤tNode,-1); | |
|
385 | if(Q_UNLIKELY(currentNode->type!=identifier)) | |
|
386 | { | |
|
387 | qDebug()<<"Error expected return type @line " <<currentNode->line <<" column "<<currentNode->column<<"\n"; | |
|
388 | } | |
|
389 | walk_forward(¤tNode,-1); | |
|
390 | } | |
|
391 | *rootNode=currentNode; | |
|
392 | if(currentNode->type==is) | |
|
393 | { | |
|
394 | walk_forward(rootNode,-1); //skip is | |
|
395 | parse_DeclarativeBlock(rootNode,openBlocksContext); | |
|
396 | startNode->type=static_cast<VHDL_AST_Node_type>(startNode->type | closedByEnd); | |
|
397 | return parse_body(rootNode,openBlocksContext); | |
|
398 | } | |
|
399 | else | |
|
400 | { | |
|
401 | startNode->type=static_cast<VHDL_AST_Node_type>(currentNode->type | closedBySemicolon); | |
|
402 | closeAndMatchBlock(rootNode,openBlocksContext,QList<VHDL_AST_Node_type>()); | |
|
403 | } | |
|
404 | return -1; | |
|
405 | } | |
|
406 | ||
|
407 | int VHDL_Tools::parse_DeclarativeBlock(VHDL_Tools::VHDL_AST_Node **rootNode, QStack<VHDL_Tools::VHDL_AST_Node *> *openBlocksContext, bool mustHaveBegin) | |
|
408 | { | |
|
409 | //Parse until begin or end | |
|
410 | VHDL_AST_Node *currentNode=*rootNode; | |
|
411 | VHDL_AST_Node *startNode=openBlocksContext->top(); | |
|
412 | while(( ((currentNode->type!=begin) && (currentNode->type!=endKw)) || (openBlocksContext->top()!=startNode) ) && (currentNode->childs.count())) | |
|
413 | { | |
|
414 | switch(currentNode->type) | |
|
415 | { | |
|
416 | case block: | |
|
417 | parse_Block(¤tNode,openBlocksContext); | |
|
418 | break; | |
|
419 | case function: | |
|
420 | parse_Function(¤tNode,openBlocksContext); | |
|
421 | break; | |
|
422 | case procedure: | |
|
423 | parse_Procedure(¤tNode,openBlocksContext); | |
|
424 | break; | |
|
425 | case clause: //use / lib / subtype | |
|
426 | parse_Clause(¤tNode,openBlocksContext); | |
|
427 | break; | |
|
428 | case constant: | |
|
429 | parse_Signal_or_Constant(¤tNode,openBlocksContext); | |
|
430 | break; | |
|
431 | case signal: | |
|
432 | parse_Signal_or_Constant(¤tNode,openBlocksContext); | |
|
433 | break; | |
|
434 | case type: | |
|
435 | parse_Type(¤tNode,openBlocksContext); | |
|
436 | break; | |
|
437 | case file: | |
|
438 | parse_File(¤tNode,openBlocksContext); | |
|
439 | break; | |
|
440 | case subtype: | |
|
441 | parse_Subtype(¤tNode,openBlocksContext); | |
|
442 | break; | |
|
443 | case component: | |
|
444 | parse_Component(¤tNode,openBlocksContext); | |
|
445 | break; | |
|
446 | case alias: | |
|
447 | parse_Alias(¤tNode,openBlocksContext); | |
|
448 | break; | |
|
449 | case report: | |
|
450 | parse_Report(¤tNode,openBlocksContext); | |
|
451 | break; | |
|
452 | default: | |
|
453 | walk_forward(¤tNode,0); | |
|
454 | break; | |
|
455 | } | |
|
456 | } | |
|
457 | if(Q_UNLIKELY(mustHaveBegin && (currentNode->type!=begin))) | |
|
458 | { | |
|
459 | qDebug()<<"Error expected \"begin\" keyword and got " << currentNode->a_value << " @line " <<currentNode->line <<" column "<<currentNode->column<<"\n"; | |
|
460 | } | |
|
461 | *rootNode=currentNode; | |
|
462 | return 0; | |
|
463 | } | |
|
464 | ||
|
465 | int VHDL_Tools::parse_Type(VHDL_Tools::VHDL_AST_Node **rootNode, QStack<VHDL_Tools::VHDL_AST_Node *> *openBlocksContext) | |
|
466 | { | |
|
467 | VHDL_AST_Node *currentNode=*rootNode; | |
|
468 | openBlocksContext->push(currentNode); | |
|
469 | VHDL_AST_Node *startNode=openBlocksContext->top(); | |
|
470 | VHDL_AST_Node *startNode2; | |
|
471 | walk_forward(¤tNode,-1); // skip type | |
|
472 | CHECK_TOKEN_EXIT(rootNode,currentNode,identifier,"Type identifier"); | |
|
473 | walk_forward(¤tNode,-1); // got Type identifier | |
|
474 | CHECK_TOKEN_EXIT(rootNode,currentNode,is,"is"); | |
|
475 | walk_forward(¤tNode,-1); // got is | |
|
476 | switch (currentNode->type) | |
|
477 | { | |
|
478 | case array: | |
|
479 | do | |
|
480 | { | |
|
481 | walk_forward(¤tNode,-1); | |
|
482 | if(Q_UNLIKELY(currentNode->type==leftParen)) | |
|
483 | { | |
|
484 | openBlocksContext->push(currentNode); | |
|
485 | } | |
|
486 | else | |
|
487 | { | |
|
488 | if(Q_UNLIKELY(currentNode->type==rightParen)) | |
|
489 | { | |
|
490 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()); | |
|
491 | } | |
|
492 | } | |
|
493 | }while(((currentNode->type!=semicolon) || (startNode!=openBlocksContext->top())) && currentNode->childs.count()); | |
|
494 | if(currentNode->type == semicolon) | |
|
495 | { | |
|
496 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()); | |
|
497 | } | |
|
498 | break; | |
|
499 | case record: | |
|
500 | parse_Record(¤tNode,openBlocksContext); | |
|
501 | break; | |
|
502 | case access: | |
|
503 | walk_forward(¤tNode,-1); | |
|
504 | CHECK_TOKEN_EXIT(rootNode,currentNode,identifier,"Type identifier"); | |
|
505 | walk_forward(¤tNode,-1); | |
|
506 | CHECK_TOKEN_EXIT(rootNode,currentNode,semicolon,"semicolon"); | |
|
507 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()); | |
|
508 | break; | |
|
509 | case file: | |
|
510 | do | |
|
511 | { | |
|
512 | walk_forward(¤tNode,-1); | |
|
513 | if(Q_UNLIKELY(currentNode->type==leftParen)) | |
|
514 | { | |
|
515 | openBlocksContext->push(currentNode); | |
|
516 | } | |
|
517 | else | |
|
518 | { | |
|
519 | if(Q_UNLIKELY(currentNode->type==rightParen)) | |
|
520 | { | |
|
521 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()); | |
|
522 | } | |
|
523 | } | |
|
524 | }while(((currentNode->type!=semicolon) || (startNode!=openBlocksContext->top())) && currentNode->childs.count()); | |
|
525 | if(currentNode->type == semicolon) | |
|
526 | { | |
|
527 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()); | |
|
528 | } | |
|
529 | break; | |
|
530 | case range: | |
|
531 | do | |
|
532 | { | |
|
533 | walk_forward(¤tNode,-1); | |
|
534 | if(Q_UNLIKELY(currentNode->type==leftParen)) | |
|
535 | { | |
|
536 | openBlocksContext->push(currentNode); | |
|
537 | } | |
|
538 | else | |
|
539 | { | |
|
540 | if(Q_UNLIKELY(currentNode->type==rightParen)) | |
|
541 | { | |
|
542 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()); | |
|
543 | } | |
|
544 | } | |
|
545 | }while((((currentNode->type!=semicolon) && (currentNode->type!=units)) || (startNode!=openBlocksContext->top())) && currentNode->childs.count()); | |
|
546 | if(currentNode->type == semicolon) | |
|
547 | { | |
|
548 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()); | |
|
549 | } | |
|
550 | else | |
|
551 | { | |
|
552 | if(currentNode->type == units) | |
|
553 | { | |
|
554 | parse_Units(¤tNode,openBlocksContext); | |
|
555 | } | |
|
556 | } | |
|
557 | break; | |
|
558 | case leftParen: | |
|
559 | openBlocksContext->push(currentNode); | |
|
560 | startNode2 = currentNode; | |
|
561 | walk_forward(¤tNode,-1); | |
|
562 | openBlocksContext->push(currentNode); | |
|
563 | do | |
|
564 | { | |
|
565 | if(Q_UNLIKELY(currentNode->type==comma)) | |
|
566 | { | |
|
567 | walk_forward(¤tNode,-1); | |
|
568 | currentNode->move(openBlocksContext->pop()->parent()); | |
|
569 | openBlocksContext->push(currentNode); | |
|
570 | } | |
|
571 | else | |
|
572 | { | |
|
573 | walk_forward(¤tNode,-1); | |
|
574 | } | |
|
575 | }while(currentNode->childs.count() && ((currentNode->type!=rightParen))); | |
|
576 | if(openBlocksContext->top()!=startNode2) | |
|
577 | { | |
|
578 | openBlocksContext->pop(); | |
|
579 | } | |
|
580 | CHECK_TOKEN_EXIT(rootNode,currentNode,rightParen,"\")\""); | |
|
581 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()); | |
|
582 | CHECK_TOKEN_EXIT(rootNode,currentNode,semicolon,"\";\""); | |
|
583 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()); | |
|
584 | break; | |
|
585 | default: | |
|
586 | break; | |
|
587 | } | |
|
588 | *rootNode=currentNode; | |
|
589 | return 0; | |
|
590 | } | |
|
591 | ||
|
592 | int VHDL_Tools::parse_Subtype(VHDL_Tools::VHDL_AST_Node **rootNode, QStack<VHDL_Tools::VHDL_AST_Node *> *openBlocksContext) | |
|
593 | { | |
|
594 | /*========================================================================================== | |
|
595 | SUBTYPE MyArray IS BIT_VECTOR(7 DOWNTO 3); | |
|
596 | subtype-declaration –› | |
|
597 | subtype identifier is subtype-indication ';' | |
|
598 | ||
|
599 | subtype-indication, type-indication –› | |
|
600 | [ resolution-function-name ] type-name [ range-constraint | index-constraint ] | |
|
601 | =============================================================================================*/ | |
|
602 | VHDL_AST_Node *currentNode=*rootNode; | |
|
603 | //VHDL_AST_Node *startNode=openBlocksContext->top(); | |
|
604 | openBlocksContext->append(currentNode); | |
|
605 | walk_forward(¤tNode,-1); // skip subtype | |
|
606 | CHECK_TOKEN_EXIT(rootNode,currentNode,identifier,"Subtype identifier"); | |
|
607 | walk_forward(¤tNode,-1); // got Subtype identifier | |
|
608 | CHECK_TOKEN_EXIT(rootNode,currentNode,is,"is"); | |
|
609 | walk_forward(¤tNode,-1); // got is | |
|
610 | CHECK_TOKEN_EXIT(rootNode,currentNode,identifier,"type name"); | |
|
611 | walk_forward(¤tNode,-1); | |
|
612 | switch (currentNode->type) { | |
|
613 | case leftParen: | |
|
614 | parse_ConstrainedRange(¤tNode,openBlocksContext); | |
|
615 | break; | |
|
616 | case identifier: | |
|
617 | walk_forward(¤tNode,-1); | |
|
618 | break; | |
|
619 | case range: | |
|
620 | parse_ConstrainedRange(¤tNode,openBlocksContext); | |
|
621 | break; | |
|
622 | default: | |
|
623 | break; | |
|
624 | } | |
|
625 | CHECK_TOKEN_EXIT(rootNode,currentNode,semicolon,"\";\""); | |
|
626 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()); | |
|
627 | *rootNode=currentNode; | |
|
628 | return 0; | |
|
629 | } | |
|
630 | ||
|
631 | int VHDL_Tools::parse_Component(VHDL_Tools::VHDL_AST_Node **rootNode, QStack<VHDL_Tools::VHDL_AST_Node *> *openBlocksContext) | |
|
632 | { | |
|
633 | VHDL_AST_Node *currentNode=*rootNode; | |
|
634 | openBlocksContext->append(currentNode); | |
|
635 | walk_forward(¤tNode,-1); | |
|
636 | CHECK_TOKEN_EXIT(rootNode,currentNode,identifier,"Type identifier"); | |
|
637 | walk_forward(¤tNode,-1); | |
|
638 | if(Q_LIKELY(currentNode->type==is)) | |
|
639 | { | |
|
640 | walk_forward(¤tNode,-1); | |
|
641 | } | |
|
642 | do | |
|
643 | { | |
|
644 | switch (currentNode->type) | |
|
645 | { | |
|
646 | case port: | |
|
647 | parse_Port_or_Generic(¤tNode,openBlocksContext); | |
|
648 | break; | |
|
649 | case generic: | |
|
650 | parse_Port_or_Generic(¤tNode,openBlocksContext); | |
|
651 | break; | |
|
652 | default: | |
|
653 | walk_forward(¤tNode,-1); | |
|
654 | break; | |
|
655 | } | |
|
656 | }while(currentNode->type!=endKw); | |
|
657 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()<<identifier,true,true); | |
|
658 | *rootNode=currentNode; | |
|
659 | return 0; | |
|
660 | } | |
|
661 | ||
|
662 | int VHDL_Tools::parse_ConstrainedRange(VHDL_Tools::VHDL_AST_Node **rootNode, QStack<VHDL_Tools::VHDL_AST_Node *> *openBlocksContext) | |
|
663 | { | |
|
664 | //range 0 to 9 | |
|
665 | //(1 to 20) | |
|
666 | //(20 dowto 1) | |
|
667 | VHDL_AST_Node *currentNode=*rootNode; | |
|
668 | VHDL_AST_Node *startNode=openBlocksContext->top(); | |
|
669 | switch (currentNode->type) | |
|
670 | { | |
|
671 | case range: | |
|
672 | //Expecting a constrained range so must get an identifier or a literal or an expression | |
|
673 | do | |
|
674 | { | |
|
675 | walk_forward(¤tNode,-1); | |
|
676 | if(Q_UNLIKELY(currentNode->type==leftParen)) | |
|
677 | { | |
|
678 | openBlocksContext->push(currentNode); | |
|
679 | } | |
|
680 | else | |
|
681 | { | |
|
682 | if(Q_UNLIKELY(currentNode->type==rightParen)) | |
|
683 | { | |
|
684 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()); | |
|
685 | } | |
|
686 | } | |
|
687 | }while(((currentNode->type!=semicolon) || (startNode!=openBlocksContext->top())) && currentNode->childs.count()); | |
|
688 | break; | |
|
689 | case leftParen: | |
|
690 | openBlocksContext->push(currentNode); | |
|
691 | startNode = currentNode; | |
|
692 | walk_forward(¤tNode,-1); | |
|
693 | do | |
|
694 | { | |
|
695 | if(Q_UNLIKELY(currentNode->type==leftParen)) | |
|
696 | { | |
|
697 | openBlocksContext->push(currentNode); | |
|
698 | } | |
|
699 | else | |
|
700 | { | |
|
701 | if(Q_UNLIKELY(currentNode->type==rightParen)) | |
|
702 | { | |
|
703 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()); | |
|
704 | } | |
|
705 | } | |
|
706 | walk_forward(¤tNode,-1); | |
|
707 | }while(((currentNode->type!=rightParen) || (startNode!=openBlocksContext->top())) && currentNode->childs.count()); | |
|
708 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()); | |
|
709 | break; | |
|
710 | default: | |
|
711 | break; | |
|
712 | } | |
|
713 | *rootNode=currentNode; | |
|
714 | return 0; | |
|
715 | } | |
|
716 | ||
|
717 | int VHDL_Tools::parse_Units(VHDL_Tools::VHDL_AST_Node **rootNode, QStack<VHDL_Tools::VHDL_AST_Node *> *openBlocksContext) | |
|
718 | { | |
|
719 | VHDL_AST_Node *currentNode=*rootNode; | |
|
720 | openBlocksContext->push(currentNode); | |
|
721 | openBlocksContext->push(currentNode->childs.first()); | |
|
722 | FORCE_CLOSETYPE(currentNode->childs.first(),closedBySemicolon); | |
|
723 | do | |
|
724 | { | |
|
725 | walk_forward(¤tNode,-1); | |
|
726 | if(Q_UNLIKELY(currentNode->type==semicolon)) | |
|
727 | { | |
|
728 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()); | |
|
729 | if(currentNode->type!=endKw) | |
|
730 | { | |
|
731 | FORCE_CLOSETYPE(currentNode,closedBySemicolon); | |
|
732 | openBlocksContext->push(currentNode); | |
|
733 | } | |
|
734 | } | |
|
735 | }while((currentNode->type!=endKw) && currentNode->childs.count()); | |
|
736 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()<<identifier,true,true); | |
|
737 | currentNode->move(openBlocksContext->pop()->parent()); | |
|
738 | *rootNode=currentNode; | |
|
739 | return 0; | |
|
740 | } | |
|
741 | ||
|
742 | int VHDL_Tools::parse_Record(VHDL_Tools::VHDL_AST_Node **rootNode, QStack<VHDL_Tools::VHDL_AST_Node *> *openBlocksContext) | |
|
743 | { | |
|
744 | VHDL_AST_Node *currentNode=*rootNode; | |
|
745 | openBlocksContext->push(currentNode); | |
|
746 | openBlocksContext->push(currentNode->childs.first()); | |
|
747 | FORCE_CLOSETYPE(currentNode->childs.first(),closedBySemicolon); | |
|
748 | do | |
|
749 | { | |
|
750 | walk_forward(¤tNode,-1); | |
|
751 | if(Q_UNLIKELY(currentNode->type==semicolon)) | |
|
752 | { | |
|
753 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()); | |
|
754 | if(currentNode->type!=endKw) | |
|
755 | { | |
|
756 | FORCE_CLOSETYPE(currentNode,closedBySemicolon); | |
|
757 | openBlocksContext->push(currentNode); | |
|
758 | } | |
|
759 | } | |
|
760 | }while((currentNode->type!=endKw) && currentNode->childs.count()); | |
|
761 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()<<identifier,true,true); | |
|
762 | currentNode->move(openBlocksContext->pop()->parent()); | |
|
763 | *rootNode=currentNode; | |
|
764 | return 0; | |
|
765 | } | |
|
766 | ||
|
767 | int VHDL_Tools::parse_File(VHDL_Tools::VHDL_AST_Node **rootNode, QStack<VHDL_Tools::VHDL_AST_Node *> *openBlocksContext) | |
|
768 | { | |
|
769 | VHDL_AST_Node *currentNode=*rootNode; | |
|
770 | openBlocksContext->push(currentNode); | |
|
771 | VHDL_AST_Node *startNode=openBlocksContext->top(); | |
|
772 | FORCE_CLOSETYPE(currentNode->childs.first(),closedBySemicolon); | |
|
773 | do | |
|
774 | { | |
|
775 | walk_forward(¤tNode,-1); | |
|
776 | if(Q_UNLIKELY(currentNode->type==leftParen)) | |
|
777 | { | |
|
778 | openBlocksContext->push(currentNode); | |
|
779 | } | |
|
780 | else | |
|
781 | { | |
|
782 | if(Q_UNLIKELY(currentNode->type==rightParen)) | |
|
783 | { | |
|
784 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()); | |
|
785 | } | |
|
786 | } | |
|
787 | }while(((currentNode->type!=semicolon) || (startNode!=openBlocksContext->top())) && currentNode->childs.count()); | |
|
788 | if(currentNode->type == semicolon) | |
|
789 | { | |
|
790 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()); | |
|
791 | } | |
|
792 | *rootNode=currentNode; | |
|
793 | return 0; | |
|
794 | } | |
|
795 | ||
|
796 | int VHDL_Tools::parse_Alias(VHDL_Tools::VHDL_AST_Node **rootNode, QStack<VHDL_Tools::VHDL_AST_Node *> *openBlocksContext) | |
|
797 | { | |
|
798 | VHDL_AST_Node *currentNode=*rootNode; | |
|
799 | openBlocksContext->push(currentNode); | |
|
800 | VHDL_AST_Node *startNode=openBlocksContext->top(); | |
|
801 | FORCE_CLOSETYPE(currentNode->childs.first(),closedBySemicolon); | |
|
802 | do | |
|
803 | { | |
|
804 | walk_forward(¤tNode,-1); | |
|
805 | if(Q_UNLIKELY(currentNode->type==leftParen)) | |
|
806 | { | |
|
807 | openBlocksContext->push(currentNode); | |
|
808 | } | |
|
809 | else | |
|
810 | { | |
|
811 | if(Q_UNLIKELY(currentNode->type==rightParen)) | |
|
812 | { | |
|
813 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()); | |
|
814 | } | |
|
815 | } | |
|
816 | }while(((currentNode->type!=semicolon) || (startNode!=openBlocksContext->top())) && currentNode->childs.count()); | |
|
817 | if(currentNode->type == semicolon) | |
|
818 | { | |
|
819 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()); | |
|
820 | } | |
|
821 | *rootNode=currentNode; | |
|
822 | return 0; | |
|
823 | } | |
|
824 | ||
|
825 | int VHDL_Tools::parse_Report(VHDL_Tools::VHDL_AST_Node **rootNode, QStack<VHDL_Tools::VHDL_AST_Node *> *openBlocksContext) | |
|
826 | { | |
|
827 | VHDL_AST_Node *currentNode=*rootNode; | |
|
828 | openBlocksContext->push(currentNode); | |
|
829 | VHDL_AST_Node *startNode=openBlocksContext->top(); | |
|
830 | FORCE_CLOSETYPE(currentNode->childs.first(),closedBySemicolon); | |
|
831 | do | |
|
832 | { | |
|
833 | walk_forward(¤tNode,-1); | |
|
834 | if(Q_UNLIKELY(currentNode->type==leftParen)) | |
|
835 | { | |
|
836 | openBlocksContext->push(currentNode); | |
|
837 | } | |
|
838 | else | |
|
839 | { | |
|
840 | if(Q_UNLIKELY(currentNode->type==rightParen)) | |
|
841 | { | |
|
842 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()); | |
|
843 | } | |
|
844 | } | |
|
845 | }while(((currentNode->type!=semicolon) || (startNode!=openBlocksContext->top())) && currentNode->childs.count()); | |
|
846 | if(currentNode->type == semicolon) | |
|
847 | { | |
|
848 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()); | |
|
849 | } | |
|
850 | *rootNode=currentNode; | |
|
851 | return 0; | |
|
852 | } | |
|
853 | ||
|
854 | int VHDL_Tools::parse_Process(VHDL_Tools::VHDL_AST_Node **rootNode, QStack<VHDL_Tools::VHDL_AST_Node *> *openBlocksContext) | |
|
855 | { | |
|
856 | VHDL_AST_Node *currentNode=*rootNode; | |
|
857 | if(currentNode->parent()->type==colon) | |
|
858 | { | |
|
859 | if(currentNode->parent()->parent()->type==identifier) | |
|
860 | { | |
|
861 | FORCE_CLOSETYPE(currentNode->parent()->parent(),closedByEnd); | |
|
862 | openBlocksContext->append(currentNode->parent()->parent()); | |
|
863 | } | |
|
864 | } | |
|
865 | else | |
|
866 | { | |
|
867 | openBlocksContext->append(currentNode); | |
|
868 | } | |
|
869 | VHDL_AST_Node *startNode=openBlocksContext->top(); | |
|
870 | parse_DeclarativeBlock(¤tNode,openBlocksContext,true); | |
|
871 | if(currentNode->type!=endKw) | |
|
872 | { | |
|
873 | do | |
|
874 | { | |
|
875 | switch (currentNode->type) | |
|
876 | { | |
|
877 | case identifier: | |
|
878 | if(currentNode->childs.count() && currentNode->childs.first()->type==colon) | |
|
879 | { | |
|
880 | openBlocksContext->push(currentNode); | |
|
881 | walk_forward(¤tNode,-1); | |
|
882 | walk_forward(¤tNode,-1); | |
|
883 | if(currentNode->type==block) | |
|
884 | { | |
|
885 | FORCE_CLOSETYPE(openBlocksContext->top(),closedByEnd); | |
|
886 | } | |
|
887 | else | |
|
888 | { | |
|
889 | FORCE_CLOSETYPE(openBlocksContext->top(),closedBySemicolon); | |
|
890 | } | |
|
891 | } | |
|
892 | else | |
|
893 | { | |
|
894 | walk_forward(¤tNode,-1); | |
|
895 | } | |
|
896 | break; | |
|
897 | case block: | |
|
898 | parse_Block(¤tNode,openBlocksContext); | |
|
899 | break; | |
|
900 | case semicolon: | |
|
901 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()); | |
|
902 | openBlocksContext->push(currentNode); | |
|
903 | break; | |
|
904 | case caseKw: | |
|
905 | break; | |
|
906 | default: | |
|
907 | walk_forward(¤tNode,-1); | |
|
908 | break; | |
|
909 | } | |
|
910 | }while(((currentNode->type!=endKw) || (startNode!=openBlocksContext->top())) && currentNode->childs.count()); | |
|
911 | } | |
|
912 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()<<identifier,true,true); | |
|
913 | *rootNode=currentNode; | |
|
914 | return 0; | |
|
915 | } | |
|
916 | ||
|
917 | int VHDL_Tools::parse_Signal_or_Constant(VHDL_Tools::VHDL_AST_Node **rootNode, QStack<VHDL_Tools::VHDL_AST_Node *> *openBlocksContext) | |
|
918 | { | |
|
919 | VHDL_AST_Node *currentNode=*rootNode; | |
|
920 | openBlocksContext->push(currentNode); | |
|
921 | VHDL_AST_Node *startNode=openBlocksContext->top(); | |
|
922 | do | |
|
923 | { | |
|
924 | walk_forward(¤tNode,-1); | |
|
925 | if(Q_UNLIKELY(currentNode->type==leftParen)) | |
|
926 | { | |
|
927 | openBlocksContext->push(currentNode); | |
|
928 | } | |
|
929 | else | |
|
930 | { | |
|
931 | if(Q_UNLIKELY(currentNode->type==rightParen)) | |
|
932 | { | |
|
933 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()); | |
|
934 | } | |
|
935 | } | |
|
936 | }while(((currentNode->type!=semicolon) || (startNode!=openBlocksContext->top())) && currentNode->childs.count()); | |
|
937 | if(Q_LIKELY(currentNode->type == semicolon)) | |
|
938 | { | |
|
939 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()); | |
|
940 | } | |
|
941 | *rootNode=currentNode; | |
|
942 | return 0; | |
|
943 | } | |
|
944 | ||
|
945 | int VHDL_Tools::parse_Port_or_Generic(VHDL_Tools::VHDL_AST_Node **rootNode, QStack<VHDL_Tools::VHDL_AST_Node *> *openBlocksContext) | |
|
946 | { | |
|
947 | ||
|
948 | VHDL_AST_Node *currentNode=*rootNode; | |
|
949 | openBlocksContext->push(currentNode); | |
|
950 | walk_forward(¤tNode,-1); | |
|
951 | if(currentNode->type==leftParen) | |
|
952 | { | |
|
953 | parse_InterfaceList(¤tNode,openBlocksContext); | |
|
954 | } | |
|
955 | if(Q_LIKELY(currentNode->type == semicolon)) | |
|
956 | { | |
|
957 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()); | |
|
958 | } | |
|
959 | *rootNode=currentNode; | |
|
960 | return 0; | |
|
961 | } | |
|
962 | ||
|
963 | int VHDL_Tools::parse_Block(VHDL_Tools::VHDL_AST_Node **rootNode, QStack<VHDL_Tools::VHDL_AST_Node *> *openBlocksContext) | |
|
964 | { | |
|
965 | VHDL_AST_Node *currentNode=*rootNode; | |
|
966 | openBlocksContext->push(currentNode); | |
|
967 | VHDL_AST_Node *startNode=currentNode; | |
|
968 | walk_forward(¤tNode,-1); | |
|
969 | if(currentNode->type!=endKw) | |
|
970 | { | |
|
971 | do | |
|
972 | { | |
|
973 | switch (currentNode->type) | |
|
974 | { | |
|
975 | case identifier: | |
|
976 | __private_parse_Architecture_Identifier(¤tNode,openBlocksContext); | |
|
977 | break; | |
|
978 | case block: | |
|
979 | parse_Block(¤tNode,openBlocksContext); | |
|
980 | break; | |
|
981 | case wait: | |
|
982 | parse_Wait(¤tNode,openBlocksContext); | |
|
983 | break; | |
|
984 | case semicolon: | |
|
985 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()); | |
|
986 | openBlocksContext->push(currentNode); | |
|
987 | break; | |
|
988 | default: | |
|
989 | walk_forward(¤tNode,-1); | |
|
990 | break; | |
|
991 | } | |
|
992 | }while(((currentNode->type!=endKw) || (startNode!=openBlocksContext->top())) && currentNode->childs.count()); | |
|
993 | } | |
|
994 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()<<identifier,true,true); | |
|
995 | *rootNode=currentNode; | |
|
996 | return 0; | |
|
997 | } | |
|
998 | ||
|
999 | int VHDL_Tools::parse_Assignment(VHDL_Tools::VHDL_AST_Node **rootNode, QStack<VHDL_Tools::VHDL_AST_Node *> *openBlocksContext) | |
|
1000 | { | |
|
1001 | VHDL_AST_Node *currentNode=*rootNode; | |
|
1002 | openBlocksContext->push(currentNode); | |
|
1003 | VHDL_AST_Node *startNode = currentNode; | |
|
1004 | FORCE_CLOSETYPE(currentNode,closedBySemicolon); | |
|
1005 | while (currentNode->type!=semicolon) | |
|
1006 | { | |
|
1007 | if(Q_UNLIKELY(walk_forward(¤tNode,-1))) | |
|
1008 | { | |
|
1009 | openBlocksContext->pop(); | |
|
1010 | *rootNode=currentNode; | |
|
1011 | return 0; | |
|
1012 | } | |
|
1013 | } | |
|
1014 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()); | |
|
1015 | *rootNode=currentNode; | |
|
1016 | return 0; | |
|
1017 | } | |
|
1018 | ||
|
1019 | int VHDL_Tools::parse_Wait(VHDL_Tools::VHDL_AST_Node **rootNode, QStack<VHDL_Tools::VHDL_AST_Node *> *openBlocksContext) | |
|
1020 | { | |
|
1021 | VHDL_AST_Node *currentNode=*rootNode; | |
|
1022 | openBlocksContext->push(currentNode); | |
|
1023 | while(currentNode->type!=semicolon) | |
|
1024 | { | |
|
1025 | if(Q_UNLIKELY(walk_forward(¤tNode,-1))) | |
|
1026 | { | |
|
1027 | *rootNode=currentNode; | |
|
1028 | return -1; | |
|
1029 | } | |
|
1030 | } | |
|
1031 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_AST_Node_type>()); | |
|
1032 | *rootNode=currentNode; | |
|
1033 | return 0; | |
|
1034 | } | |
|
1035 | ||
|
1036 | int VHDL_Tools::parse_AssociationList(VHDL_Tools::VHDL_AST_Node **rootNode, QStack<VHDL_Tools::VHDL_AST_Node *> *openBlocksContext) | |
|
1037 | { | |
|
1038 | /* association-list –› [ formal-part ‘=>’ ] actual-part { ‘,’ [ formal-part ‘=>’ ] actual-part }*/ | |
|
1039 | VHDL_AST_Node *currentNode=*rootNode; | |
|
1040 | openBlocksContext->push(currentNode); | |
|
1041 | walk_forward(¤tNode,-1); | |
|
1042 | if(currentNode->type!=rightParen) | |
|
1043 | { | |
|
1044 | FORCE_CLOSETYPE(currentNode, closedBySemicolon); | |
|
1045 | openBlocksContext->push(currentNode); | |
|
1046 | VHDL_AST_Node *currentLine=currentNode; | |
|
1047 | while((currentNode->type!=rightParen) || openBlocksContext->top()!=currentLine) | |
|
1048 | { | |
|
1049 | switch (currentNode->type) | |
|
1050 | { | |
|
1051 | case colon: | |
|
1052 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_Tools::VHDL_AST_Node_type>()); | |
|
1053 | if(currentNode->childs.first()->type!=rightParen) | |
|
1054 | { | |
|
1055 | FORCE_CLOSETYPE(currentNode, closedBySemicolon); | |
|
1056 | openBlocksContext->push(currentNode); | |
|
1057 | currentLine = currentNode; | |
|
1058 | } | |
|
1059 | walk_forward(¤tNode,-1); | |
|
1060 | break; | |
|
1061 | case leftParen: | |
|
1062 | openBlocksContext->push(currentNode); | |
|
1063 | walk_forward(¤tNode,-1); | |
|
1064 | break; | |
|
1065 | case rightParen: | |
|
1066 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_Tools::VHDL_AST_Node_type>()); | |
|
1067 | break; | |
|
1068 | default: | |
|
1069 | walk_forward(¤tNode,-1); | |
|
1070 | break; | |
|
1071 | } | |
|
1072 | } | |
|
1073 | } | |
|
1074 | openBlocksContext->pop(); | |
|
1075 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_Tools::VHDL_AST_Node_type>()); | |
|
1076 | *rootNode=currentNode; | |
|
1077 | return 0; | |
|
1078 | } | |
|
1079 | ||
|
1080 | int VHDL_Tools::parse_Case(VHDL_Tools::VHDL_AST_Node **rootNode, QStack<VHDL_Tools::VHDL_AST_Node *> *openBlocksContext) | |
|
1081 | { | |
|
1082 | /* | |
|
1083 | case-statement –› [ case-label ‘:’ ] case expression is | |
|
1084 | when choices ‘=>’ { sequential-statement } | |
|
1085 | { when choices ‘=>’ { sequential-statement }} | |
|
1086 | end case [ case-label ] ‘;’ | |
|
1087 | choices –› choice { | choice } | |
|
1088 | */ | |
|
1089 | VHDL_AST_Node *currentNode=*rootNode; | |
|
1090 | openBlocksContext->push(currentNode); | |
|
1091 | do | |
|
1092 | { | |
|
1093 | walk_forward(¤tNode); | |
|
1094 | }while(currentNode->type!=is); | |
|
1095 | do{ | |
|
1096 | if(currentNode->type==when) | |
|
1097 | { | |
|
1098 | parse_When_case(¤tNode,openBlocksContext); | |
|
1099 | } | |
|
1100 | else | |
|
1101 | { | |
|
1102 | walk_forward(¤tNode,-1); | |
|
1103 | } | |
|
1104 | }while(currentNode!=endKw); | |
|
1105 | closeAndMatchBlock(¤tNode,openBlocksContext,QList<VHDL_Tools::VHDL_AST_Node_type>()); | |
|
1106 | *rootNode=currentNode; | |
|
1107 | return 0; | |
|
1108 | } | |
|
1109 | ||
|
1110 | int VHDL_Tools::parse_When_case(VHDL_Tools::VHDL_AST_Node **rootNode, QStack<VHDL_Tools::VHDL_AST_Node *> *openBlocksContext) | |
|
1111 | { | |
|
1112 | VHDL_AST_Node *currentNode=*rootNode; | |
|
1113 | VHDL_AST_Node *startNode=*rootNode; | |
|
1114 | ||
|
1115 | *rootNode=currentNode; | |
|
1116 | return 0; | |
|
1117 | } | |
|
1118 | ||
|
1119 | ||
|
1120 | ||
|
1121 | ||
|
1122 | ||
|
1123 | ||
|
1124 | ||
|
1125 | ||
|
1126 | ||
|
1127 | ||
|
1128 |
@@ -0,0 +1,120 | |||
|
1 | #ifndef ELEMENTPARSER_H | |
|
2 | #define ELEMENTPARSER_H | |
|
3 | #include "scanner/vhdl_ast_node.h" | |
|
4 | #include <QStack> | |
|
5 | #include <QString> | |
|
6 | #include <QDebug> | |
|
7 | namespace VHDL_Tools { | |
|
8 | ||
|
9 | #define WALK_FORWARD( node , code ) \ | |
|
10 | while((node)->childs.count())\ | |
|
11 | {\ | |
|
12 | (node) = (node)->childs.first();\ | |
|
13 | if(Q_UNLIKELY((node)->type==comment))\ | |
|
14 | {\ | |
|
15 | while(((node)->type==comment) && (node)->childs.count())\ | |
|
16 | {\ | |
|
17 | (node) = (node)->childs.first(); /*get next node*/ \ | |
|
18 | (node)->move((node)->parent()->parent()); \ | |
|
19 | }\ | |
|
20 | }\ | |
|
21 | else\ | |
|
22 | {\ | |
|
23 | break;\ | |
|
24 | }\ | |
|
25 | }\ | |
|
26 | return (code); | |
|
27 | ||
|
28 | ||
|
29 | ||
|
30 | #define PARSE_COMMENT(node)\ | |
|
31 | WALK_FORWARD((node),0);\ | |
|
32 | (node)->move((node)->parent()->parent()); | |
|
33 | ||
|
34 | inline int walk_forward(VHDL_AST_Node **rootNode,int code) | |
|
35 | { | |
|
36 | VHDL_AST_Node *node = *rootNode; | |
|
37 | int retcode=code; | |
|
38 | while(node->childs.count()) | |
|
39 | { | |
|
40 | node = node->childs.first(); | |
|
41 | retcode=0; | |
|
42 | if(Q_UNLIKELY(node->type==comment)) | |
|
43 | { | |
|
44 | while((node->type==comment) && node->childs.count()) | |
|
45 | { | |
|
46 | node = node->childs.first(); /*get next node*/ | |
|
47 | node->moveWithoutChilds(node->parent()->parent()); | |
|
48 | } | |
|
49 | break; | |
|
50 | } | |
|
51 | else | |
|
52 | { | |
|
53 | break; | |
|
54 | } | |
|
55 | } | |
|
56 | *rootNode=node; | |
|
57 | return (retcode); | |
|
58 | } | |
|
59 | #define skipTokens(node,TokenType) while (((node)->type & 0x0FF )==(TokenType & 0x0FF)){walk_forward(&(node),-1);} | |
|
60 | ||
|
61 | bool isInContext(QStack<VHDL_Tools::VHDL_AST_Node *> openBlocksContext, VHDL_Tools::VHDL_AST_Node_type type); | |
|
62 | int closeAndMatchBlock(VHDL_Tools::VHDL_AST_Node** currentNode,QStack<VHDL_Tools::VHDL_AST_Node*>* openBlocksContext,QList<VHDL_Tools::VHDL_AST_Node_type>skipTypes,bool skipOpenType=false,bool endWithSemicolon=false); | |
|
63 | ||
|
64 | inline int parse_Clause(VHDL_AST_Node **rootNode, QStack<VHDL_AST_Node *> *openBlocksContext) | |
|
65 | { | |
|
66 | VHDL_AST_Node *currentNode=*rootNode; | |
|
67 | openBlocksContext->push(currentNode); | |
|
68 | do | |
|
69 | { | |
|
70 | walk_forward(¤tNode,-1); | |
|
71 | if(Q_UNLIKELY(currentNode->type!=identifier)) | |
|
72 | { | |
|
73 | qDebug()<<"Error expecting identifier, got "<< currentNode->a_value << " @line " <<currentNode->line <<" column "<<currentNode->column<<"\n"; | |
|
74 | *rootNode=currentNode; | |
|
75 | return -1; | |
|
76 | } | |
|
77 | walk_forward(¤tNode,-1); | |
|
78 | }while ((currentNode->type==comma) && currentNode->childs.count()); | |
|
79 | if(Q_UNLIKELY(currentNode->type!=semicolon)) | |
|
80 | { | |
|
81 | qDebug()<<"Error expecting \';\', got "<< currentNode->a_value << " @line " <<currentNode->line <<" column "<<currentNode->column<<"\n"; | |
|
82 | *rootNode=currentNode; | |
|
83 | return -1; | |
|
84 | } | |
|
85 | *rootNode=currentNode; | |
|
86 | closeAndMatchBlock(rootNode,openBlocksContext,QList<VHDL_Tools::VHDL_AST_Node_type>()); | |
|
87 | return 0; | |
|
88 | } | |
|
89 | ||
|
90 | ||
|
91 | int parse_Alias(VHDL_AST_Node **rootNode, QStack<VHDL_AST_Node *> *openBlocksContext); | |
|
92 | int parse_Architecture(VHDL_AST_Node **rootNode, QStack<VHDL_AST_Node *> *openBlocksContext); | |
|
93 | int parse_Assignment(VHDL_AST_Node **rootNode, QStack<VHDL_AST_Node *> *openBlocksContext); | |
|
94 | int parse_AssociationList(VHDL_AST_Node **rootNode, QStack<VHDL_AST_Node *> *openBlocksContext); | |
|
95 | int parse_Attribute(VHDL_AST_Node **rootNode, QStack<VHDL_AST_Node *> *openBlocksContext); | |
|
96 | int parse_body(VHDL_AST_Node **rootNode, QStack<VHDL_AST_Node *> *openBlocksContext); | |
|
97 | int parse_Block(VHDL_AST_Node **rootNode, QStack<VHDL_AST_Node *> *openBlocksContext); | |
|
98 | int parse_Case(VHDL_AST_Node **rootNode, QStack<VHDL_AST_Node *> *openBlocksContext); | |
|
99 | int parse_Component(VHDL_AST_Node **rootNode, QStack<VHDL_AST_Node *> *openBlocksContext); | |
|
100 | int parse_ConstrainedRange(VHDL_AST_Node **rootNode, QStack<VHDL_AST_Node *> *openBlocksContext); | |
|
101 | int parse_DeclarativeBlock(VHDL_AST_Node **rootNode, QStack<VHDL_AST_Node *> *openBlocksContext,bool mustHaveBegin=true); | |
|
102 | int parse_Entity(VHDL_AST_Node **rootNode, QStack<VHDL_AST_Node *> *openBlocksContext); | |
|
103 | int parse_File(VHDL_AST_Node **rootNode, QStack<VHDL_AST_Node *> *openBlocksContext); | |
|
104 | int parse_Function(VHDL_AST_Node **rootNode, QStack<VHDL_AST_Node *> *openBlocksContext); | |
|
105 | int parse_InterfaceList(VHDL_AST_Node **rootNode, QStack<VHDL_AST_Node *> *openBlocksContext); | |
|
106 | int parse_Package(VHDL_AST_Node **rootNode, QStack<VHDL_AST_Node *> *openBlocksContext); | |
|
107 | int parse_Port_or_Generic(VHDL_AST_Node **rootNode, QStack<VHDL_AST_Node *> *openBlocksContext); | |
|
108 | int parse_Procedure(VHDL_AST_Node **rootNode, QStack<VHDL_AST_Node *> *openBlocksContext); | |
|
109 | int parse_Process(VHDL_AST_Node **rootNode, QStack<VHDL_AST_Node *> *openBlocksContext); | |
|
110 | int parse_Record(VHDL_AST_Node **rootNode, QStack<VHDL_AST_Node *> *openBlocksContext); | |
|
111 | int parse_Report(VHDL_AST_Node **rootNode, QStack<VHDL_AST_Node *> *openBlocksContext); | |
|
112 | int parse_Signal_or_Constant(VHDL_AST_Node **rootNode, QStack<VHDL_AST_Node *> *openBlocksContext); | |
|
113 | int parse_Subtype(VHDL_AST_Node **rootNode, QStack<VHDL_AST_Node *> *openBlocksContext); | |
|
114 | int parse_Type(VHDL_AST_Node **rootNode, QStack<VHDL_AST_Node *> *openBlocksContext); | |
|
115 | int parse_Units(VHDL_AST_Node **rootNode, QStack<VHDL_AST_Node *> *openBlocksContext); | |
|
116 | int parse_Wait(VHDL_AST_Node **rootNode, QStack<VHDL_AST_Node *> *openBlocksContext); | |
|
117 | int parse_When_case(VHDL_AST_Node **rootNode, QStack<VHDL_AST_Node *> *openBlocksContext); | |
|
118 | } | |
|
119 | ||
|
120 | #endif // ELEMENTPARSER_H |
@@ -1,111 +1,114 | |||
|
1 | 1 | #include "mainwindow.h" |
|
2 | 2 | #include "ui_mainwindow.h" |
|
3 | 3 | #include <QFileDialog> |
|
4 | 4 | #include <QTreeWidget> |
|
5 | 5 | #include <QTreeWidgetItem> |
|
6 | 6 | |
|
7 | 7 | MainWindow::MainWindow(QWidget *parent) : |
|
8 | 8 | QMainWindow(parent), |
|
9 | 9 | ui(new Ui::MainWindow) |
|
10 | 10 | { |
|
11 | 11 | ui->setupUi(this); |
|
12 | 12 | connect(this->ui->actionOpen,SIGNAL(triggered()),this,SLOT(openFile())); |
|
13 | 13 | connect(this->ui->actionScan_Folder,SIGNAL(triggered()),this,SLOT(openFolder())); |
|
14 | 14 | this->file = new VHDL_Tools::VHDL_File; |
|
15 | 15 | this->rootNode = NULL; |
|
16 | 16 | } |
|
17 | 17 | |
|
18 | 18 | MainWindow::~MainWindow() |
|
19 | 19 | { |
|
20 | 20 | delete ui; |
|
21 | 21 | } |
|
22 | 22 | |
|
23 | 23 | void MainWindow::openFile() |
|
24 | 24 | { |
|
25 | 25 | QString fileName = QFileDialog::getOpenFileName(this, |
|
26 | 26 | tr("Open VHDL file"), NULL, tr("VHDL Files (*.vhd)")); |
|
27 | 27 | if(fileName!="") |
|
28 | 28 | { |
|
29 | 29 | parseFile(fileName,true); |
|
30 | 30 | this->rootNode=file->getParseTree(); |
|
31 | 31 | updateTree(rootNode); |
|
32 | 32 | } |
|
33 | 33 | } |
|
34 | 34 | |
|
35 | 35 | void MainWindow::openFolder() |
|
36 | 36 | { |
|
37 | 37 | QString dir = QFileDialog::getExistingDirectory(this, tr("Open Directory"), |
|
38 | 38 | NULL, |
|
39 | 39 | QFileDialog::ShowDirsOnly |
|
40 | 40 | | QFileDialog::DontResolveSymlinks); |
|
41 | 41 | if(dir!="") |
|
42 | 42 | { |
|
43 | 43 | this->rootNode=new VHDL_Tools::VHDL_AST_Node(dir,VHDL_Tools::virtualGroup); |
|
44 | 44 | parseDirectory(dir); |
|
45 | 45 | updateTree(this->rootNode); |
|
46 | 46 | } |
|
47 | 47 | } |
|
48 | 48 | |
|
49 | 49 | |
|
50 | 50 | void MainWindow::updateTree(VHDL_Tools::VHDL_AST_Node *rootNode) |
|
51 | 51 | { |
|
52 | 52 | this->ui->VHDLtreeWidget->clear(); |
|
53 | 53 | if(rootNode) |
|
54 | 54 | { |
|
55 | 55 | QTreeWidgetItem* item = new QTreeWidgetItem(QStringList()<<rootNode->a_value); |
|
56 | 56 | for(int i=0;i<rootNode->childs.count();i++) |
|
57 | 57 | { |
|
58 | 58 | printNode(rootNode->childs.at(i),item); |
|
59 | 59 | } |
|
60 | 60 | this->ui->VHDLtreeWidget->addTopLevelItem(item); |
|
61 | 61 | } |
|
62 | 62 | } |
|
63 | 63 | |
|
64 | 64 | void MainWindow::printNode(VHDL_Tools::VHDL_AST_Node *rootNode, QTreeWidgetItem *parent) |
|
65 | 65 | { |
|
66 | 66 | if(rootNode) |
|
67 | 67 | { |
|
68 | 68 | QTreeWidgetItem* item = new QTreeWidgetItem(parent,QStringList()<<rootNode->a_value); |
|
69 | 69 | for(int i=0;i<rootNode->childs.count();i++) |
|
70 | 70 | { |
|
71 | 71 | printNode(rootNode->childs.at(i),item); |
|
72 | 72 | } |
|
73 | 73 | } |
|
74 | 74 | } |
|
75 | 75 | |
|
76 | 76 | void MainWindow::parseFile(const QString &fileName, bool trashPreviousTree) |
|
77 | 77 | { |
|
78 | 78 | if(fileName!="") |
|
79 | 79 | this->file->parseFile(fileName,trashPreviousTree); |
|
80 | 80 | } |
|
81 | 81 | |
|
82 | 82 | void MainWindow::parseDirectory(const QString &dirName) |
|
83 | 83 | { |
|
84 | 84 | QDir dir(dirName); |
|
85 |
dir.setFilter(QDir::Files | QDir:: |
|
|
85 | dir.setFilter(QDir::Files | QDir::NoDotAndDotDot| QDir::Dirs | QDir::NoSymLinks); | |
|
86 | 86 | QFileInfoList list = dir.entryInfoList(); |
|
87 | 87 | for (int i = 0; i < list.size(); ++i) |
|
88 | 88 | { |
|
89 | 89 | if(list.at(i).isDir()) |
|
90 | 90 | { |
|
91 |
parseDirectory(list.at(i). |
|
|
91 | parseDirectory(list.at(i).absoluteFilePath()); | |
|
92 | 92 | } |
|
93 | 93 | else |
|
94 | 94 | { |
|
95 | 95 | if(list.at(i).isFile() && (!list.at(i).completeSuffix().compare("vhd"))) |
|
96 | 96 | { |
|
97 | 97 | parseFile(list.at(i).absoluteFilePath(),false); |
|
98 | 98 | VHDL_Tools::VHDL_AST_Node* parseTree = file->getParseTree(); |
|
99 | if(parseTree!=NULL) | |
|
100 | { | |
|
99 | 101 | this->rootNode->childs.append(parseTree); |
|
100 |
parseTree-> |
|
|
102 | parseTree->setParent(this->rootNode); | |
|
103 | } | |
|
101 | 104 | } |
|
102 | 105 | } |
|
103 | 106 | } |
|
104 | 107 | } |
|
105 | 108 | |
|
106 | 109 | |
|
107 | 110 | |
|
108 | 111 | |
|
109 | 112 | |
|
110 | 113 | |
|
111 | 114 |
@@ -1,33 +1,34 | |||
|
1 | 1 | #ifndef MAINWINDOW_H |
|
2 | 2 | #define MAINWINDOW_H |
|
3 | 3 | |
|
4 | 4 | #include <QMainWindow> |
|
5 | 5 | #include <vhdl_file.h> |
|
6 | 6 | #include <QTreeWidgetItem> |
|
7 | 7 | |
|
8 | 8 | namespace Ui { |
|
9 | 9 | class MainWindow; |
|
10 | 10 | } |
|
11 | 11 | |
|
12 | 12 | class MainWindow : public QMainWindow |
|
13 | 13 | { |
|
14 | 14 | Q_OBJECT |
|
15 | 15 | |
|
16 | 16 | public: |
|
17 | 17 | explicit MainWindow(QWidget *parent = 0); |
|
18 | 18 | ~MainWindow(); |
|
19 | 19 | |
|
20 | 20 | private slots: |
|
21 | 21 | void openFile(); |
|
22 | 22 | void openFolder(); |
|
23 | 23 | private: |
|
24 | 24 | void updateTree(VHDL_Tools::VHDL_AST_Node* rootNode); |
|
25 | 25 | void printNode(VHDL_Tools::VHDL_AST_Node* rootNode,QTreeWidgetItem* parent); |
|
26 | 26 | void parseFile(const QString& fileName, bool trashPreviousTree=false); |
|
27 | 27 | void parseDirectory(const QString& dirName); |
|
28 | 28 | VHDL_Tools::VHDL_AST_Node* rootNode; |
|
29 | 29 | Ui::MainWindow *ui; |
|
30 | 30 | VHDL_Tools::VHDL_File* file; |
|
31 | ||
|
31 | 32 | }; |
|
32 | 33 | |
|
33 | 34 | #endif // MAINWINDOW_H |
@@ -1,250 +1,292 | |||
|
1 | 1 | %{ |
|
2 | 2 | /* C++ string header, for string ops below */ |
|
3 | 3 | #include <string> |
|
4 | 4 | #include <QString> |
|
5 | 5 | /* Implementation of yyFlexScanner */ |
|
6 | 6 | #include "vhdl_scanner.h" |
|
7 | 7 | #include <QDebug> |
|
8 | 8 | /* define to keep from re-typing the same code over and over */ |
|
9 | 9 | #define STOKEN( x ) ( new QString( x ) ) |
|
10 | 10 | |
|
11 | 11 | /* define yyterminate as this instead of NULL */ |
|
12 | 12 | //#define yyterminate() return( token::END ) |
|
13 | 13 | |
|
14 | 14 | /* msvc2010 requires that we exclude this header file. */ |
|
15 | 15 | #define YY_NO_UNISTD_H |
|
16 | 16 | |
|
17 | /* handle locations */ | |
|
18 | int yycolumn = 1; | |
|
17 | ||
|
19 | 18 | |
|
20 | 19 | #define YY_USER_ACTION yycolumn += yyleng; |
|
21 | 20 | |
|
22 | 21 | %} |
|
23 | 22 | %option debug |
|
24 | 23 | %option nodefault |
|
25 | 24 | %option yyclass="vhdl_Scanner" |
|
26 | 25 | %option case-insensitive yylineno |
|
27 | 26 | %option noyywrap |
|
28 | 27 | %option c++ |
|
29 | 28 | |
|
30 | 29 | |
|
31 | 30 | %% |
|
32 | 31 | |
|
33 | 32 | /*-----------------------------------------------------------*/ |
|
34 | 33 | /*Separators*/ |
|
35 | 34 | [ \t]+ { } //skip new lines, blanc spaces and tabulations |
|
36 | 35 | /*-----------------------------------------------------------*/ |
|
37 | 36 | \n {yycolumn=1;} |
|
38 | 37 | |
|
38 | \x0d\x0a {yycolumn=1;} | |
|
39 | ||
|
39 | 40 | /*comment*/ |
|
40 | 41 | --.* { |
|
41 |
|
|
|
42 | this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::comment,yylineno, yycolumn-yyleng)); | |
|
42 | 43 | } |
|
43 | 44 | /*-----------------------------------------------------------*/ |
|
44 | 45 | |
|
45 | 46 | /*Reserved words*/ |
|
46 | 47 | |
|
47 | 48 | abs | |
|
48 | access | | |
|
49 | 49 | after | |
|
50 | alias | | |
|
51 | 50 | all | |
|
52 | 51 | and | |
|
53 | array | | |
|
54 | 52 | assert | |
|
55 | attribute | | |
|
56 | begin | | |
|
57 | body | | |
|
58 | 53 | buffer | |
|
59 | 54 | bus | |
|
60 | 55 | disconnect | |
|
61 | downto | | |
|
62 | 56 | else | |
|
63 | 57 | elsif | |
|
64 | 58 | exit | |
|
65 | file | | |
|
66 | function | | |
|
67 | 59 | generate | /* don't parse generate as block! just look for "if" or "for" */ |
|
68 | 60 | group | |
|
69 | 61 | guarded | |
|
70 | 62 | impure | |
|
71 | 63 | in | |
|
72 | 64 | inertial | |
|
73 | 65 | inout | |
|
74 | is | | |
|
75 | 66 | label | |
|
76 | 67 | linkage | |
|
77 | 68 | literal | |
|
78 | 69 | mod | |
|
79 | 70 | nand | |
|
80 | 71 | new | |
|
81 | 72 | next | |
|
82 | 73 | nor | |
|
83 | 74 | not | |
|
84 | 75 | null | |
|
85 | of | | |
|
86 | 76 | on | |
|
87 | 77 | open | |
|
88 | 78 | or | |
|
89 | 79 | others | |
|
90 | 80 | out | |
|
91 | 81 | postponed | |
|
92 | 82 | pure | |
|
93 | range | | |
|
94 | 83 | register | |
|
95 | 84 | reject | |
|
96 | 85 | rem | |
|
97 | report | | |
|
98 | return | | |
|
99 | 86 | rol | |
|
100 | 87 | ror | |
|
101 | 88 | select | |
|
102 | 89 | severity | |
|
103 | shared | | |
|
104 | 90 | sla | |
|
105 | 91 | sll | |
|
106 | 92 | sra | |
|
107 | 93 | srl | |
|
108 | 94 | then | |
|
109 | to | | |
|
110 | 95 | transport | |
|
111 | 96 | unaffected | |
|
112 | 97 | until | |
|
113 | wait | | |
|
114 | 98 | when | |
|
115 | while | | |
|
116 | 99 | with | |
|
117 | 100 | xnor | |
|
118 | 101 | xor | |
|
119 | 102 | (true|false) {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::keyword,yylineno, yycolumn-yyleng));} |
|
120 | 103 | |
|
104 | return {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::return_t,yylineno, yycolumn-yyleng));} | |
|
105 | ||
|
106 | when {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::when,yylineno, yycolumn-yyleng));} | |
|
107 | ||
|
108 | begin {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::begin,yylineno, yycolumn-yyleng));} | |
|
109 | ||
|
110 | is {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::is,yylineno, yycolumn-yyleng));} | |
|
111 | ||
|
121 | 112 | port {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::port,yylineno, yycolumn-yyleng));} |
|
122 | 113 | |
|
123 | 114 | generic {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::generic,yylineno, yycolumn-yyleng));} |
|
124 | 115 | |
|
125 | 116 | map {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::map,yylineno, yycolumn-yyleng));} |
|
126 | 117 | |
|
127 | architecture | | |
|
118 | loop {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::loop,yylineno, yycolumn-yyleng));} | |
|
119 | ||
|
120 | range {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::range,yylineno, yycolumn-yyleng));} | |
|
121 | ||
|
122 | array {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::array,yylineno, yycolumn-yyleng));} | |
|
123 | ||
|
124 | access {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::access,yylineno, yycolumn-yyleng));} | |
|
125 | ||
|
126 | file {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::file,yylineno, yycolumn-yyleng));} | |
|
127 | ||
|
128 | alias {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::alias,yylineno, yycolumn-yyleng));} | |
|
129 | ||
|
130 | report {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::report,yylineno, yycolumn-yyleng));} | |
|
131 | ||
|
132 | body {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::body,yylineno, yycolumn-yyleng));} | |
|
133 | ||
|
134 | of {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::of,yylineno, yycolumn-yyleng));} | |
|
135 | ||
|
136 | to | | |
|
137 | downto {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::direction,yylineno, yycolumn-yyleng));} | |
|
138 | ||
|
128 | 139 | block | |
|
129 | case | | |
|
130 | 140 | configuration | |
|
131 | component | | |
|
132 | 141 | for | |
|
133 | 142 | if | |
|
134 | loop | | |
|
135 | package | | |
|
136 | procedure | | |
|
137 | process | | |
|
138 | protected | | |
|
139 | record { | |
|
143 | while | | |
|
144 | protected { | |
|
140 | 145 | this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::block,yylineno, yycolumn-yyleng)); |
|
141 | 146 | } |
|
142 | 147 | |
|
143 |
e |
|
|
148 | case {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::caseKw,yylineno, yycolumn-yyleng));} | |
|
144 | 149 | |
|
145 | 150 | |
|
146 | units { | |
|
147 | this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::units,yylineno, yycolumn-yyleng)); | |
|
148 | } | |
|
151 | wait {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::wait,yylineno, yycolumn-yyleng));} | |
|
152 | ||
|
153 | process {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::process,yylineno, yycolumn-yyleng));} | |
|
154 | ||
|
155 | component {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::component,yylineno, yycolumn-yyleng));} | |
|
156 | ||
|
157 | package {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::package,yylineno, yycolumn-yyleng));} | |
|
158 | ||
|
159 | architecture {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::architecture,yylineno, yycolumn-yyleng));} | |
|
149 | 160 | |
|
150 | constant | | |
|
161 | record {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::record,yylineno, yycolumn-yyleng));} | |
|
162 | ||
|
163 | entity {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::entity,yylineno, yycolumn-yyleng));} | |
|
164 | ||
|
165 | procedure {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::procedure,yylineno, yycolumn-yyleng));} | |
|
166 | ||
|
167 | function {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::function,yylineno, yycolumn-yyleng));} | |
|
168 | ||
|
169 | units { this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::units,yylineno, yycolumn-yyleng));} | |
|
170 | ||
|
151 | 171 | library | |
|
152 | signal | | |
|
153 | subtype | | |
|
154 | type | | |
|
155 | use | | |
|
156 |
|
|
|
172 | use {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::clause,yylineno, yycolumn-yyleng));} | |
|
173 | ||
|
174 | constant {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::constant,yylineno, yycolumn-yyleng));} | |
|
175 | ||
|
176 | subtype {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::subtype,yylineno, yycolumn-yyleng));} | |
|
177 | ||
|
178 | type {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::type,yylineno, yycolumn-yyleng));} | |
|
157 | 179 | |
|
180 | attribute {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::attribute,yylineno, yycolumn-yyleng));} | |
|
158 | 181 | |
|
182 | variable {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::variable,yylineno, yycolumn-yyleng));} | |
|
183 | ||
|
184 | signal {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::signal,yylineno, yycolumn-yyleng));} | |
|
185 | ||
|
186 | shared {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::shared,yylineno, yycolumn-yyleng));} | |
|
159 | 187 | |
|
160 | 188 | end {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::endKw,yylineno, yycolumn-yyleng));} |
|
161 | 189 | |
|
162 | 190 | |
|
191 | ||
|
163 | 192 | /*-----------------------------------------------------------*/ |
|
164 | 193 | |
|
165 | 194 | /*identifier (may be a reserved word)*/ |
|
166 |
[a-z][a-z0-9\_\.] |
|
|
195 | [a-z][a-z0-9\_\.]*[a-z0-9]+ | | |
|
167 | 196 | [a-z]+ | |
|
168 | 197 | \\.*\\ {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::identifier,yylineno, yycolumn-yyleng));} |
|
169 | 198 | |
|
170 | 199 | /*-----------------------------------------------------------*/ |
|
171 | 200 | |
|
172 | 201 | /*abstract literal (integer or floating point type)*/ |
|
173 | 202 | /*Numerical literals*/ |
|
203 | ||
|
204 | [0-9]+\#[a-f0-9]+\# {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));} | |
|
205 | ||
|
174 | 206 | (\+|\-)?([0-9\_]+)|(\+|\-)?([0-9\_]+E[0-9\_]+)|((2|3|4|5|6|7|8|9|10|11|12|13|14|15|16)\#[0-9\_]\#) {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));} |
|
175 | 207 | |
|
176 | 208 | (\+|\-)?[0-9\_]+\.[0-9\_]+|[0-9\_]+\.[0-9\_]+E[0-9\_]+ {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));} |
|
177 | 209 | |
|
178 | 210 | \'(0|1)\' {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));} |
|
179 | 211 | |
|
180 | 212 | \'.\' {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));} |
|
181 | 213 | |
|
182 | 214 | |
|
183 | 215 | (\+|\-)?([0-9\_]+)(fs|ps|ns|us|ms|sec|min|hr) {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));} |
|
184 | 216 | |
|
185 | 217 | /*Bit string literals*/ |
|
186 | \"[0-1\_]+\" {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));} | |
|
218 | [\"\”][0-1\_\-]+[\"\”] {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));} | |
|
219 | ||
|
220 | ||
|
221 | x[\"\”][0-9A-F\_]+[\"\”] {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));} | |
|
222 | ||
|
223 | o[\"\”][0-7\_]+[\"\”] {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));} | |
|
187 | 224 | |
|
188 | 225 | /*String literals*/ |
|
189 |
|
|
|
190 | ||
|
191 | x\"[0-9A-F\_]+\" {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));} | |
|
192 | ||
|
193 | o\"[0-7\_]+\" {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));} | |
|
194 | ||
|
226 | [\"\”][^\"\n]*[\"\”] {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));} | |
|
195 | 227 | /*The NULL literal*/ |
|
196 | 228 | |
|
197 | 229 | \[NULL\] {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));} |
|
198 | 230 | |
|
199 | 231 | /*-----------------------------------------------------------*/ |
|
200 | 232 | |
|
201 | 233 | /*character literal (a graphical character surrounded by ‘, e.g.: ‘H’)*/ |
|
202 | 234 | /*-----------------------------------------------------------*/ |
|
203 | 235 | |
|
204 | 236 | /*string literal (a sequence of graphical characters surrounded by ”, e.g.: ”HAR-DI”)*/ |
|
205 | 237 | /*-----------------------------------------------------------*/ |
|
206 | 238 | |
|
207 | 239 | /* bit string literal (a sequence of extended digits * surrounded by ”, e.g.: ”011”)*/ |
|
208 | 240 | /*-----------------------------------------------------------*/ |
|
209 | 241 | |
|
210 | 242 | /* delimiter*/ |
|
211 | \. | \| | \[ | \] | | |
|
212 | \:= | \>\= | | |
|
213 |
\ |
|
|
243 | \. | | |
|
244 | \| | | |
|
245 | \[ | | |
|
246 | \] | | |
|
247 | \>\= | | |
|
214 | 248 | \/\= | |
|
215 | 249 | \= | |
|
216 | 250 | \> | |
|
217 | 251 | \< | |
|
218 | 252 | \& | |
|
219 | 253 | \‘ | |
|
220 | 254 | \' | |
|
221 |
\ |
|
|
222 | \<\> | | |
|
223 | \, | | |
|
255 | \’ | | |
|
224 | 256 | \* | |
|
225 | 257 | \+ | |
|
226 | 258 | \- | |
|
227 | 259 | \/ | |
|
228 | 260 | \*\* {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::separator,yylineno, yycolumn-yyleng)); } |
|
229 | 261 | |
|
262 | \<\= {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::leSym,yylineno, yycolumn-yyleng)); } | |
|
263 | ||
|
264 | \=\> {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::arrow,yylineno, yycolumn-yyleng)); } | |
|
265 | ||
|
266 | \:= {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::varAsgn,yylineno, yycolumn-yyleng)); } | |
|
267 | ||
|
268 | \<\> {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::box,yylineno, yycolumn-yyleng)); } | |
|
269 | ||
|
270 | \, {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::comma,yylineno, yycolumn-yyleng)); } | |
|
271 | ||
|
230 | 272 | |
|
231 | 273 | \: {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::colon,yylineno, yycolumn-yyleng)); } |
|
232 | 274 | |
|
233 | 275 | |
|
234 | 276 | \( {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::leftParen,yylineno, yycolumn-yyleng));} |
|
235 | 277 | |
|
236 | 278 | \) {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::rightParen,yylineno, yycolumn-yyleng));} |
|
237 | 279 | |
|
238 | 280 | |
|
239 | 281 | \; {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::semicolon,yylineno, yycolumn-yyleng)); } |
|
240 | 282 | |
|
241 | 283 | . printf("bad input character '%s' at line %d column %d\n ", yytext, yylineno,yycolumn-yyleng); |
|
242 | 284 | |
|
243 | 285 | %% |
|
244 | 286 | |
|
245 | 287 | |
|
246 | 288 | |
|
247 | 289 | |
|
248 | 290 | |
|
249 | 291 | |
|
250 | 292 |
@@ -1,40 +1,72 | |||
|
1 | 1 | /*------------------------------------------------------------------------------ |
|
2 | 2 | -- This file is a part of the VHDL Tools Software |
|
3 | 3 | -- Copyright (C) 2014, Plasma Physics Laboratory - CNRS |
|
4 | 4 | -- |
|
5 | 5 | -- This program is free software; you can redistribute it and/or modify |
|
6 | 6 | -- it under the terms of the GNU General Public License as published by |
|
7 | 7 | -- the Free Software Foundation; either version 2 of the License, or |
|
8 | 8 | -- (at your option) any later version. |
|
9 | 9 | -- |
|
10 | 10 | -- This program is distributed in the hope that it will be useful, |
|
11 | 11 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 | 12 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
13 | 13 | -- GNU General Public License for more details. |
|
14 | 14 | -- |
|
15 | 15 | -- You should have received a copy of the GNU General Public License |
|
16 | 16 | -- along with this program; if not, write to the Free Software |
|
17 | 17 | -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
18 | 18 | -------------------------------------------------------------------------------*/ |
|
19 | 19 | /*-- Author : Alexis Jeandet |
|
20 | 20 | -- Mail : alexis.jeandet@member.fsf.org |
|
21 | 21 | ----------------------------------------------------------------------------*/ |
|
22 | 22 | #include "vhdl_ast_node.h" |
|
23 | 23 | |
|
24 | 24 | |
|
25 | 25 | |
|
26 | 26 | VHDL_Tools::VHDL_AST_Node::VHDL_AST_Node(const QString &value, VHDL_Tools::VHDL_AST_Node_type type, int line, int column) |
|
27 | :a_value(value),type(type),line(line),column(column) | |
|
27 | :a_value(value),type(type),line(line),column(column),p_parent(NULL) | |
|
28 | 28 | { |
|
29 | 29 | |
|
30 | 30 | } |
|
31 | 31 | |
|
32 | VHDL_Tools::VHDL_AST_Node::~VHDL_AST_Node() | |
|
33 | { | |
|
34 | for(int i=0;i<childs.count();i++) | |
|
35 | { | |
|
36 | VHDL_AST_Node* nd=childs.first(); | |
|
37 | childs.removeFirst(); | |
|
38 | delete nd; | |
|
39 | } | |
|
40 | } | |
|
41 | ||
|
32 | 42 | void VHDL_Tools::VHDL_AST_Node::move(VHDL_Tools::VHDL_AST_Node *parentNode) |
|
33 | 43 | { |
|
34 | 44 | if(parentNode!=NULL) |
|
35 | 45 | { |
|
36 | this->parent->childs.removeOne(this); | |
|
46 | if(this->p_parent) | |
|
47 | { | |
|
48 | this->p_parent->childs.removeOne(this); | |
|
49 | } | |
|
37 | 50 | parentNode->childs.append(this); |
|
38 | this->parent=parentNode; | |
|
51 | this->p_parent=parentNode; | |
|
39 | 52 | } |
|
40 | 53 | } |
|
54 | ||
|
55 | void VHDL_Tools::VHDL_AST_Node::moveWithoutChilds(VHDL_Tools::VHDL_AST_Node *parentNode) | |
|
56 | { | |
|
57 | if(parentNode!=NULL) | |
|
58 | { | |
|
59 | if(this->p_parent) | |
|
60 | { | |
|
61 | this->p_parent->childs.removeOne(this); | |
|
62 | } | |
|
63 | while(Q_UNLIKELY(this->childs.isEmpty())) | |
|
64 | { | |
|
65 | VHDL_Tools::VHDL_AST_Node *child = this->childs.first(); | |
|
66 | this->childs.removeAll(child); | |
|
67 | this->p_parent->childs.append(child); | |
|
68 | } | |
|
69 | parentNode->childs.append(this); | |
|
70 | this->p_parent=parentNode; | |
|
71 | } | |
|
72 | } |
@@ -1,78 +1,121 | |||
|
1 | 1 | /*------------------------------------------------------------------------------ |
|
2 | 2 | -- This file is a part of the VHDL Tools Software |
|
3 | 3 | -- Copyright (C) 2014, Plasma Physics Laboratory - CNRS |
|
4 | 4 | -- |
|
5 | 5 | -- This program is free software; you can redistribute it and/or modify |
|
6 | 6 | -- it under the terms of the GNU General Public License as published by |
|
7 | 7 | -- the Free Software Foundation; either version 2 of the License, or |
|
8 | 8 | -- (at your option) any later version. |
|
9 | 9 | -- |
|
10 | 10 | -- This program is distributed in the hope that it will be useful, |
|
11 | 11 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 | 12 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
13 | 13 | -- GNU General Public License for more details. |
|
14 | 14 | -- |
|
15 | 15 | -- You should have received a copy of the GNU General Public License |
|
16 | 16 | -- along with this program; if not, write to the Free Software |
|
17 | 17 | -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
18 | 18 | -------------------------------------------------------------------------------*/ |
|
19 | 19 | /*-- Author : Alexis Jeandet |
|
20 | 20 | -- Mail : alexis.jeandet@member.fsf.org |
|
21 | 21 | ----------------------------------------------------------------------------*/ |
|
22 | 22 | #ifndef VHDL_AST_NODE_H |
|
23 | 23 | #define VHDL_AST_NODE_H |
|
24 | 24 | #include <QString> |
|
25 | 25 | #include <QList> |
|
26 | 26 | |
|
27 | 27 | namespace VHDL_Tools{ |
|
28 | 28 | |
|
29 | #define closedByEnd 0x100 | |
|
30 | #define closedBySemicolon 0x200 | |
|
31 | #define closedByRightParen 0x300 | |
|
29 | #define closedByEnd (0x100) | |
|
30 | #define closedBySemicolon (0x200) | |
|
31 | #define closedByRightParen (0x300) | |
|
32 | 32 | |
|
33 | 33 | #define IS_CLOSED_BY_END(type) (((type)&0xF00)==closedByEnd) |
|
34 | 34 | #define IS_CLOSED_BY_SEMICOLON(type) (((type)&0xF00)==closedBySemicolon) |
|
35 | 35 | #define IS_CLOSED_BY_RIGHTPAREN(type) (((type)&0xF00)==closedByRightParen) |
|
36 | 36 | |
|
37 | 37 | #define IS_CLOSED_BY(openType,type) ((type)==ExpectedCloseTypeLookUp[((openType)&0xF00)>>8]) |
|
38 | 38 | |
|
39 | #define FORCE_CLOSETYPE(node,closetype) (node)->type = static_cast<VHDL_Tools::VHDL_AST_Node_type>(((node)->type & 0x0FF) | (closetype)) | |
|
40 | ||
|
39 | 41 | enum VHDL_AST_Node_type { |
|
40 | none=0, | |
|
41 | separator=1, | |
|
42 |
|
|
|
43 | leftParen=3|closedByRightParen, | |
|
44 | rightParen=4, | |
|
45 | block=5|closedByEnd, | |
|
46 | units=6|closedByEnd, | |
|
47 | entity=7|closedByEnd, | |
|
48 |
c |
|
|
49 |
|
|
|
50 |
|
|
|
51 |
|
|
|
52 |
|
|
|
53 | map=13, | |
|
54 |
|
|
|
55 | virtualGroup=15, | |
|
56 | identifier=16, | |
|
57 | literal=17, | |
|
58 | rootNode=18, | |
|
59 | comment=19 | |
|
42 | none=0xF00000, //to force to at least 32 bits | |
|
43 | rootNode=1, | |
|
44 | separator=2, | |
|
45 | keyword=3, | |
|
46 | leftParen=4|closedByRightParen, | |
|
47 | rightParen=5, | |
|
48 | semicolon=6, | |
|
49 | colon=7, | |
|
50 | generic=8|closedBySemicolon, | |
|
51 | port=9|closedBySemicolon, | |
|
52 | map=10, | |
|
53 | endKw=11, | |
|
54 | virtualGroup=112, | |
|
55 | identifier=13, | |
|
56 | literal=14, | |
|
57 | comment=15, | |
|
58 | block=16|closedByEnd, | |
|
59 | units=17|closedByEnd, | |
|
60 | entity=18|closedByEnd, | |
|
61 | record=19|closedByEnd, | |
|
62 | clause=20|closedBySemicolon, | |
|
63 | signal=21|closedBySemicolon, | |
|
64 | variable=22|closedBySemicolon, | |
|
65 | shared=23|closedBySemicolon, | |
|
66 | type=24|closedBySemicolon, | |
|
67 | attribute=25|closedBySemicolon, | |
|
68 | constant=26|closedBySemicolon, | |
|
69 | function=27, | |
|
70 | procedure=28, | |
|
71 | is=29, | |
|
72 | return_t=30, | |
|
73 | begin=31, | |
|
74 | loop=32, | |
|
75 | architecture=33|closedByEnd, | |
|
76 | package=34|closedByEnd, | |
|
77 | subtype=35|closedBySemicolon, | |
|
78 | component=36|closedByEnd, | |
|
79 | range=37, | |
|
80 | comma=38, | |
|
81 | box=39, | |
|
82 | direction=40, | |
|
83 | array=41, | |
|
84 | access=42, | |
|
85 | file=43|closedBySemicolon, | |
|
86 | alias=44|closedBySemicolon, | |
|
87 | report=45|closedBySemicolon, | |
|
88 | body=46|closedByEnd, | |
|
89 | of=47, | |
|
90 | process=48|closedByEnd, | |
|
91 | arrow=49, | |
|
92 | varAsgn=50, | |
|
93 | wait=51|closedBySemicolon, | |
|
94 | leSym=52, | |
|
95 | caseKw=53|closedByEnd, | |
|
96 | when=54 | |
|
60 | 97 | }; |
|
61 | 98 | |
|
62 | 99 | const VHDL_AST_Node_type ExpectedCloseTypeLookUp[]={none,endKw,semicolon,rightParen,none,none,none,none,none,none,none,none,none,none,none,none}; |
|
63 | 100 | |
|
64 | 101 | class VHDL_AST_Node |
|
65 | 102 | { |
|
66 | 103 | public: |
|
67 | 104 | VHDL_AST_Node(const QString& value,VHDL_Tools::VHDL_AST_Node_type type,int line=0, int column=0); |
|
105 | ~VHDL_AST_Node(); | |
|
68 | 106 | QString a_value; |
|
69 | 107 | VHDL_Tools::VHDL_AST_Node_type type; |
|
70 | 108 | int line; |
|
71 | 109 | int column; |
|
72 | VHDL_Tools::VHDL_AST_Node* parent; | |
|
73 | 110 | QList<VHDL_Tools::VHDL_AST_Node*> childs; |
|
74 | 111 | void move(VHDL_Tools::VHDL_AST_Node* parentNode); |
|
112 | void moveWithoutChilds(VHDL_Tools::VHDL_AST_Node* parentNode); | |
|
113 | VHDL_Tools::VHDL_AST_Node* parent(){return p_parent;} | |
|
114 | void setParent(VHDL_Tools::VHDL_AST_Node* parent){this->p_parent=parent;} | |
|
115 | private: | |
|
116 | VHDL_Tools::VHDL_AST_Node* p_parent; | |
|
117 | ||
|
75 | 118 | }; |
|
76 | 119 | } |
|
77 | 120 | |
|
78 | 121 | #endif // VHDL_AST_NODE_H |
@@ -1,71 +1,64 | |||
|
1 | 1 | /*------------------------------------------------------------------------------ |
|
2 | 2 | -- This file is a part of the VHDL Tools Software |
|
3 | 3 | -- Copyright (C) 2014, Plasma Physics Laboratory - CNRS |
|
4 | 4 | -- |
|
5 | 5 | -- This program is free software; you can redistribute it and/or modify |
|
6 | 6 | -- it under the terms of the GNU General Public License as published by |
|
7 | 7 | -- the Free Software Foundation; either version 2 of the License, or |
|
8 | 8 | -- (at your option) any later version. |
|
9 | 9 | -- |
|
10 | 10 | -- This program is distributed in the hope that it will be useful, |
|
11 | 11 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 | 12 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
13 | 13 | -- GNU General Public License for more details. |
|
14 | 14 | -- |
|
15 | 15 | -- You should have received a copy of the GNU General Public License |
|
16 | 16 | -- along with this program; if not, write to the Free Software |
|
17 | 17 | -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
18 | 18 | -------------------------------------------------------------------------------*/ |
|
19 | 19 | /*-- Author : Alexis Jeandet |
|
20 | 20 | -- Mail : alexis.jeandet@member.fsf.org |
|
21 | 21 | ----------------------------------------------------------------------------*/ |
|
22 | 22 | #include "vhdl_scanner.h" |
|
23 | 23 | #include <QDebug> |
|
24 | 24 | |
|
25 | 25 | VHDL_Tools::vhdl_Scanner::vhdl_Scanner(std::istream *in, const QString &fileName) |
|
26 | 26 | : yyFlexLexer(in) |
|
27 | 27 | { |
|
28 | 28 | this->rootNode = new VHDL_Tools::VHDL_AST_Node(fileName,VHDL_Tools::rootNode); |
|
29 | 29 | this->currentNode = rootNode; |
|
30 |
this->rootNode-> |
|
|
30 | this->rootNode->setParent(this->rootNode); | |
|
31 | 31 | } |
|
32 | 32 | |
|
33 | 33 | VHDL_Tools::vhdl_Scanner::~vhdl_Scanner() |
|
34 | 34 | { |
|
35 |
delete |
|
|
35 | delete rootNode; | |
|
36 | 36 | } |
|
37 | 37 | |
|
38 | 38 | |
|
39 | 39 | int VHDL_Tools::vhdl_Scanner::scan() |
|
40 | 40 | { |
|
41 | 41 | return( yylex() ); |
|
42 | 42 | } |
|
43 | 43 | |
|
44 | 44 | int VHDL_Tools::vhdl_Scanner::newFile(std::istream *in, const QString &fileName,bool trashPreviousTree) |
|
45 | 45 | { |
|
46 | 46 | switch_streams(in); |
|
47 | 47 | if(trashPreviousTree) |
|
48 |
delete |
|
|
48 | delete rootNode; | |
|
49 | this->yylineno=1; | |
|
50 | this->yycolumn=1; | |
|
49 | 51 | this->rootNode = new VHDL_Tools::VHDL_AST_Node(fileName,VHDL_Tools::rootNode); |
|
50 | 52 | this->currentNode = rootNode; |
|
51 |
this->rootNode-> |
|
|
53 | this->rootNode->setParent(this->rootNode); | |
|
52 | 54 | return 1; |
|
53 | 55 | } |
|
54 | 56 | |
|
55 | 57 | |
|
56 | 58 | void VHDL_Tools::vhdl_Scanner::appendNode(VHDL_Tools::VHDL_AST_Node *node) |
|
57 | 59 | { |
|
58 | this->currentNode->childs.append(node); | |
|
59 | node->parent = this->currentNode; | |
|
60 | node->move(currentNode); | |
|
61 | // this->currentNode->childs.append(node); | |
|
62 | // node->parent = this->currentNode; | |
|
60 | 63 | this->currentNode = node; |
|
61 | 64 | } |
|
62 | ||
|
63 | void VHDL_Tools::vhdl_Scanner::deleteNode(VHDL_Tools::VHDL_AST_Node *node) | |
|
64 | { | |
|
65 | for(int i=0;i<node->childs.count();i++) | |
|
66 | { | |
|
67 | deleteNode(node->childs.at(i)); | |
|
68 | } | |
|
69 | node->parent->childs.removeAll(node); | |
|
70 | delete node; | |
|
71 | } |
@@ -1,68 +1,67 | |||
|
1 | 1 | /*------------------------------------------------------------------------------ |
|
2 | 2 | -- This file is a part of the VHDL Tools Software |
|
3 | 3 | -- Copyright (C) 2014, Plasma Physics Laboratory - CNRS |
|
4 | 4 | -- |
|
5 | 5 | -- This program is free software; you can redistribute it and/or modify |
|
6 | 6 | -- it under the terms of the GNU General Public License as published by |
|
7 | 7 | -- the Free Software Foundation; either version 2 of the License, or |
|
8 | 8 | -- (at your option) any later version. |
|
9 | 9 | -- |
|
10 | 10 | -- This program is distributed in the hope that it will be useful, |
|
11 | 11 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 | 12 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
13 | 13 | -- GNU General Public License for more details. |
|
14 | 14 | -- |
|
15 | 15 | -- You should have received a copy of the GNU General Public License |
|
16 | 16 | -- along with this program; if not, write to the Free Software |
|
17 | 17 | -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
18 | 18 | -------------------------------------------------------------------------------*/ |
|
19 | 19 | /*-- Author : Alexis Jeandet |
|
20 | 20 | -- Mail : alexis.jeandet@member.fsf.org |
|
21 | 21 | ----------------------------------------------------------------------------*/ |
|
22 | 22 | #ifndef vhdl_SCANNER_H |
|
23 | 23 | #define vhdl_SCANNER_H |
|
24 | 24 | #if ! defined(yyFlexLexerOnce) |
|
25 | 25 | #include <FlexLexer.h> |
|
26 | 26 | #endif |
|
27 | 27 | #include <iostream> |
|
28 | 28 | #include <cstdlib> |
|
29 | 29 | #include <fstream> |
|
30 | 30 | #include <QString> |
|
31 | 31 | #include <QList> |
|
32 | 32 | #include <QStack> |
|
33 | 33 | #include "vhdl_ast_node.h" |
|
34 | #include "vhdl_fragment.h" | |
|
35 | ||
|
36 | 34 | #undef YY_DECL |
|
37 | 35 | #define YY_DECL int VHDL_Tools::vhdl_Scanner::yylex() |
|
38 | 36 | |
|
39 | 37 | namespace VHDL_Tools{ |
|
40 | 38 | |
|
41 | 39 | class vhdl_Scanner_block_stack |
|
42 | 40 | { |
|
43 | 41 | public: |
|
44 | 42 | vhdl_Scanner_block_stack(bool waitForSemicolon,bool waitForParen, int delta) |
|
45 | 43 | :waitForSemicolon(waitForSemicolon),waitForParen(waitForParen),stackDelta(delta){} |
|
46 | 44 | bool waitForSemicolon; |
|
47 | 45 | bool waitForParen; |
|
48 | 46 | int stackDelta; |
|
49 | 47 | }; |
|
50 | 48 | |
|
51 | 49 | class vhdl_Scanner : public yyFlexLexer |
|
52 | 50 | { |
|
53 | 51 | public: |
|
54 | 52 | vhdl_Scanner(std::istream *in,const QString& fileName); |
|
55 | 53 | ~vhdl_Scanner(); |
|
56 | 54 | int scan(); |
|
57 | 55 | int newFile(std::istream *in, const QString& fileName, bool trashPreviousTree=false); |
|
58 | 56 | VHDL_Tools::VHDL_AST_Node* getScanTree(){return rootNode;} |
|
59 | 57 | private: |
|
60 | 58 | /* hide this one from public view */ |
|
61 | 59 | int yylex(); |
|
60 | /* handle locations */ | |
|
61 | int yycolumn; | |
|
62 | 62 | void appendNode(VHDL_Tools::VHDL_AST_Node* node); |
|
63 | void deleteNode(VHDL_Tools::VHDL_AST_Node* node); | |
|
64 | 63 | VHDL_Tools::VHDL_AST_Node* rootNode,*currentNode; |
|
65 | 64 | }; |
|
66 | 65 | } |
|
67 | 66 | |
|
68 | 67 | #endif // vhdl_SCANNER_H |
@@ -1,169 +1,87 | |||
|
1 | 1 | #include "vhdl_file.h" |
|
2 | 2 | #include <QDebug> |
|
3 | 3 | |
|
4 | 4 | VHDL_Tools::VHDL_File::VHDL_File() |
|
5 | 5 | { |
|
6 | 6 | this->scanner = NULL; |
|
7 | 7 | } |
|
8 | 8 | |
|
9 | #define walkForward( node , code ) \ | |
|
10 | if((node)->childs.count())\ | |
|
11 | {\ | |
|
12 | (node) = (node)->childs.first();\ | |
|
13 | }\ | |
|
14 | else\ | |
|
15 | {\ | |
|
16 | return (code);\ | |
|
17 | }\ | |
|
18 | ||
|
19 | ||
|
20 | #define skipTokens(node,TokenType) while ((node)->type==(TokenType)){walkForward((node),-1);} | |
|
21 | 9 | |
|
22 | 10 | bool VHDL_Tools::VHDL_File::parseFile(const QString &file, bool trashPreviousTree) |
|
23 | 11 | { |
|
24 | 12 | std::ifstream in_file( file.toStdString().c_str() ); |
|
25 | 13 | if( ! in_file.good() ) return false; |
|
26 | // if(scanner) | |
|
27 | // delete(scanner); | |
|
28 | // try | |
|
29 | // { | |
|
30 | // scanner = new VHDL_Tools::vhdl_Scanner( &in_file ,file); | |
|
31 | // } | |
|
32 | // catch( std::bad_alloc &ba ) | |
|
33 | // { | |
|
34 | // std::cerr << "Failed to allocate scanner: (" << | |
|
35 | // ba.what() << ")\n"; | |
|
36 | // return false; | |
|
37 | // } | |
|
38 | 14 | if(scanner==NULL) |
|
39 | 15 | { |
|
40 | 16 | try |
|
41 | 17 | { |
|
42 | 18 | scanner = new VHDL_Tools::vhdl_Scanner( &in_file ,file); |
|
43 | 19 | } |
|
44 | 20 | catch( std::bad_alloc &ba ) |
|
45 | 21 | { |
|
46 | 22 | std::cerr << "Failed to allocate scanner: (" << |
|
47 | 23 | ba.what() << ")\n"; |
|
48 | 24 | return false; |
|
49 | 25 | } |
|
50 | 26 | } |
|
27 | qDebug()<<"Parsing File "<<file<<"\n"; | |
|
51 | 28 | scanner->newFile(&in_file,file,trashPreviousTree); |
|
52 | 29 | while (scanner->scan()!=0); |
|
53 | 30 | makeParseTree(scanner->getScanTree()); |
|
54 | 31 | return false; |
|
55 | 32 | } |
|
56 | 33 | |
|
57 | 34 | VHDL_Tools::VHDL_AST_Node *VHDL_Tools::VHDL_File::getParseTree() |
|
58 | 35 | { |
|
59 | 36 | return rootNode; |
|
60 | 37 | } |
|
61 | 38 | |
|
62 | 39 | int VHDL_Tools::VHDL_File::makeParseTree(VHDL_AST_Node *rootNode) |
|
63 | 40 | { |
|
64 | 41 | this->rootNode = rootNode; |
|
65 | 42 | VHDL_AST_Node *currentNode=rootNode; |
|
66 | 43 | QStack<VHDL_AST_Node*> openBlocks; |
|
67 | 44 | openBlocks.push(rootNode); |
|
68 | while (currentNode) | |
|
45 | do | |
|
46 | { | |
|
47 | parseNext(¤tNode,&openBlocks); | |
|
48 | }while(currentNode->childs.count()); | |
|
49 | return 0; | |
|
50 | } | |
|
51 | ||
|
52 | int VHDL_Tools::VHDL_File::parseNext(VHDL_Tools::VHDL_AST_Node **rootNode, QStack<VHDL_Tools::VHDL_AST_Node *> *openBlocksContext) | |
|
53 | { | |
|
54 | VHDL_AST_Node *currentNode=*rootNode; | |
|
55 | if(currentNode) | |
|
69 | 56 | { |
|
70 | 57 | switch (currentNode->type) |
|
71 | 58 | { |
|
72 | case block: | |
|
73 | openBlocks.push(currentNode); | |
|
74 | walkForward(currentNode,-1); | |
|
75 | break; | |
|
76 | 59 | case entity: |
|
77 | //Declaration or instanciation? | |
|
78 | if(!((currentNode->parent->type == colon) && (currentNode->parent->parent->type==identifier))) | |
|
79 | { | |
|
80 | openBlocks.push(currentNode); | |
|
81 | } | |
|
82 | walkForward(currentNode,-1); | |
|
60 | parse_Entity(¤tNode,openBlocksContext); | |
|
83 | 61 | break; |
|
84 |
case |
|
|
85 | if(openBlocks.top()->type==clause) | |
|
86 | { | |
|
87 | openBlocks.top()->type=units; | |
|
88 | walkForward(currentNode,-1); | |
|
89 | } | |
|
90 | break; | |
|
91 | case port: | |
|
92 | currentNode->type = static_cast<VHDL_AST_Node_type>(currentNode->type | closedBySemicolon); | |
|
93 | openBlocks.push(currentNode); | |
|
94 | break; | |
|
95 | case generic: | |
|
96 | if(!(currentNode->childs.first()->type==map)) | |
|
97 | { | |
|
98 | currentNode->type = static_cast<VHDL_AST_Node_type>(currentNode->type | closedBySemicolon); | |
|
99 | openBlocks.push(currentNode); | |
|
100 | } | |
|
101 | walkForward(currentNode,-1); | |
|
62 | case architecture: | |
|
63 | parse_Architecture(¤tNode,openBlocksContext); | |
|
102 | 64 | break; |
|
103 | 65 | case clause: |
|
104 |
|
|
|
105 | walkForward(currentNode,-1); | |
|
106 | break; | |
|
107 | case endKw: | |
|
108 | closeAndMatchBlock(¤tNode,&openBlocks,QList<VHDL_AST_Node_type>()<<units<<block<<identifier,true); | |
|
109 | break; | |
|
110 | case leftParen: | |
|
111 | openBlocks.push(currentNode); | |
|
112 | walkForward(currentNode,-1); | |
|
66 | parse_Clause(¤tNode,openBlocksContext); | |
|
113 | 67 | break; |
|
114 |
case |
|
|
115 | if((openBlocks.top()->parent->type==port)||(openBlocks.top()->parent->type==generic)) | |
|
116 | closeAndMatchBlock(¤tNode,&openBlocks,QList<VHDL_AST_Node_type>(),false); | |
|
117 | else | |
|
118 | closeAndMatchBlock(¤tNode,&openBlocks,QList<VHDL_AST_Node_type>(),false); | |
|
119 | break; | |
|
120 | case semicolon: | |
|
121 | if(IS_CLOSED_BY_SEMICOLON(openBlocks.top()->type)) | |
|
122 | { | |
|
123 | closeAndMatchBlock(¤tNode,&openBlocks,QList<VHDL_AST_Node_type>(),false); | |
|
124 | } | |
|
125 | else | |
|
126 | { | |
|
127 | walkForward(currentNode,0); | |
|
128 | } | |
|
68 | case package: | |
|
69 | parse_Package(¤tNode,openBlocksContext); | |
|
129 | 70 | break; |
|
130 | 71 | default: |
|
131 |
walk |
|
|
72 | walk_forward(¤tNode,0); | |
|
132 | 73 | break; |
|
133 | 74 | } |
|
134 | 75 | } |
|
135 | return 0; | |
|
136 | } | |
|
137 | ||
|
138 | int VHDL_Tools::VHDL_File::closeAndMatchBlock(VHDL_Tools::VHDL_AST_Node **currentNode, QStack<VHDL_Tools::VHDL_AST_Node *> *openBlocksContext, QList<VHDL_Tools::VHDL_AST_Node_type> skipTypes, bool endWithSemicolon) | |
|
139 | { | |
|
140 | VHDL_AST_Node* startNode = openBlocksContext->pop(); | |
|
141 | ||
|
142 | if( IS_CLOSED_BY(startNode->type,(*currentNode)->type)) | |
|
143 | { | |
|
144 | walkForward((*currentNode),-1); | |
|
145 | for(int i=0;i<skipTypes.length();i++) | |
|
146 | { | |
|
147 | skipTokens((*currentNode),skipTypes.at(i)); | |
|
148 | } | |
|
149 | if(endWithSemicolon && ((*currentNode)->type==semicolon)) | |
|
150 | { | |
|
151 | walkForward((*currentNode),-1); | |
|
152 | (*currentNode)->move(startNode->parent); | |
|
153 | ||
|
154 | } | |
|
155 | else | |
|
156 | { | |
|
157 | (*currentNode)->move(startNode->parent); | |
|
158 | } | |
|
159 | } | |
|
160 | else | |
|
161 | { | |
|
162 | // TODO improve message ! | |
|
163 | qDebug() << "Got unexpected close token! @ line:" << (*currentNode)->line << " column:"<< (*currentNode)->column; | |
|
164 | } | |
|
76 | *rootNode =currentNode; | |
|
165 | 77 | return 0; |
|
166 | 78 | } |
|
167 | 79 | |
|
168 | 80 | |
|
169 | 81 | |
|
82 | ||
|
83 | ||
|
84 | ||
|
85 | ||
|
86 | ||
|
87 |
@@ -1,23 +1,27 | |||
|
1 | #ifndef VHDL_FILE_H | |
|
1 | #ifndef VHDL_FILE_H | |
|
2 | 2 | #define VHDL_FILE_H |
|
3 | 3 | |
|
4 | 4 | #include "vhdlparser_global.h" |
|
5 | 5 | #include "scanner/vhdl_scanner.h" |
|
6 | #include "vhdl_element_parser.h" | |
|
7 | #include <QHash> | |
|
6 | 8 | #include <QString> |
|
7 | 9 | namespace VHDL_Tools { |
|
10 | ||
|
8 | 11 | class VHDL_File |
|
9 | 12 | { |
|
10 | 13 | |
|
11 | 14 | public: |
|
12 | 15 | VHDL_File(); |
|
13 | 16 | bool parseFile(const QString& file, bool trashPreviousTree=false); |
|
14 | 17 | VHDL_Tools::VHDL_AST_Node* getParseTree(); |
|
15 | 18 | private: |
|
16 | 19 | VHDL_Tools::vhdl_Scanner *scanner; |
|
17 | 20 | int makeParseTree(VHDL_Tools::VHDL_AST_Node* rootNode); |
|
18 |
int |
|
|
21 | int parsePackage(VHDL_Tools::VHDL_AST_Node** rootNode,QStack<VHDL_Tools::VHDL_AST_Node*>* openBlocksContext); | |
|
22 | int parseNext(VHDL_Tools::VHDL_AST_Node** rootNode,QStack<VHDL_Tools::VHDL_AST_Node*>* openBlocksContext); | |
|
19 | 23 | VHDL_Tools::VHDL_AST_Node* rootNode; |
|
20 | 24 | }; |
|
21 | 25 | |
|
22 | 26 | } |
|
23 | 27 | #endif // VHDL_FILE_H |
@@ -1,40 +1,40 | |||
|
1 | 1 | #------------------------------------------------- |
|
2 | 2 | # |
|
3 | 3 | # Project created by QtCreator 2014-07-20T21:32:03 |
|
4 | 4 | # |
|
5 | 5 | #------------------------------------------------- |
|
6 | 6 | |
|
7 | 7 | QT -= gui |
|
8 | 8 | |
|
9 | 9 | |
|
10 | 10 | include ( ./scanner/Flex_Bison_FIles/Flex_Bison_FIles.pri ) |
|
11 | 11 | |
|
12 | 12 | TARGET = vhdlparser |
|
13 | 13 | TEMPLATE = lib |
|
14 | 14 | |
|
15 | 15 | LIBS += -lfl |
|
16 | 16 | |
|
17 | 17 | DEFINES += LIBVHDLPARSER_LIBRARY |
|
18 | 18 | DESTDIR = ../bin |
|
19 | 19 | |
|
20 | 20 | INCLUDEPATH += ./scanner |
|
21 | 21 | INCLUDEPATH += \ |
|
22 | 22 | ../vhdlparser |
|
23 | 23 | |
|
24 | 24 | |
|
25 | 25 | SOURCES += vhdl_file.cpp \ |
|
26 | 26 | scanner/vhdl_scanner.cpp \ |
|
27 |
scanner/vhdl_ |
|
|
28 | scanner/vhdl_ast_node.cpp | |
|
27 | scanner/vhdl_ast_node.cpp \ | |
|
28 | vhdl_element_parser.cpp | |
|
29 | 29 | |
|
30 | 30 | HEADERS += vhdl_file.h\ |
|
31 | 31 | libvhdlparser_global.h \ |
|
32 | 32 | scanner/vhdl_scanner.h \ |
|
33 |
scanner/vhdl_ |
|
|
34 | scanner/vhdl_ast_node.h | |
|
33 | scanner/vhdl_ast_node.h \ | |
|
34 | vhdl_element_parser.h | |
|
35 | 35 | |
|
36 | 36 | unix { |
|
37 | 37 | target.path = /usr/lib |
|
38 | 38 | INSTALLS += target |
|
39 | 39 | } |
|
40 | 40 |
|
1 | NO CONTENT: file was removed |
|
1 | NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now