##// END OF EJS Templates
Work in progress.
jeandet -
r2:f40b36fd7205 tip default
parent child
Show More
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(&currentNode,-1);
41 CHECK_TOKEN_EXIT(rootNode,currentNode,identifier,"Type identifier");
42 walk_forward(&currentNode,-1);
43 CHECK_TOKEN_EXIT(rootNode,currentNode,is,"\"is\" keyword");
44 walk_forward(&currentNode,-1);
45 if(currentNode->type==generic)
46 {
47 parse_Port_or_Generic(&currentNode,openBlocksContext);
48 }
49 if(currentNode->type==port)
50 {
51 parse_Port_or_Generic(&currentNode,openBlocksContext);
52 }
53 if(currentNode->type!=endKw)
54 {
55 parse_DeclarativeBlock(&currentNode,openBlocksContext,false);
56 do
57 {
58 walk_forward(&currentNode,-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(&currentNode,openBlocksContext,QList<VHDL_AST_Node_type>());
68 }
69 }
70 }while(((currentNode->type!=endKw) || (startNode!=openBlocksContext->top())) && currentNode->childs.count());
71 }
72 closeAndMatchBlock(&currentNode,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(&currentNode,-1); // skip Function
83 walk_forward(&currentNode,-1); // skip Name
84 parse_InterfaceList(&currentNode,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(&currentNode,-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(&currentNode,-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(&currentNode,-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(&currentNode,openBlocksContext,false);
130 closeAndMatchBlock(&currentNode,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(&currentNode,-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(&currentNode,-1);
194 break;
195 case process:
196 if(!isInContext(*openBlocksContext,attribute))
197 parse_Process(&currentNode,openBlocksContext);
198 // openBlocksContext->push(currentNode);
199 walk_forward(&currentNode,-1);
200 break;
201 case wait:
202 parse_Wait(&currentNode,openBlocksContext);
203 break;
204 case component:
205 parse_Component(&currentNode,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(&currentNode,openBlocksContext,QList<VHDL_AST_Node_type>()<<loop<<block<<identifier,true,true);
215 break;
216 case attribute:
217 parse_Attribute(&currentNode,openBlocksContext);
218 break;
219 case constant:
220 if(!isInContext(*openBlocksContext,procedure) && !isInContext(*openBlocksContext,function) && !isInContext(*openBlocksContext,attribute))
221 openBlocksContext->push(currentNode);
222 walk_forward(&currentNode,-1);
223 break;
224 case signal:
225 parse_Signal_or_Constant(&currentNode,openBlocksContext);
226 break;
227 case variable:
228 if(!isInContext(*openBlocksContext,procedure) && !isInContext(*openBlocksContext,function) && !isInContext(*openBlocksContext,attribute))
229 openBlocksContext->push(currentNode);
230 walk_forward(&currentNode,-1);
231 break;
232 case semicolon:
233 if( (openBlocksContext->size()) && (IS_CLOSED_BY_SEMICOLON(openBlocksContext->top()->type)))
234 {
235 closeAndMatchBlock(&currentNode,openBlocksContext,QList<VHDL_AST_Node_type>(),false);
236 }
237 else
238 {
239 walk_forward(&currentNode,-1);
240 }
241 break;
242 default:
243 walk_forward(&currentNode,-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(&currentNode,-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(&currentNode,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(&currentNode,-1);
275 break;
276 case leftParen:
277 openBlocksContext->push(currentNode);
278 walk_forward(&currentNode,-1);
279 break;
280 case rightParen:
281 closeAndMatchBlock(&currentNode,openBlocksContext,QList<VHDL_Tools::VHDL_AST_Node_type>());
282 break;
283 default:
284 walk_forward(&currentNode,-1);
285 break;
286 }
287 }
288 }
289 openBlocksContext->pop();
290 closeAndMatchBlock(&currentNode,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(&currentNode,-1);
300 switch (currentNode->type)
301 {
302 case VHDL_Tools::colon:
303 VHDL_Tools::parse_Block(&currentNode,openBlocksContext);
304 break;
305 case VHDL_Tools::leSym:
306 currentNode = currentNode->parent();
307 VHDL_Tools::parse_Assignment(&currentNode,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(&currentNode,openBlocksContext);
313 VHDL_Tools::closeAndMatchBlock(&currentNode,openBlocksContext,QList<VHDL_Tools::VHDL_AST_Node_type>());
314 break;
315 case VHDL_Tools::varAsgn:
316 VHDL_Tools::parse_Assignment(&currentNode,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(&currentNode,-1);
331 CHECK_TOKEN_EXIT(rootNode,currentNode,identifier,"Type identifier");
332 walk_forward(&currentNode,-1);
333 CHECK_TOKEN_EXIT(rootNode,currentNode,of,"\"of\" keyword");
334 walk_forward(&currentNode,-1);
335 CHECK_TOKEN_EXIT(rootNode,currentNode,identifier,"Type identifier");
336 walk_forward(&currentNode,-1);
337 CHECK_TOKEN_EXIT(rootNode,currentNode,is,"\"is\" keyword");
338 walk_forward(&currentNode,-1);
339 parse_DeclarativeBlock(&currentNode,openBlocksContext,true);
340 /*if(currentNode->type!=endKw)
341 {
342 do
343 {
344 walk_forward(&currentNode,-1);
345 switch (currentNode->type) {
346 case identifier:
347 __private_parse_Architecture_Identifier(&currentNode,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(&currentNode,openBlocksContext);
356 // closeAndMatchBlock(&currentNode,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(&currentNode,-1); // skip Procedure
367 walk_forward(&currentNode,-1); // skip Name
368 if(currentNode->type==leftParen)
369 {
370 parse_InterfaceList(&currentNode,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(&currentNode,-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(&currentNode,-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(&currentNode,openBlocksContext);
418 break;
419 case function:
420 parse_Function(&currentNode,openBlocksContext);
421 break;
422 case procedure:
423 parse_Procedure(&currentNode,openBlocksContext);
424 break;
425 case clause: //use / lib / subtype
426 parse_Clause(&currentNode,openBlocksContext);
427 break;
428 case constant:
429 parse_Signal_or_Constant(&currentNode,openBlocksContext);
430 break;
431 case signal:
432 parse_Signal_or_Constant(&currentNode,openBlocksContext);
433 break;
434 case type:
435 parse_Type(&currentNode,openBlocksContext);
436 break;
437 case file:
438 parse_File(&currentNode,openBlocksContext);
439 break;
440 case subtype:
441 parse_Subtype(&currentNode,openBlocksContext);
442 break;
443 case component:
444 parse_Component(&currentNode,openBlocksContext);
445 break;
446 case alias:
447 parse_Alias(&currentNode,openBlocksContext);
448 break;
449 case report:
450 parse_Report(&currentNode,openBlocksContext);
451 break;
452 default:
453 walk_forward(&currentNode,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(&currentNode,-1); // skip type
472 CHECK_TOKEN_EXIT(rootNode,currentNode,identifier,"Type identifier");
473 walk_forward(&currentNode,-1); // got Type identifier
474 CHECK_TOKEN_EXIT(rootNode,currentNode,is,"is");
475 walk_forward(&currentNode,-1); // got is
476 switch (currentNode->type)
477 {
478 case array:
479 do
480 {
481 walk_forward(&currentNode,-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(&currentNode,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(&currentNode,openBlocksContext,QList<VHDL_AST_Node_type>());
497 }
498 break;
499 case record:
500 parse_Record(&currentNode,openBlocksContext);
501 break;
502 case access:
503 walk_forward(&currentNode,-1);
504 CHECK_TOKEN_EXIT(rootNode,currentNode,identifier,"Type identifier");
505 walk_forward(&currentNode,-1);
506 CHECK_TOKEN_EXIT(rootNode,currentNode,semicolon,"semicolon");
507 closeAndMatchBlock(&currentNode,openBlocksContext,QList<VHDL_AST_Node_type>());
508 break;
509 case file:
510 do
511 {
512 walk_forward(&currentNode,-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(&currentNode,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(&currentNode,openBlocksContext,QList<VHDL_AST_Node_type>());
528 }
529 break;
530 case range:
531 do
532 {
533 walk_forward(&currentNode,-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(&currentNode,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(&currentNode,openBlocksContext,QList<VHDL_AST_Node_type>());
549 }
550 else
551 {
552 if(currentNode->type == units)
553 {
554 parse_Units(&currentNode,openBlocksContext);
555 }
556 }
557 break;
558 case leftParen:
559 openBlocksContext->push(currentNode);
560 startNode2 = currentNode;
561 walk_forward(&currentNode,-1);
562 openBlocksContext->push(currentNode);
563 do
564 {
565 if(Q_UNLIKELY(currentNode->type==comma))
566 {
567 walk_forward(&currentNode,-1);
568 currentNode->move(openBlocksContext->pop()->parent());
569 openBlocksContext->push(currentNode);
570 }
571 else
572 {
573 walk_forward(&currentNode,-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(&currentNode,openBlocksContext,QList<VHDL_AST_Node_type>());
582 CHECK_TOKEN_EXIT(rootNode,currentNode,semicolon,"\";\"");
583 closeAndMatchBlock(&currentNode,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(&currentNode,-1); // skip subtype
606 CHECK_TOKEN_EXIT(rootNode,currentNode,identifier,"Subtype identifier");
607 walk_forward(&currentNode,-1); // got Subtype identifier
608 CHECK_TOKEN_EXIT(rootNode,currentNode,is,"is");
609 walk_forward(&currentNode,-1); // got is
610 CHECK_TOKEN_EXIT(rootNode,currentNode,identifier,"type name");
611 walk_forward(&currentNode,-1);
612 switch (currentNode->type) {
613 case leftParen:
614 parse_ConstrainedRange(&currentNode,openBlocksContext);
615 break;
616 case identifier:
617 walk_forward(&currentNode,-1);
618 break;
619 case range:
620 parse_ConstrainedRange(&currentNode,openBlocksContext);
621 break;
622 default:
623 break;
624 }
625 CHECK_TOKEN_EXIT(rootNode,currentNode,semicolon,"\";\"");
626 closeAndMatchBlock(&currentNode,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(&currentNode,-1);
636 CHECK_TOKEN_EXIT(rootNode,currentNode,identifier,"Type identifier");
637 walk_forward(&currentNode,-1);
638 if(Q_LIKELY(currentNode->type==is))
639 {
640 walk_forward(&currentNode,-1);
641 }
642 do
643 {
644 switch (currentNode->type)
645 {
646 case port:
647 parse_Port_or_Generic(&currentNode,openBlocksContext);
648 break;
649 case generic:
650 parse_Port_or_Generic(&currentNode,openBlocksContext);
651 break;
652 default:
653 walk_forward(&currentNode,-1);
654 break;
655 }
656 }while(currentNode->type!=endKw);
657 closeAndMatchBlock(&currentNode,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(&currentNode,-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(&currentNode,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(&currentNode,-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(&currentNode,openBlocksContext,QList<VHDL_AST_Node_type>());
704 }
705 }
706 walk_forward(&currentNode,-1);
707 }while(((currentNode->type!=rightParen) || (startNode!=openBlocksContext->top())) && currentNode->childs.count());
708 closeAndMatchBlock(&currentNode,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(&currentNode,-1);
726 if(Q_UNLIKELY(currentNode->type==semicolon))
727 {
728 closeAndMatchBlock(&currentNode,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(&currentNode,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(&currentNode,-1);
751 if(Q_UNLIKELY(currentNode->type==semicolon))
752 {
753 closeAndMatchBlock(&currentNode,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(&currentNode,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(&currentNode,-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(&currentNode,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(&currentNode,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(&currentNode,-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(&currentNode,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(&currentNode,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(&currentNode,-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(&currentNode,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(&currentNode,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(&currentNode,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(&currentNode,-1);
882 walk_forward(&currentNode,-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(&currentNode,-1);
895 }
896 break;
897 case block:
898 parse_Block(&currentNode,openBlocksContext);
899 break;
900 case semicolon:
901 closeAndMatchBlock(&currentNode,openBlocksContext,QList<VHDL_AST_Node_type>());
902 openBlocksContext->push(currentNode);
903 break;
904 case caseKw:
905 break;
906 default:
907 walk_forward(&currentNode,-1);
908 break;
909 }
910 }while(((currentNode->type!=endKw) || (startNode!=openBlocksContext->top())) && currentNode->childs.count());
911 }
912 closeAndMatchBlock(&currentNode,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(&currentNode,-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(&currentNode,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(&currentNode,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(&currentNode,-1);
951 if(currentNode->type==leftParen)
952 {
953 parse_InterfaceList(&currentNode,openBlocksContext);
954 }
955 if(Q_LIKELY(currentNode->type == semicolon))
956 {
957 closeAndMatchBlock(&currentNode,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(&currentNode,-1);
969 if(currentNode->type!=endKw)
970 {
971 do
972 {
973 switch (currentNode->type)
974 {
975 case identifier:
976 __private_parse_Architecture_Identifier(&currentNode,openBlocksContext);
977 break;
978 case block:
979 parse_Block(&currentNode,openBlocksContext);
980 break;
981 case wait:
982 parse_Wait(&currentNode,openBlocksContext);
983 break;
984 case semicolon:
985 closeAndMatchBlock(&currentNode,openBlocksContext,QList<VHDL_AST_Node_type>());
986 openBlocksContext->push(currentNode);
987 break;
988 default:
989 walk_forward(&currentNode,-1);
990 break;
991 }
992 }while(((currentNode->type!=endKw) || (startNode!=openBlocksContext->top())) && currentNode->childs.count());
993 }
994 closeAndMatchBlock(&currentNode,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(&currentNode,-1)))
1008 {
1009 openBlocksContext->pop();
1010 *rootNode=currentNode;
1011 return 0;
1012 }
1013 }
1014 closeAndMatchBlock(&currentNode,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(&currentNode,-1)))
1026 {
1027 *rootNode=currentNode;
1028 return -1;
1029 }
1030 }
1031 closeAndMatchBlock(&currentNode,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(&currentNode,-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(&currentNode,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(&currentNode,-1);
1060 break;
1061 case leftParen:
1062 openBlocksContext->push(currentNode);
1063 walk_forward(&currentNode,-1);
1064 break;
1065 case rightParen:
1066 closeAndMatchBlock(&currentNode,openBlocksContext,QList<VHDL_Tools::VHDL_AST_Node_type>());
1067 break;
1068 default:
1069 walk_forward(&currentNode,-1);
1070 break;
1071 }
1072 }
1073 }
1074 openBlocksContext->pop();
1075 closeAndMatchBlock(&currentNode,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(&currentNode);
1094 }while(currentNode->type!=is);
1095 do{
1096 if(currentNode->type==when)
1097 {
1098 parse_When_case(&currentNode,openBlocksContext);
1099 }
1100 else
1101 {
1102 walk_forward(&currentNode,-1);
1103 }
1104 }while(currentNode!=endKw);
1105 closeAndMatchBlock(&currentNode,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(&currentNode,-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(&currentNode,-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
@@ -82,13 +82,13 void MainWindow::parseFile(const QString
82 void MainWindow::parseDirectory(const QString &dirName)
82 void MainWindow::parseDirectory(const QString &dirName)
83 {
83 {
84 QDir dir(dirName);
84 QDir dir(dirName);
85 dir.setFilter(QDir::Files | QDir::Hidden | QDir::NoSymLinks);
85 dir.setFilter(QDir::Files | QDir::NoDotAndDotDot| QDir::Dirs | QDir::NoSymLinks);
86 QFileInfoList list = dir.entryInfoList();
86 QFileInfoList list = dir.entryInfoList();
87 for (int i = 0; i < list.size(); ++i)
87 for (int i = 0; i < list.size(); ++i)
88 {
88 {
89 if(list.at(i).isDir())
89 if(list.at(i).isDir())
90 {
90 {
91 parseDirectory(list.at(i).fileName());
91 parseDirectory(list.at(i).absoluteFilePath());
92 }
92 }
93 else
93 else
94 {
94 {
@@ -96,8 +96,11 void MainWindow::parseDirectory(const QS
96 {
96 {
97 parseFile(list.at(i).absoluteFilePath(),false);
97 parseFile(list.at(i).absoluteFilePath(),false);
98 VHDL_Tools::VHDL_AST_Node* parseTree = file->getParseTree();
98 VHDL_Tools::VHDL_AST_Node* parseTree = file->getParseTree();
99 this->rootNode->childs.append(parseTree);
99 if(parseTree!=NULL)
100 parseTree->parent = this->rootNode;
100 {
101 this->rootNode->childs.append(parseTree);
102 parseTree->setParent(this->rootNode);
103 }
101 }
104 }
102 }
105 }
103 }
106 }
@@ -28,6 +28,7 private:
28 VHDL_Tools::VHDL_AST_Node* rootNode;
28 VHDL_Tools::VHDL_AST_Node* rootNode;
29 Ui::MainWindow *ui;
29 Ui::MainWindow *ui;
30 VHDL_Tools::VHDL_File* file;
30 VHDL_Tools::VHDL_File* file;
31
31 };
32 };
32
33
33 #endif // MAINWINDOW_H
34 #endif // MAINWINDOW_H
@@ -14,8 +14,7
14 /* msvc2010 requires that we exclude this header file. */
14 /* msvc2010 requires that we exclude this header file. */
15 #define YY_NO_UNISTD_H
15 #define YY_NO_UNISTD_H
16
16
17 /* handle locations */
17
18 int yycolumn = 1;
19
18
20 #define YY_USER_ACTION yycolumn += yyleng;
19 #define YY_USER_ACTION yycolumn += yyleng;
21
20
@@ -36,34 +35,27 int yycolumn = 1;
36 /*-----------------------------------------------------------*/
35 /*-----------------------------------------------------------*/
37 \n {yycolumn=1;}
36 \n {yycolumn=1;}
38
37
38 \x0d\x0a {yycolumn=1;}
39
39 /*comment*/
40 /*comment*/
40 --.* {
41 --.* {
41 //this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::comment,yylineno, yycolumn-yyleng));
42 this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::comment,yylineno, yycolumn-yyleng));
42 }
43 }
43 /*-----------------------------------------------------------*/
44 /*-----------------------------------------------------------*/
44
45
45 /*Reserved words*/
46 /*Reserved words*/
46
47
47 abs |
48 abs |
48 access |
49 after |
49 after |
50 alias |
51 all |
50 all |
52 and |
51 and |
53 array |
54 assert |
52 assert |
55 attribute |
56 begin |
57 body |
58 buffer |
53 buffer |
59 bus |
54 bus |
60 disconnect |
55 disconnect |
61 downto |
62 else |
56 else |
63 elsif |
57 elsif |
64 exit |
58 exit |
65 file |
66 function |
67 generate | /* don't parse generate as block! just look for "if" or "for" */
59 generate | /* don't parse generate as block! just look for "if" or "for" */
68 group |
60 group |
69 guarded |
61 guarded |
@@ -71,7 +63,6 impure |
71 in |
63 in |
72 inertial |
64 inertial |
73 inout |
65 inout |
74 is |
75 label |
66 label |
76 linkage |
67 linkage |
77 literal |
68 literal |
@@ -82,7 +73,6 next |
82 nor |
73 nor |
83 not |
74 not |
84 null |
75 null |
85 of |
86 on |
76 on |
87 open |
77 open |
88 or |
78 or |
@@ -90,80 +80,119 others |
90 out |
80 out |
91 postponed |
81 postponed |
92 pure |
82 pure |
93 range |
94 register |
83 register |
95 reject |
84 reject |
96 rem |
85 rem |
97 report |
98 return |
99 rol |
86 rol |
100 ror |
87 ror |
101 select |
88 select |
102 severity |
89 severity |
103 shared |
104 sla |
90 sla |
105 sll |
91 sll |
106 sra |
92 sra |
107 srl |
93 srl |
108 then |
94 then |
109 to |
110 transport |
95 transport |
111 unaffected |
96 unaffected |
112 until |
97 until |
113 wait |
114 when |
98 when |
115 while |
116 with |
99 with |
117 xnor |
100 xnor |
118 xor |
101 xor |
119 (true|false) {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::keyword,yylineno, yycolumn-yyleng));}
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 port {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::port,yylineno, yycolumn-yyleng));}
112 port {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::port,yylineno, yycolumn-yyleng));}
122
113
123 generic {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::generic,yylineno, yycolumn-yyleng));}
114 generic {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::generic,yylineno, yycolumn-yyleng));}
124
115
125 map {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::map,yylineno, yycolumn-yyleng));}
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 block |
139 block |
129 case |
130 configuration |
140 configuration |
131 component |
132 for |
141 for |
133 if |
142 if |
134 loop |
143 while |
135 package |
144 protected {
136 procedure |
137 process |
138 protected |
139 record {
140 this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::block,yylineno, yycolumn-yyleng));
145 this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::block,yylineno, yycolumn-yyleng));
141 }
146 }
142
147
143 entity {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::entity,yylineno, yycolumn-yyleng));}
148 case {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::caseKw,yylineno, yycolumn-yyleng));}
144
149
145
150
146 units {
151 wait {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::wait,yylineno, yycolumn-yyleng));}
147 this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::units,yylineno, yycolumn-yyleng));
152
148 }
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 library |
171 library |
152 signal |
172 use {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::clause,yylineno, yycolumn-yyleng));}
153 subtype |
173
154 type |
174 constant {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::constant,yylineno, yycolumn-yyleng));}
155 use |
175
156 variable {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::clause,yylineno, yycolumn-yyleng));}
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 end {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::endKw,yylineno, yycolumn-yyleng));}
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 /*identifier (may be a reserved word)*/
194 /*identifier (may be a reserved word)*/
166 [a-z][a-z0-9\_\.]+[a-z0-9]+ |
195 [a-z][a-z0-9\_\.]*[a-z0-9]+ |
167 [a-z]+ |
196 [a-z]+ |
168 \\.*\\ {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::identifier,yylineno, yycolumn-yyleng));}
197 \\.*\\ {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::identifier,yylineno, yycolumn-yyleng));}
169
198
@@ -171,6 +200,9 end {this->appendNode(new VHDL_Tools::VH
171
200
172 /*abstract literal (integer or floating point type)*/
201 /*abstract literal (integer or floating point type)*/
173 /*Numerical literals*/
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 (\+|\-)?([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));}
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 (\+|\-)?[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));}
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));}
@@ -183,15 +215,15 end {this->appendNode(new VHDL_Tools::VH
183 (\+|\-)?([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));}
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 /*Bit string literals*/
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 /*String literals*/
225 /*String literals*/
189 \".*\" {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));}
226 [\"\”][^\"\n]*[\"\”] {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));}
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
195 /*The NULL literal*/
227 /*The NULL literal*/
196
228
197 \[NULL\] {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));}
229 \[NULL\] {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));}
@@ -208,9 +240,11 o\"[0-7\_]+\" {this->appendNode(new VHDL
208 /*-----------------------------------------------------------*/
240 /*-----------------------------------------------------------*/
209
241
210 /* delimiter*/
242 /* delimiter*/
211 \. | \| | \[ | \] |
243 \. |
212 \:= | \>\= |
244 \| |
213 \<\= |
245 \[ |
246 \] |
247 \>\= |
214 \/\= |
248 \/\= |
215 \= |
249 \= |
216 \> |
250 \> |
@@ -218,15 +252,23 o\"[0-7\_]+\" {this->appendNode(new VHDL
218 \& |
252 \& |
219 \‘ |
253 \‘ |
220 \' |
254 \' |
221 \=\> |
255 \ |
222 \<\> |
223 \, |
224 \* |
256 \* |
225 \+ |
257 \+ |
226 \- |
258 \- |
227 \/ |
259 \/ |
228 \*\* {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::separator,yylineno, yycolumn-yyleng)); }
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 \: {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::colon,yylineno, yycolumn-yyleng)); }
273 \: {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::colon,yylineno, yycolumn-yyleng)); }
232
274
@@ -24,17 +24,49
24
24
25
25
26 VHDL_Tools::VHDL_AST_Node::VHDL_AST_Node(const QString &value, VHDL_Tools::VHDL_AST_Node_type type, int line, int column)
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 void VHDL_Tools::VHDL_AST_Node::move(VHDL_Tools::VHDL_AST_Node *parentNode)
42 void VHDL_Tools::VHDL_AST_Node::move(VHDL_Tools::VHDL_AST_Node *parentNode)
33 {
43 {
34 if(parentNode!=NULL)
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 parentNode->childs.append(this);
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 }
@@ -26,9 +26,9
26
26
27 namespace VHDL_Tools{
27 namespace VHDL_Tools{
28
28
29 #define closedByEnd 0x100
29 #define closedByEnd (0x100)
30 #define closedBySemicolon 0x200
30 #define closedBySemicolon (0x200)
31 #define closedByRightParen 0x300
31 #define closedByRightParen (0x300)
32
32
33 #define IS_CLOSED_BY_END(type) (((type)&0xF00)==closedByEnd)
33 #define IS_CLOSED_BY_END(type) (((type)&0xF00)==closedByEnd)
34 #define IS_CLOSED_BY_SEMICOLON(type) (((type)&0xF00)==closedBySemicolon)
34 #define IS_CLOSED_BY_SEMICOLON(type) (((type)&0xF00)==closedBySemicolon)
@@ -36,27 +36,64 namespace VHDL_Tools{
36
36
37 #define IS_CLOSED_BY(openType,type) ((type)==ExpectedCloseTypeLookUp[((openType)&0xF00)>>8])
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 enum VHDL_AST_Node_type {
41 enum VHDL_AST_Node_type {
40 none=0,
42 none=0xF00000, //to force to at least 32 bits
41 separator=1,
43 rootNode=1,
42 keyword=2,
44 separator=2,
43 leftParen=3|closedByRightParen,
45 keyword=3,
44 rightParen=4,
46 leftParen=4|closedByRightParen,
45 block=5|closedByEnd,
47 rightParen=5,
46 units=6|closedByEnd,
48 semicolon=6,
47 entity=7|closedByEnd,
49 colon=7,
48 clause=8|closedBySemicolon,
50 generic=8|closedBySemicolon,
49 semicolon=9,
51 port=9|closedBySemicolon,
50 colon=10,
52 map=10,
51 generic=11,
53 endKw=11,
52 port=12,
54 virtualGroup=112,
53 map=13,
55 identifier=13,
54 endKw=14,
56 literal=14,
55 virtualGroup=15,
57 comment=15,
56 identifier=16,
58 block=16|closedByEnd,
57 literal=17,
59 units=17|closedByEnd,
58 rootNode=18,
60 entity=18|closedByEnd,
59 comment=19
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 const VHDL_AST_Node_type ExpectedCloseTypeLookUp[]={none,endKw,semicolon,rightParen,none,none,none,none,none,none,none,none,none,none,none,none};
99 const VHDL_AST_Node_type ExpectedCloseTypeLookUp[]={none,endKw,semicolon,rightParen,none,none,none,none,none,none,none,none,none,none,none,none};
@@ -65,13 +102,19 class VHDL_AST_Node
65 {
102 {
66 public:
103 public:
67 VHDL_AST_Node(const QString& value,VHDL_Tools::VHDL_AST_Node_type type,int line=0, int column=0);
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 QString a_value;
106 QString a_value;
69 VHDL_Tools::VHDL_AST_Node_type type;
107 VHDL_Tools::VHDL_AST_Node_type type;
70 int line;
108 int line;
71 int column;
109 int column;
72 VHDL_Tools::VHDL_AST_Node* parent;
73 QList<VHDL_Tools::VHDL_AST_Node*> childs;
110 QList<VHDL_Tools::VHDL_AST_Node*> childs;
74 void move(VHDL_Tools::VHDL_AST_Node* parentNode);
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
@@ -27,12 +27,12 VHDL_Tools::vhdl_Scanner::vhdl_Scanner(s
27 {
27 {
28 this->rootNode = new VHDL_Tools::VHDL_AST_Node(fileName,VHDL_Tools::rootNode);
28 this->rootNode = new VHDL_Tools::VHDL_AST_Node(fileName,VHDL_Tools::rootNode);
29 this->currentNode = rootNode;
29 this->currentNode = rootNode;
30 this->rootNode->parent = this->rootNode;
30 this->rootNode->setParent(this->rootNode);
31 }
31 }
32
32
33 VHDL_Tools::vhdl_Scanner::~vhdl_Scanner()
33 VHDL_Tools::vhdl_Scanner::~vhdl_Scanner()
34 {
34 {
35 deleteNode(rootNode);
35 delete rootNode;
36 }
36 }
37
37
38
38
@@ -45,27 +45,20 int VHDL_Tools::vhdl_Scanner::newFile(st
45 {
45 {
46 switch_streams(in);
46 switch_streams(in);
47 if(trashPreviousTree)
47 if(trashPreviousTree)
48 deleteNode(rootNode);
48 delete rootNode;
49 this->yylineno=1;
50 this->yycolumn=1;
49 this->rootNode = new VHDL_Tools::VHDL_AST_Node(fileName,VHDL_Tools::rootNode);
51 this->rootNode = new VHDL_Tools::VHDL_AST_Node(fileName,VHDL_Tools::rootNode);
50 this->currentNode = rootNode;
52 this->currentNode = rootNode;
51 this->rootNode->parent = this->rootNode;
53 this->rootNode->setParent(this->rootNode);
52 return 1;
54 return 1;
53 }
55 }
54
56
55
57
56 void VHDL_Tools::vhdl_Scanner::appendNode(VHDL_Tools::VHDL_AST_Node *node)
58 void VHDL_Tools::vhdl_Scanner::appendNode(VHDL_Tools::VHDL_AST_Node *node)
57 {
59 {
58 this->currentNode->childs.append(node);
60 node->move(currentNode);
59 node->parent = this->currentNode;
61 // this->currentNode->childs.append(node);
62 // node->parent = this->currentNode;
60 this->currentNode = node;
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 }
@@ -31,8 +31,6
31 #include <QList>
31 #include <QList>
32 #include <QStack>
32 #include <QStack>
33 #include "vhdl_ast_node.h"
33 #include "vhdl_ast_node.h"
34 #include "vhdl_fragment.h"
35
36 #undef YY_DECL
34 #undef YY_DECL
37 #define YY_DECL int VHDL_Tools::vhdl_Scanner::yylex()
35 #define YY_DECL int VHDL_Tools::vhdl_Scanner::yylex()
38
36
@@ -59,8 +57,9 public:
59 private:
57 private:
60 /* hide this one from public view */
58 /* hide this one from public view */
61 int yylex();
59 int yylex();
60 /* handle locations */
61 int yycolumn;
62 void appendNode(VHDL_Tools::VHDL_AST_Node* node);
62 void appendNode(VHDL_Tools::VHDL_AST_Node* node);
63 void deleteNode(VHDL_Tools::VHDL_AST_Node* node);
64 VHDL_Tools::VHDL_AST_Node* rootNode,*currentNode;
63 VHDL_Tools::VHDL_AST_Node* rootNode,*currentNode;
65 };
64 };
66 }
65 }
@@ -6,35 +6,11 VHDL_Tools::VHDL_File::VHDL_File()
6 this->scanner = NULL;
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 bool VHDL_Tools::VHDL_File::parseFile(const QString &file, bool trashPreviousTree)
10 bool VHDL_Tools::VHDL_File::parseFile(const QString &file, bool trashPreviousTree)
23 {
11 {
24 std::ifstream in_file( file.toStdString().c_str() );
12 std::ifstream in_file( file.toStdString().c_str() );
25 if( ! in_file.good() ) return false;
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 if(scanner==NULL)
14 if(scanner==NULL)
39 {
15 {
40 try
16 try
@@ -48,6 +24,7 bool VHDL_Tools::VHDL_File::parseFile(co
48 return false;
24 return false;
49 }
25 }
50 }
26 }
27 qDebug()<<"Parsing File "<<file<<"\n";
51 scanner->newFile(&in_file,file,trashPreviousTree);
28 scanner->newFile(&in_file,file,trashPreviousTree);
52 while (scanner->scan()!=0);
29 while (scanner->scan()!=0);
53 makeParseTree(scanner->getScanTree());
30 makeParseTree(scanner->getScanTree());
@@ -65,105 +42,46 int VHDL_Tools::VHDL_File::makeParseTree
65 VHDL_AST_Node *currentNode=rootNode;
42 VHDL_AST_Node *currentNode=rootNode;
66 QStack<VHDL_AST_Node*> openBlocks;
43 QStack<VHDL_AST_Node*> openBlocks;
67 openBlocks.push(rootNode);
44 openBlocks.push(rootNode);
68 while (currentNode)
45 do
46 {
47 parseNext(&currentNode,&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 switch (currentNode->type)
57 switch (currentNode->type)
71 {
58 {
72 case block:
73 openBlocks.push(currentNode);
74 walkForward(currentNode,-1);
75 break;
76 case entity:
59 case entity:
77 //Declaration or instanciation?
60 parse_Entity(&currentNode,openBlocksContext);
78 if(!((currentNode->parent->type == colon) && (currentNode->parent->parent->type==identifier)))
79 {
80 openBlocks.push(currentNode);
81 }
82 walkForward(currentNode,-1);
83 break;
61 break;
84 case units:
62 case architecture:
85 if(openBlocks.top()->type==clause)
63 parse_Architecture(&currentNode,openBlocksContext);
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);
102 break;
64 break;
103 case clause:
65 case clause:
104 openBlocks.push(currentNode);
66 parse_Clause(&currentNode,openBlocksContext);
105 walkForward(currentNode,-1);
106 break;
107 case endKw:
108 closeAndMatchBlock(&currentNode,&openBlocks,QList<VHDL_AST_Node_type>()<<units<<block<<identifier,true);
109 break;
110 case leftParen:
111 openBlocks.push(currentNode);
112 walkForward(currentNode,-1);
113 break;
67 break;
114 case rightParen:
68 case package:
115 if((openBlocks.top()->parent->type==port)||(openBlocks.top()->parent->type==generic))
69 parse_Package(&currentNode,openBlocksContext);
116 closeAndMatchBlock(&currentNode,&openBlocks,QList<VHDL_AST_Node_type>(),false);
117 else
118 closeAndMatchBlock(&currentNode,&openBlocks,QList<VHDL_AST_Node_type>(),false);
119 break;
120 case semicolon:
121 if(IS_CLOSED_BY_SEMICOLON(openBlocks.top()->type))
122 {
123 closeAndMatchBlock(&currentNode,&openBlocks,QList<VHDL_AST_Node_type>(),false);
124 }
125 else
126 {
127 walkForward(currentNode,0);
128 }
129 break;
70 break;
130 default:
71 default:
131 walkForward(currentNode,0);
72 walk_forward(&currentNode,0);
132 break;
73 break;
133 }
74 }
134 }
75 }
135 return 0;
76 *rootNode =currentNode;
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 }
165 return 0;
77 return 0;
166 }
78 }
167
79
168
80
169
81
82
83
84
85
86
87
@@ -1,10 +1,13
1 #ifndef VHDL_FILE_H
1 #ifndef VHDL_FILE_H
2 #define VHDL_FILE_H
2 #define VHDL_FILE_H
3
3
4 #include "vhdlparser_global.h"
4 #include "vhdlparser_global.h"
5 #include "scanner/vhdl_scanner.h"
5 #include "scanner/vhdl_scanner.h"
6 #include "vhdl_element_parser.h"
7 #include <QHash>
6 #include <QString>
8 #include <QString>
7 namespace VHDL_Tools {
9 namespace VHDL_Tools {
10
8 class VHDL_File
11 class VHDL_File
9 {
12 {
10
13
@@ -15,7 +18,8 public:
15 private:
18 private:
16 VHDL_Tools::vhdl_Scanner *scanner;
19 VHDL_Tools::vhdl_Scanner *scanner;
17 int makeParseTree(VHDL_Tools::VHDL_AST_Node* rootNode);
20 int makeParseTree(VHDL_Tools::VHDL_AST_Node* rootNode);
18 int closeAndMatchBlock(VHDL_Tools::VHDL_AST_Node** currentNode,QStack<VHDL_Tools::VHDL_AST_Node*>* openBlocksContext,QList<VHDL_Tools::VHDL_AST_Node_type>skipTypes,bool endWithSemicolon=false);
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 VHDL_Tools::VHDL_AST_Node* rootNode;
23 VHDL_Tools::VHDL_AST_Node* rootNode;
20 };
24 };
21
25
@@ -24,14 +24,14 INCLUDEPATH += \
24
24
25 SOURCES += vhdl_file.cpp \
25 SOURCES += vhdl_file.cpp \
26 scanner/vhdl_scanner.cpp \
26 scanner/vhdl_scanner.cpp \
27 scanner/vhdl_fragment.cpp \
27 scanner/vhdl_ast_node.cpp \
28 scanner/vhdl_ast_node.cpp
28 vhdl_element_parser.cpp
29
29
30 HEADERS += vhdl_file.h\
30 HEADERS += vhdl_file.h\
31 libvhdlparser_global.h \
31 libvhdlparser_global.h \
32 scanner/vhdl_scanner.h \
32 scanner/vhdl_scanner.h \
33 scanner/vhdl_fragment.h \
33 scanner/vhdl_ast_node.h \
34 scanner/vhdl_ast_node.h
34 vhdl_element_parser.h
35
35
36 unix {
36 unix {
37 target.path = /usr/lib
37 target.path = /usr/lib
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now