##// 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
@@ -1,111 +1,114
1 #include "mainwindow.h"
1 #include "mainwindow.h"
2 #include "ui_mainwindow.h"
2 #include "ui_mainwindow.h"
3 #include <QFileDialog>
3 #include <QFileDialog>
4 #include <QTreeWidget>
4 #include <QTreeWidget>
5 #include <QTreeWidgetItem>
5 #include <QTreeWidgetItem>
6
6
7 MainWindow::MainWindow(QWidget *parent) :
7 MainWindow::MainWindow(QWidget *parent) :
8 QMainWindow(parent),
8 QMainWindow(parent),
9 ui(new Ui::MainWindow)
9 ui(new Ui::MainWindow)
10 {
10 {
11 ui->setupUi(this);
11 ui->setupUi(this);
12 connect(this->ui->actionOpen,SIGNAL(triggered()),this,SLOT(openFile()));
12 connect(this->ui->actionOpen,SIGNAL(triggered()),this,SLOT(openFile()));
13 connect(this->ui->actionScan_Folder,SIGNAL(triggered()),this,SLOT(openFolder()));
13 connect(this->ui->actionScan_Folder,SIGNAL(triggered()),this,SLOT(openFolder()));
14 this->file = new VHDL_Tools::VHDL_File;
14 this->file = new VHDL_Tools::VHDL_File;
15 this->rootNode = NULL;
15 this->rootNode = NULL;
16 }
16 }
17
17
18 MainWindow::~MainWindow()
18 MainWindow::~MainWindow()
19 {
19 {
20 delete ui;
20 delete ui;
21 }
21 }
22
22
23 void MainWindow::openFile()
23 void MainWindow::openFile()
24 {
24 {
25 QString fileName = QFileDialog::getOpenFileName(this,
25 QString fileName = QFileDialog::getOpenFileName(this,
26 tr("Open VHDL file"), NULL, tr("VHDL Files (*.vhd)"));
26 tr("Open VHDL file"), NULL, tr("VHDL Files (*.vhd)"));
27 if(fileName!="")
27 if(fileName!="")
28 {
28 {
29 parseFile(fileName,true);
29 parseFile(fileName,true);
30 this->rootNode=file->getParseTree();
30 this->rootNode=file->getParseTree();
31 updateTree(rootNode);
31 updateTree(rootNode);
32 }
32 }
33 }
33 }
34
34
35 void MainWindow::openFolder()
35 void MainWindow::openFolder()
36 {
36 {
37 QString dir = QFileDialog::getExistingDirectory(this, tr("Open Directory"),
37 QString dir = QFileDialog::getExistingDirectory(this, tr("Open Directory"),
38 NULL,
38 NULL,
39 QFileDialog::ShowDirsOnly
39 QFileDialog::ShowDirsOnly
40 | QFileDialog::DontResolveSymlinks);
40 | QFileDialog::DontResolveSymlinks);
41 if(dir!="")
41 if(dir!="")
42 {
42 {
43 this->rootNode=new VHDL_Tools::VHDL_AST_Node(dir,VHDL_Tools::virtualGroup);
43 this->rootNode=new VHDL_Tools::VHDL_AST_Node(dir,VHDL_Tools::virtualGroup);
44 parseDirectory(dir);
44 parseDirectory(dir);
45 updateTree(this->rootNode);
45 updateTree(this->rootNode);
46 }
46 }
47 }
47 }
48
48
49
49
50 void MainWindow::updateTree(VHDL_Tools::VHDL_AST_Node *rootNode)
50 void MainWindow::updateTree(VHDL_Tools::VHDL_AST_Node *rootNode)
51 {
51 {
52 this->ui->VHDLtreeWidget->clear();
52 this->ui->VHDLtreeWidget->clear();
53 if(rootNode)
53 if(rootNode)
54 {
54 {
55 QTreeWidgetItem* item = new QTreeWidgetItem(QStringList()<<rootNode->a_value);
55 QTreeWidgetItem* item = new QTreeWidgetItem(QStringList()<<rootNode->a_value);
56 for(int i=0;i<rootNode->childs.count();i++)
56 for(int i=0;i<rootNode->childs.count();i++)
57 {
57 {
58 printNode(rootNode->childs.at(i),item);
58 printNode(rootNode->childs.at(i),item);
59 }
59 }
60 this->ui->VHDLtreeWidget->addTopLevelItem(item);
60 this->ui->VHDLtreeWidget->addTopLevelItem(item);
61 }
61 }
62 }
62 }
63
63
64 void MainWindow::printNode(VHDL_Tools::VHDL_AST_Node *rootNode, QTreeWidgetItem *parent)
64 void MainWindow::printNode(VHDL_Tools::VHDL_AST_Node *rootNode, QTreeWidgetItem *parent)
65 {
65 {
66 if(rootNode)
66 if(rootNode)
67 {
67 {
68 QTreeWidgetItem* item = new QTreeWidgetItem(parent,QStringList()<<rootNode->a_value);
68 QTreeWidgetItem* item = new QTreeWidgetItem(parent,QStringList()<<rootNode->a_value);
69 for(int i=0;i<rootNode->childs.count();i++)
69 for(int i=0;i<rootNode->childs.count();i++)
70 {
70 {
71 printNode(rootNode->childs.at(i),item);
71 printNode(rootNode->childs.at(i),item);
72 }
72 }
73 }
73 }
74 }
74 }
75
75
76 void MainWindow::parseFile(const QString &fileName, bool trashPreviousTree)
76 void MainWindow::parseFile(const QString &fileName, bool trashPreviousTree)
77 {
77 {
78 if(fileName!="")
78 if(fileName!="")
79 this->file->parseFile(fileName,trashPreviousTree);
79 this->file->parseFile(fileName,trashPreviousTree);
80 }
80 }
81
81
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 {
95 if(list.at(i).isFile() && (!list.at(i).completeSuffix().compare("vhd")))
95 if(list.at(i).isFile() && (!list.at(i).completeSuffix().compare("vhd")))
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 if(parseTree!=NULL)
100 {
99 this->rootNode->childs.append(parseTree);
101 this->rootNode->childs.append(parseTree);
100 parseTree->parent = this->rootNode;
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 #ifndef MAINWINDOW_H
1 #ifndef MAINWINDOW_H
2 #define MAINWINDOW_H
2 #define MAINWINDOW_H
3
3
4 #include <QMainWindow>
4 #include <QMainWindow>
5 #include <vhdl_file.h>
5 #include <vhdl_file.h>
6 #include <QTreeWidgetItem>
6 #include <QTreeWidgetItem>
7
7
8 namespace Ui {
8 namespace Ui {
9 class MainWindow;
9 class MainWindow;
10 }
10 }
11
11
12 class MainWindow : public QMainWindow
12 class MainWindow : public QMainWindow
13 {
13 {
14 Q_OBJECT
14 Q_OBJECT
15
15
16 public:
16 public:
17 explicit MainWindow(QWidget *parent = 0);
17 explicit MainWindow(QWidget *parent = 0);
18 ~MainWindow();
18 ~MainWindow();
19
19
20 private slots:
20 private slots:
21 void openFile();
21 void openFile();
22 void openFolder();
22 void openFolder();
23 private:
23 private:
24 void updateTree(VHDL_Tools::VHDL_AST_Node* rootNode);
24 void updateTree(VHDL_Tools::VHDL_AST_Node* rootNode);
25 void printNode(VHDL_Tools::VHDL_AST_Node* rootNode,QTreeWidgetItem* parent);
25 void printNode(VHDL_Tools::VHDL_AST_Node* rootNode,QTreeWidgetItem* parent);
26 void parseFile(const QString& fileName, bool trashPreviousTree=false);
26 void parseFile(const QString& fileName, bool trashPreviousTree=false);
27 void parseDirectory(const QString& dirName);
27 void parseDirectory(const QString& dirName);
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
@@ -1,250 +1,292
1 %{
1 %{
2 /* C++ string header, for string ops below */
2 /* C++ string header, for string ops below */
3 #include <string>
3 #include <string>
4 #include <QString>
4 #include <QString>
5 /* Implementation of yyFlexScanner */
5 /* Implementation of yyFlexScanner */
6 #include "vhdl_scanner.h"
6 #include "vhdl_scanner.h"
7 #include <QDebug>
7 #include <QDebug>
8 /* define to keep from re-typing the same code over and over */
8 /* define to keep from re-typing the same code over and over */
9 #define STOKEN( x ) ( new QString( x ) )
9 #define STOKEN( x ) ( new QString( x ) )
10
10
11 /* define yyterminate as this instead of NULL */
11 /* define yyterminate as this instead of NULL */
12 //#define yyterminate() return( token::END )
12 //#define yyterminate() return( token::END )
13
13
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
22 %}
21 %}
23 %option debug
22 %option debug
24 %option nodefault
23 %option nodefault
25 %option yyclass="vhdl_Scanner"
24 %option yyclass="vhdl_Scanner"
26 %option case-insensitive yylineno
25 %option case-insensitive yylineno
27 %option noyywrap
26 %option noyywrap
28 %option c++
27 %option c++
29
28
30
29
31 %%
30 %%
32
31
33 /*-----------------------------------------------------------*/
32 /*-----------------------------------------------------------*/
34 /*Separators*/
33 /*Separators*/
35 [ \t]+ { } //skip new lines, blanc spaces and tabulations
34 [ \t]+ { } //skip new lines, blanc spaces and tabulations
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 |
70 impure |
62 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 |
78 mod |
69 mod |
79 nand |
70 nand |
80 new |
71 new |
81 next |
72 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 |
89 others |
79 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
170 /*-----------------------------------------------------------*/
199 /*-----------------------------------------------------------*/
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));}
177
209
178 \'(0|1)\' {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));}
210 \'(0|1)\' {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));}
179
211
180 \'.\' {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));}
212 \'.\' {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::literal,yylineno, yycolumn-yyleng));}
181
213
182
214
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));}
198
230
199 /*-----------------------------------------------------------*/
231 /*-----------------------------------------------------------*/
200
232
201 /*character literal (a graphical character surrounded by ‘, e.g.: ‘H’)*/
233 /*character literal (a graphical character surrounded by ‘, e.g.: ‘H’)*/
202 /*-----------------------------------------------------------*/
234 /*-----------------------------------------------------------*/
203
235
204 /*string literal (a sequence of graphical characters surrounded by ”, e.g.: ”HAR-DI”)*/
236 /*string literal (a sequence of graphical characters surrounded by ”, e.g.: ”HAR-DI”)*/
205 /*-----------------------------------------------------------*/
237 /*-----------------------------------------------------------*/
206
238
207 /* bit string literal (a sequence of extended digits * surrounded by ”, e.g.: ”011”)*/
239 /* bit string literal (a sequence of extended digits * surrounded by ”, e.g.: ”011”)*/
208 /*-----------------------------------------------------------*/
240 /*-----------------------------------------------------------*/
209
241
210 /* delimiter*/
242 /* delimiter*/
211 \. | \| | \[ | \] |
243 \. |
212 \:= | \>\= |
244 \| |
213 \<\= |
245 \[ |
246 \] |
247 \>\= |
214 \/\= |
248 \/\= |
215 \= |
249 \= |
216 \> |
250 \> |
217 \< |
251 \< |
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
233
275
234 \( {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::leftParen,yylineno, yycolumn-yyleng));}
276 \( {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::leftParen,yylineno, yycolumn-yyleng));}
235
277
236 \) {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::rightParen,yylineno, yycolumn-yyleng));}
278 \) {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::rightParen,yylineno, yycolumn-yyleng));}
237
279
238
280
239 \; {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::semicolon,yylineno, yycolumn-yyleng)); }
281 \; {this->appendNode(new VHDL_Tools::VHDL_AST_Node(YYText(),VHDL_Tools::semicolon,yylineno, yycolumn-yyleng)); }
240
282
241 . printf("bad input character '%s' at line %d column %d\n ", yytext, yylineno,yycolumn-yyleng);
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 -- This file is a part of the VHDL Tools Software
2 -- This file is a part of the VHDL Tools Software
3 -- Copyright (C) 2014, Plasma Physics Laboratory - CNRS
3 -- Copyright (C) 2014, Plasma Physics Laboratory - CNRS
4 --
4 --
5 -- This program is free software; you can redistribute it and/or modify
5 -- This program is free software; you can redistribute it and/or modify
6 -- it under the terms of the GNU General Public License as published by
6 -- it under the terms of the GNU General Public License as published by
7 -- the Free Software Foundation; either version 2 of the License, or
7 -- the Free Software Foundation; either version 2 of the License, or
8 -- (at your option) any later version.
8 -- (at your option) any later version.
9 --
9 --
10 -- This program is distributed in the hope that it will be useful,
10 -- This program is distributed in the hope that it will be useful,
11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 -- GNU General Public License for more details.
13 -- GNU General Public License for more details.
14 --
14 --
15 -- You should have received a copy of the GNU General Public License
15 -- You should have received a copy of the GNU General Public License
16 -- along with this program; if not, write to the Free Software
16 -- along with this program; if not, write to the Free Software
17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 -------------------------------------------------------------------------------*/
18 -------------------------------------------------------------------------------*/
19 /*-- Author : Alexis Jeandet
19 /*-- Author : Alexis Jeandet
20 -- Mail : alexis.jeandet@member.fsf.org
20 -- Mail : alexis.jeandet@member.fsf.org
21 ----------------------------------------------------------------------------*/
21 ----------------------------------------------------------------------------*/
22 #include "vhdl_ast_node.h"
22 #include "vhdl_ast_node.h"
23
23
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 }
@@ -1,78 +1,121
1 /*------------------------------------------------------------------------------
1 /*------------------------------------------------------------------------------
2 -- This file is a part of the VHDL Tools Software
2 -- This file is a part of the VHDL Tools Software
3 -- Copyright (C) 2014, Plasma Physics Laboratory - CNRS
3 -- Copyright (C) 2014, Plasma Physics Laboratory - CNRS
4 --
4 --
5 -- This program is free software; you can redistribute it and/or modify
5 -- This program is free software; you can redistribute it and/or modify
6 -- it under the terms of the GNU General Public License as published by
6 -- it under the terms of the GNU General Public License as published by
7 -- the Free Software Foundation; either version 2 of the License, or
7 -- the Free Software Foundation; either version 2 of the License, or
8 -- (at your option) any later version.
8 -- (at your option) any later version.
9 --
9 --
10 -- This program is distributed in the hope that it will be useful,
10 -- This program is distributed in the hope that it will be useful,
11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 -- GNU General Public License for more details.
13 -- GNU General Public License for more details.
14 --
14 --
15 -- You should have received a copy of the GNU General Public License
15 -- You should have received a copy of the GNU General Public License
16 -- along with this program; if not, write to the Free Software
16 -- along with this program; if not, write to the Free Software
17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 -------------------------------------------------------------------------------*/
18 -------------------------------------------------------------------------------*/
19 /*-- Author : Alexis Jeandet
19 /*-- Author : Alexis Jeandet
20 -- Mail : alexis.jeandet@member.fsf.org
20 -- Mail : alexis.jeandet@member.fsf.org
21 ----------------------------------------------------------------------------*/
21 ----------------------------------------------------------------------------*/
22 #ifndef VHDL_AST_NODE_H
22 #ifndef VHDL_AST_NODE_H
23 #define VHDL_AST_NODE_H
23 #define VHDL_AST_NODE_H
24 #include <QString>
24 #include <QString>
25 #include <QList>
25 #include <QList>
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)
35 #define IS_CLOSED_BY_RIGHTPAREN(type) (((type)&0xF00)==closedByRightParen)
35 #define IS_CLOSED_BY_RIGHTPAREN(type) (((type)&0xF00)==closedByRightParen)
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};
63
100
64 class VHDL_AST_Node
101 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
78 #endif // VHDL_AST_NODE_H
121 #endif // VHDL_AST_NODE_H
@@ -1,71 +1,64
1 /*------------------------------------------------------------------------------
1 /*------------------------------------------------------------------------------
2 -- This file is a part of the VHDL Tools Software
2 -- This file is a part of the VHDL Tools Software
3 -- Copyright (C) 2014, Plasma Physics Laboratory - CNRS
3 -- Copyright (C) 2014, Plasma Physics Laboratory - CNRS
4 --
4 --
5 -- This program is free software; you can redistribute it and/or modify
5 -- This program is free software; you can redistribute it and/or modify
6 -- it under the terms of the GNU General Public License as published by
6 -- it under the terms of the GNU General Public License as published by
7 -- the Free Software Foundation; either version 2 of the License, or
7 -- the Free Software Foundation; either version 2 of the License, or
8 -- (at your option) any later version.
8 -- (at your option) any later version.
9 --
9 --
10 -- This program is distributed in the hope that it will be useful,
10 -- This program is distributed in the hope that it will be useful,
11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 -- GNU General Public License for more details.
13 -- GNU General Public License for more details.
14 --
14 --
15 -- You should have received a copy of the GNU General Public License
15 -- You should have received a copy of the GNU General Public License
16 -- along with this program; if not, write to the Free Software
16 -- along with this program; if not, write to the Free Software
17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 -------------------------------------------------------------------------------*/
18 -------------------------------------------------------------------------------*/
19 /*-- Author : Alexis Jeandet
19 /*-- Author : Alexis Jeandet
20 -- Mail : alexis.jeandet@member.fsf.org
20 -- Mail : alexis.jeandet@member.fsf.org
21 ----------------------------------------------------------------------------*/
21 ----------------------------------------------------------------------------*/
22 #include "vhdl_scanner.h"
22 #include "vhdl_scanner.h"
23 #include <QDebug>
23 #include <QDebug>
24
24
25 VHDL_Tools::vhdl_Scanner::vhdl_Scanner(std::istream *in, const QString &fileName)
25 VHDL_Tools::vhdl_Scanner::vhdl_Scanner(std::istream *in, const QString &fileName)
26 : yyFlexLexer(in)
26 : yyFlexLexer(in)
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
39 int VHDL_Tools::vhdl_Scanner::scan()
39 int VHDL_Tools::vhdl_Scanner::scan()
40 {
40 {
41 return( yylex() );
41 return( yylex() );
42 }
42 }
43
43
44 int VHDL_Tools::vhdl_Scanner::newFile(std::istream *in, const QString &fileName,bool trashPreviousTree)
44 int VHDL_Tools::vhdl_Scanner::newFile(std::istream *in, const QString &fileName,bool trashPreviousTree)
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 }
@@ -1,68 +1,67
1 /*------------------------------------------------------------------------------
1 /*------------------------------------------------------------------------------
2 -- This file is a part of the VHDL Tools Software
2 -- This file is a part of the VHDL Tools Software
3 -- Copyright (C) 2014, Plasma Physics Laboratory - CNRS
3 -- Copyright (C) 2014, Plasma Physics Laboratory - CNRS
4 --
4 --
5 -- This program is free software; you can redistribute it and/or modify
5 -- This program is free software; you can redistribute it and/or modify
6 -- it under the terms of the GNU General Public License as published by
6 -- it under the terms of the GNU General Public License as published by
7 -- the Free Software Foundation; either version 2 of the License, or
7 -- the Free Software Foundation; either version 2 of the License, or
8 -- (at your option) any later version.
8 -- (at your option) any later version.
9 --
9 --
10 -- This program is distributed in the hope that it will be useful,
10 -- This program is distributed in the hope that it will be useful,
11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 -- GNU General Public License for more details.
13 -- GNU General Public License for more details.
14 --
14 --
15 -- You should have received a copy of the GNU General Public License
15 -- You should have received a copy of the GNU General Public License
16 -- along with this program; if not, write to the Free Software
16 -- along with this program; if not, write to the Free Software
17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 -------------------------------------------------------------------------------*/
18 -------------------------------------------------------------------------------*/
19 /*-- Author : Alexis Jeandet
19 /*-- Author : Alexis Jeandet
20 -- Mail : alexis.jeandet@member.fsf.org
20 -- Mail : alexis.jeandet@member.fsf.org
21 ----------------------------------------------------------------------------*/
21 ----------------------------------------------------------------------------*/
22 #ifndef vhdl_SCANNER_H
22 #ifndef vhdl_SCANNER_H
23 #define vhdl_SCANNER_H
23 #define vhdl_SCANNER_H
24 #if ! defined(yyFlexLexerOnce)
24 #if ! defined(yyFlexLexerOnce)
25 #include <FlexLexer.h>
25 #include <FlexLexer.h>
26 #endif
26 #endif
27 #include <iostream>
27 #include <iostream>
28 #include <cstdlib>
28 #include <cstdlib>
29 #include <fstream>
29 #include <fstream>
30 #include <QString>
30 #include <QString>
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
39 namespace VHDL_Tools{
37 namespace VHDL_Tools{
40
38
41 class vhdl_Scanner_block_stack
39 class vhdl_Scanner_block_stack
42 {
40 {
43 public:
41 public:
44 vhdl_Scanner_block_stack(bool waitForSemicolon,bool waitForParen, int delta)
42 vhdl_Scanner_block_stack(bool waitForSemicolon,bool waitForParen, int delta)
45 :waitForSemicolon(waitForSemicolon),waitForParen(waitForParen),stackDelta(delta){}
43 :waitForSemicolon(waitForSemicolon),waitForParen(waitForParen),stackDelta(delta){}
46 bool waitForSemicolon;
44 bool waitForSemicolon;
47 bool waitForParen;
45 bool waitForParen;
48 int stackDelta;
46 int stackDelta;
49 };
47 };
50
48
51 class vhdl_Scanner : public yyFlexLexer
49 class vhdl_Scanner : public yyFlexLexer
52 {
50 {
53 public:
51 public:
54 vhdl_Scanner(std::istream *in,const QString& fileName);
52 vhdl_Scanner(std::istream *in,const QString& fileName);
55 ~vhdl_Scanner();
53 ~vhdl_Scanner();
56 int scan();
54 int scan();
57 int newFile(std::istream *in, const QString& fileName, bool trashPreviousTree=false);
55 int newFile(std::istream *in, const QString& fileName, bool trashPreviousTree=false);
58 VHDL_Tools::VHDL_AST_Node* getScanTree(){return rootNode;}
56 VHDL_Tools::VHDL_AST_Node* getScanTree(){return rootNode;}
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 }
67
66
68 #endif // vhdl_SCANNER_H
67 #endif // vhdl_SCANNER_H
@@ -1,169 +1,87
1 #include "vhdl_file.h"
1 #include "vhdl_file.h"
2 #include <QDebug>
2 #include <QDebug>
3
3
4 VHDL_Tools::VHDL_File::VHDL_File()
4 VHDL_Tools::VHDL_File::VHDL_File()
5 {
5 {
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
41 {
17 {
42 scanner = new VHDL_Tools::vhdl_Scanner( &in_file ,file);
18 scanner = new VHDL_Tools::vhdl_Scanner( &in_file ,file);
43 }
19 }
44 catch( std::bad_alloc &ba )
20 catch( std::bad_alloc &ba )
45 {
21 {
46 std::cerr << "Failed to allocate scanner: (" <<
22 std::cerr << "Failed to allocate scanner: (" <<
47 ba.what() << ")\n";
23 ba.what() << ")\n";
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());
54 return false;
31 return false;
55 }
32 }
56
33
57 VHDL_Tools::VHDL_AST_Node *VHDL_Tools::VHDL_File::getParseTree()
34 VHDL_Tools::VHDL_AST_Node *VHDL_Tools::VHDL_File::getParseTree()
58 {
35 {
59 return rootNode;
36 return rootNode;
60 }
37 }
61
38
62 int VHDL_Tools::VHDL_File::makeParseTree(VHDL_AST_Node *rootNode)
39 int VHDL_Tools::VHDL_File::makeParseTree(VHDL_AST_Node *rootNode)
63 {
40 {
64 this->rootNode = rootNode;
41 this->rootNode = rootNode;
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,23 +1,27
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
11 public:
14 public:
12 VHDL_File();
15 VHDL_File();
13 bool parseFile(const QString& file, bool trashPreviousTree=false);
16 bool parseFile(const QString& file, bool trashPreviousTree=false);
14 VHDL_Tools::VHDL_AST_Node* getParseTree();
17 VHDL_Tools::VHDL_AST_Node* getParseTree();
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
22 }
26 }
23 #endif // VHDL_FILE_H
27 #endif // VHDL_FILE_H
@@ -1,40 +1,40
1 #-------------------------------------------------
1 #-------------------------------------------------
2 #
2 #
3 # Project created by QtCreator 2014-07-20T21:32:03
3 # Project created by QtCreator 2014-07-20T21:32:03
4 #
4 #
5 #-------------------------------------------------
5 #-------------------------------------------------
6
6
7 QT -= gui
7 QT -= gui
8
8
9
9
10 include ( ./scanner/Flex_Bison_FIles/Flex_Bison_FIles.pri )
10 include ( ./scanner/Flex_Bison_FIles/Flex_Bison_FIles.pri )
11
11
12 TARGET = vhdlparser
12 TARGET = vhdlparser
13 TEMPLATE = lib
13 TEMPLATE = lib
14
14
15 LIBS += -lfl
15 LIBS += -lfl
16
16
17 DEFINES += LIBVHDLPARSER_LIBRARY
17 DEFINES += LIBVHDLPARSER_LIBRARY
18 DESTDIR = ../bin
18 DESTDIR = ../bin
19
19
20 INCLUDEPATH += ./scanner
20 INCLUDEPATH += ./scanner
21 INCLUDEPATH += \
21 INCLUDEPATH += \
22 ../vhdlparser
22 ../vhdlparser
23
23
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
38 INSTALLS += target
38 INSTALLS += target
39 }
39 }
40
40
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