Imported Upstream version 1.8.15
[platform/upstream/doxygen.git] / src / vhdlcode.l
1 /******************************************************************************
2  *
3  * Copyright (C) 1997-2015 by Dimitri van Heesch.
4  *
5  * Permission to use, copy, modify, and distribute this software and its
6  * documentation under the terms of the GNU General Public License is hereby 
7  * granted. No representations are made about the suitability of this software 
8  * for any purpose. It is provided "as is" without express or implied warranty.
9  * See the GNU General Public License for more details.
10  *
11  * Documents produced by Doxygen are derivative works derived from the
12  * input used in their production; they are not affected by this license.
13  *
14  */
15 /******************************************************************************
16  * Parser for syntax highlighting and references for vhdl subset
17  * written by M. Kreis
18  * supports VHDL-87/93/2008
19  ******************************************************************************/
20 %option never-interactive
21 %option case-insensitive
22 %option prefix="vhdlcodeYY"
23
24 %{
25
26 /*
27  *        includes
28  */
29 #include <stdio.h>
30 #include <assert.h>
31 #include <ctype.h>
32 #include <qregexp.h>
33 #include <qdir.h>
34 #include <qcstringlist.h>
35
36 #include "entry.h"
37 #include "doxygen.h"
38 #include "message.h"
39 #include "outputlist.h"
40 #include "util.h"
41 #include "membername.h"
42 #include "searchindex.h"
43 #include "vhdldocgen.h"
44 #include "arguments.h"
45 #include "config.h"
46 #include "classdef.h"
47 #include "filedef.h"
48 #include "tooltip.h"
49
50 #define YY_NO_INPUT 1
51 #define YY_NO_UNISTD_H 1
52   
53 // Toggle for some debugging info
54 //#define DBG_CTX(x) fprintf x
55 #define DBG_CTX(x) do { } while(0)
56   
57
58 /* -----------------------------------------------------------------
59  *        statics
60  */
61
62 // ----------------- <vhdl> ----------------------------------
63
64 //static bool isPackBody=FALSE;
65 //static bool isStartMap;
66 static bool isFuncProto=FALSE;
67 static bool isComponent=FALSE;
68 static bool isPackageBody=FALSE;
69 static bool isProto = FALSE;
70 static bool       g_startCode = FALSE;
71 static QCString   g_PrevString;
72 static QCString   g_CurrClass;
73 static QDict<QCString>g_vhdlKeyDict;   
74 static QCString   g_tempComp;
75 static QCString   g_PortMapComp;
76 static MemberDef *g_vhdlMember;
77 static QCString   g_FuncProto;
78
79 //-----------------------------------------------------------
80   
81 static CodeOutputInterface * g_code;
82 static QCString      g_parmType;
83 static QCString      g_parmName;
84 static const char *  g_inputString;     //!< the code fragment as text
85 static int           g_inputPosition;   //!< read offset during parsing 
86 static int           g_inputLines;      //!< number of line in the code fragment
87 static int           g_yyLineNr;        //!< current line number
88 static bool          g_needsTermination;
89 static Definition   *g_searchCtx;
90
91 static bool          g_exampleBlock;
92 static QCString      g_exampleName;
93 static QCString      g_exampleFile;
94
95 static QCString      g_classScope;
96    
97 static bool          g_CurrARCH = FALSE;
98    
99 static FileDef *     g_sourceFileDef;
100 static Definition *  g_currentDefinition;
101 static MemberDef *   g_currentMemberDef;
102 static bool          g_includeCodeFragment;
103 static const char *  g_currentFontClass;
104
105 static bool          g_lexInit = FALSE;
106 static int           g_braceCount=0;
107
108
109 static void writeFont(const char *s,const char* text);
110 static void generateMemLink(CodeOutputInterface &ol,QCString &clName,QCString& memberName);
111 static bool writeColoredWord(QCString& word );
112 static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName, bool typeOnly=FALSE, const char *curr_class=0);
113 static void endFontClass();
114 static void startFontClass(const char *s);
115 //-------------------------------------------------------------------
116
117
118 static void setCurrentDoc(const QCString &anchor)
119 {
120   if (Doxygen::searchIndex)
121   {
122     if (g_searchCtx)
123     {
124       Doxygen::searchIndex->setCurrentDoc(g_searchCtx,g_searchCtx->anchor(),FALSE);
125     }
126     else
127     {
128       Doxygen::searchIndex->setCurrentDoc(g_sourceFileDef,anchor,TRUE);
129     }
130   }
131 }
132
133 static bool checkVhdlString(QCString &name)
134 {
135   if (name.isEmpty()) return FALSE;
136   static QRegExp regg("[\\s\"]");
137
138   int len=name.length();
139   if (name.at(0)=='"' && name.at(len-1)=='"' && len > 2)
140   {
141     QCStringList qrl=QCStringList::split(regg,name);
142     if (VhdlDocGen::isNumber(qrl[0]))
143     {
144       g_code->codify("\""); 
145       startFontClass("vhdllogic");
146       QCString mid=name.mid(1,len-2); //" 1223 "
147       g_code->codify(mid.data());
148       endFontClass();
149       g_code->codify("\""); 
150     }
151     else
152     {
153       startFontClass("keyword");
154       g_code->codify(name.data());
155       endFontClass();
156     }
157     return TRUE;
158   }
159
160   if (VhdlDocGen::isNumber(name))
161   {
162     startFontClass("vhdllogic");
163     g_code->codify(name.data());
164     endFontClass();
165     return TRUE;
166   }
167   return FALSE;
168 }
169
170 static void addToSearchIndex(const char *text)
171 {
172   if (Doxygen::searchIndex)
173   {
174     Doxygen::searchIndex->addWord(text,FALSE);
175   }
176 }
177
178
179 /*! start a new line of code, inserting a line number if g_sourceFileDef
180  * is TRUE. If a definition starts at the current line, then the line
181  * number is linked to the documentation of that definition.
182  */
183 static void startCodeLine()
184 {
185   //if (g_currentFontClass) { g_code->endFontClass(); }
186   if (g_sourceFileDef)
187   {
188     //QCString lineNumber,lineAnchor;
189     //lineNumber.sprintf("%05d",g_yyLineNr);
190     //lineAnchor.sprintf("l%05d",g_yyLineNr);
191     //  if ((g_yyLineNr % 500) == 0) 
192     //         fprintf(stderr,"\n starting Line %d:",g_yyLineNr);
193     Definition *d   = g_sourceFileDef->getSourceDefinition(g_yyLineNr);
194     //printf("startCodeLine %d d=%s\n", g_yyLineNr,d ? d->name().data() : "<null>");
195     if (!g_includeCodeFragment && d)
196     {
197       g_currentDefinition = d;
198       g_currentMemberDef = g_sourceFileDef->getSourceMember(g_yyLineNr);
199       if (!g_tempComp.isEmpty() && g_currentMemberDef )
200       {
201         //ClassDef *cf=VhdlDocGen::getClass(g_tempComp.data());
202         QCString nn=g_currentMemberDef->name();
203         MemberDef* mdeff=VhdlDocGen::findMember(g_tempComp,nn);
204         if (mdeff)
205         {
206           g_currentMemberDef=mdeff;
207         }
208       }
209
210       g_parmType.resize(0);
211       g_parmName.resize(0);
212       QCString lineAnchor;
213       lineAnchor.sprintf("l%05d",g_yyLineNr);
214       if (g_currentMemberDef)
215       {
216         g_code->writeLineNumber(g_currentMemberDef->getReference(),
217                                 g_currentMemberDef->getOutputFileBase(),
218                                 g_currentMemberDef->anchor(),g_yyLineNr);
219         setCurrentDoc(lineAnchor);
220       }
221       else if (d->isLinkableInProject())
222       {
223         g_code->writeLineNumber(d->getReference(),
224                                 d->getOutputFileBase(),
225                                 0,g_yyLineNr);
226         setCurrentDoc(lineAnchor);
227       }
228     }
229     else
230     {
231       g_code->writeLineNumber(0,0,0,g_yyLineNr);
232     }
233   }
234   g_code->startCodeLine(g_sourceFileDef); 
235   g_startCode=TRUE;
236   if (g_currentFontClass)
237   {
238     g_code->startFontClass(g_currentFontClass);
239   }
240 }
241
242 static void endCodeLine()
243 {
244   endFontClass();
245   g_code->endCodeLine();
246 }
247
248 static void nextCodeLine()
249 {
250   if (g_startCode)
251   {
252     endCodeLine();    // </div>
253   }
254   const char *fc = g_currentFontClass;
255   if (g_yyLineNr<g_inputLines) 
256   {
257     g_currentFontClass = fc;
258     startCodeLine();  //<div>
259   }
260 }
261
262 /*! writes a word to the output.
263  *  If curr_class is defined, the word belongs to a class
264  *  and will be linked.
265  */
266
267 static void writeWord(const char *word,const char* curr_class=0,bool classLink=FALSE)
268 {
269   bool found=FALSE;
270   QCString temp; 
271   QCString tclass(curr_class);
272   QCString ttt(word);
273   if (ttt.isEmpty()) return;
274   for (unsigned int j=0;j<ttt.length();j++)
275   {
276     char c=ttt.at(j);
277     if (c==' '|| c==',' || c==';' || c==':' || c=='(' || c==')' || c=='\r' || c=='\t' || c=='.')
278     {
279       if (found)
280       {
281         if (!writeColoredWord(temp)) // is it a keyword ?
282         {
283           //if (VhdlDocGen::findKeyWord(temp))
284           // writeFont("vhdlkeyword",temp.data());
285           //printf("writeWord: %s\n",temp.data());
286           if (!tclass.isEmpty())
287           {
288             if (!classLink)
289             {
290               generateMemLink(*g_code,tclass,temp);
291             }
292             else
293             {
294               generateClassOrGlobalLink(*g_code,temp,FALSE,curr_class);
295             }
296           }
297           else                                                                          
298           {
299           if (!checkVhdlString(temp))
300             g_code->codify(temp.data());
301           }
302         }
303         temp.resize(0);
304         found=FALSE;
305       }
306
307       char cc[2];
308       cc[0]=c;
309       cc[1]=0;
310       g_code->codify(cc);
311     }
312     else
313     {
314       found=TRUE;
315       temp+=c;
316     }
317   } // for
318
319   if (!temp.isEmpty())
320   {
321     if (!writeColoredWord(temp))
322     {
323       if (!tclass.isEmpty())
324       {
325         if (!classLink)
326         {
327           generateMemLink(*g_code,tclass,temp); // generateMemLink(*g_code,g_CurrClass,left); 
328         }
329         else
330         {
331           generateClassOrGlobalLink(*g_code,temp,FALSE,curr_class);
332         }
333       }
334       else                 
335       {
336          QCString qc(temp.data());
337          if (VhdlDocGen::isNumber(qc)){
338                          startFontClass("vhdllogic");
339                          g_code->codify(temp.data());
340                          endFontClass();
341                               }
342          else     
343         g_code->codify(temp.data());
344       }
345     }
346   }
347 }// writeWord
348
349
350 /*! write a code fragment `text' that may span multiple lines, inserting
351  * line numbers for each line.
352  */
353 static void codifyLines(const char *text,const char *cl=0,bool classlink=FALSE,bool comment=FALSE)
354 {
355   if (text==0) return;
356   //printf("codifyLines(%d,\"%s\")\n",g_yyLineNr,text);
357   const char *p=text,*sp=p;
358   char c;
359   bool done=FALSE;
360   while (!done)
361   {
362     sp=p;
363     while ((c=*p++) && c!='\n') {}
364     if (c=='\n')
365     {
366       g_yyLineNr++;
367       QCString line = sp;
368       line = line.left((int)(p-sp)-1);
369       //*(p-1)='\0';
370       //g_code->codify(sp);
371       if (comment)
372       {
373         writeFont("comment",line.data());
374       }
375       else
376       {
377         writeWord(line,cl,classlink);
378       }
379       nextCodeLine();
380     }
381     else
382     {
383       if (comment)
384         writeFont("comment",sp);
385       else
386         writeWord(sp,cl,classlink);
387       done=TRUE;
388     }
389   }
390 }
391
392 /*! writes a link to a fragment \a text that may span multiple lines, inserting
393  * line numbers for each line. If \a text contains newlines, the link will be 
394  * split into multiple links with the same destination, one for each line.
395  */
396 static void writeMultiLineCodeLink(CodeOutputInterface &ol,
397                   Definition *d,
398                   const char *text)
399 {
400   static bool sourceTooltips = Config_getBool(SOURCE_TOOLTIPS);
401   TooltipManager::instance()->addTooltip(d);
402   QCString ref  = d->getReference();
403   QCString file = d->getOutputFileBase();
404   QCString anchor = d->anchor();
405   QCString tooltip; 
406   if (!sourceTooltips) // fall back to simple "title" tooltips
407   {
408     tooltip = d->briefDescriptionAsTooltip();
409   }
410   bool done=FALSE;
411   char *p=(char *)text;
412   while (!done)
413   {
414     char *sp=p;
415     char c;
416     while ((c=*p++) && c!='\n') {}
417     if (c=='\n')
418     {
419       g_yyLineNr++;
420       *(p-1)='\0';
421       // printf("writeCodeLink(%s,%s,%s,%s)\n",ref,file,anchor,sp);
422       ol.writeCodeLink(ref,file,anchor,sp,tooltip);
423       nextCodeLine();
424     }
425     else
426     {
427       ol.writeCodeLink(ref,file,anchor,sp,tooltip);
428       done=TRUE;
429     }
430   }
431 }
432
433 static void setParameterList(MemberDef *md)
434 {
435   g_classScope = md->getClassDef() ? md->getClassDef()->name().data() : "";
436   ArgumentList *al = md->argumentList();
437   if (al==0) return;
438   ArgumentListIterator ali(*al);
439   Argument *a;
440   for (ali.toFirst();(a=ali.current());++ali)
441   {
442     g_parmName = a->name.copy();
443     g_parmType = a->type.copy();
444     int i = g_parmType.find('*');
445     if (i!=-1) g_parmType = g_parmType.left(i);
446     i = g_parmType.find('&');
447     if (i!=-1) g_parmType = g_parmType.left(i);
448     g_parmType.stripPrefix("const ");
449     g_parmType=g_parmType.stripWhiteSpace();
450    // g_theVarContext.addVariable(g_parmType,g_parmName);
451   }
452 }
453
454
455 /*! writes a link to a function or procedure
456  */
457
458 static void generateFuncLink(CodeOutputInterface &ol,MemberDef* mdef)
459 {
460
461   //printf("generateFuncLink(FuncName=%s)\n",mdef->name().data());
462   QCString memberName=mdef->name();
463
464   if (mdef && mdef->isLinkable()) // is it a linkable class
465   {
466     writeMultiLineCodeLink(ol,mdef,mdef->name());
467     addToSearchIndex(memberName);
468     return;
469   }
470   codifyLines(memberName.data());
471   addToSearchIndex(memberName);
472 } // generateFuncLink
473
474
475 static void generateMemLink(CodeOutputInterface &ol,QCString &clName,QCString& memberName)
476 {
477   if (memberName.isEmpty()) return; 
478   if (clName.isEmpty())
479   {
480     codifyLines(memberName.data());
481
482    return;
483   }
484   
485   QCString className=clName;
486
487   MemberDef *md=0;
488   //MemberDef *comp=0;
489   //bool isLocal=FALSE;
490
491   md=VhdlDocGen::findMember(className,memberName);
492   ClassDef *po=VhdlDocGen::getClass(className.data());
493
494   if (md==0 && po && (VhdlDocGen::VhdlClasses)po->protection()==VhdlDocGen::PACKBODYCLASS) 
495   {
496     QCString temp=className;//.stripPrefix("_");
497     temp.stripPrefix("_");
498     md=VhdlDocGen::findMember(temp,memberName);
499   }
500
501   if (md && md->isLinkable()) // is it a linkable class
502   {
503     writeMultiLineCodeLink(ol,md,memberName);
504     addToSearchIndex(memberName);
505     return;
506   }
507   // nothing found, just write out the word
508   codifyLines(memberName.data());
509   addToSearchIndex(memberName);
510 }// generateMemLink
511
512
513 static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName, bool /*typeOnly*/, const char *curr_class)
514 {
515   QCString className=clName;
516
517   if (className.isEmpty()) return;
518
519   ClassDef *cd=0;
520   //MemberDef *md=0;
521   //bool isLocal=FALSE;
522   className.stripPrefix("_");
523   cd = getClass(className.data()); 
524   if (!cd && curr_class)
525   {
526      if (QCString(curr_class).contains(QRegExp("::"+QCString(clName)+"$"))) cd = getClass(curr_class);
527   }
528
529   while (cd)
530   {
531     //className.stripPrefix("_");
532     QCString temp(clName);
533     temp.stripPrefix("_");
534     if (cd && cd->isLinkable()) // is it a linkable class
535     {
536       //if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ARCHITECTURECLASS)
537       //{
538       //  temp=VhdlDocGen::getClassName(cd);
539       //}
540       writeMultiLineCodeLink(ol,cd,temp);
541       addToSearchIndex(className);
542       return;
543     }
544     Definition *d = cd->getOuterScope();
545     if (d && d->definitionType()==Definition::TypeClass)
546     {
547       cd = (ClassDef*)d;
548     }
549     else
550     {
551       cd = 0;
552     }
553   }
554
555   // nothing found, just write out the word
556   codifyLines(clName);
557   addToSearchIndex(clName);
558 }// generateClasss or global link
559
560
561 /*! counts the number of lines in the input */
562 static int countLines()
563 {
564   const char *p=g_inputString;
565   char c;
566   int count=1;
567   while ((c=*p)) 
568   { 
569     p++ ; 
570     if (c=='\n') count++;  
571   }
572   if (p>g_inputString && *(p-1)!='\n') 
573   { // last line does not end with a \n, so we add an extra
574     // line and explicitly terminate the line after parsing.
575     count++, 
576     g_needsTermination=TRUE; 
577   } 
578   return count;
579 }
580
581 static void endFontClass()
582 {
583   if (g_currentFontClass)
584   {
585     g_code->endFontClass();
586     g_currentFontClass=0;
587   }
588 }
589
590 static void startFontClass(const char *s)
591 {
592   if (s==0) return;
593   endFontClass();
594   g_code->startFontClass(s);
595   g_currentFontClass=s;
596 }
597
598 static void writeFont(const char *s,const char* text)
599 {
600   if (s==0 || text==0) return;
601   //printf("writeFont(%d,\"%s\")\n",g_yyLineNr,text);
602   g_code->startFontClass(s);
603   g_code->codify(text);
604   g_code->endFontClass();
605 }
606
607 //----------------------------------------------------------------------------
608
609 static void appStringLower(QCString& qcs,const char* text)
610 {
611   qcs.resize(0);
612   qcs.append(text);
613   //qcs=qcs.lower();
614   qcs=qcs.stripWhiteSpace();
615 }
616
617 //static void appString(QCString& qcs,const char* text)
618 //{
619 //  qcs.resize(0);
620 //  qcs.append(text);
621 //}
622
623 static QCString g_temp;
624
625 /* writes and links a port map statement */
626 static void codifyMapLines(const char *text)
627 {
628   if (text==0) return;
629   g_temp.resize(0);       
630   //bool dot=FALSE;
631   int wordCounter=0;
632   QCString ctemp;
633   //printf("codifyLines(%d,\"%s\")\n",g_yyLineNr,text);
634   const char *p=text; //,*sp=p;
635   char c;
636   bool done=FALSE;
637   while (!done)
638   {
639     //sp=p;
640     while ((c=*p++) &&  c!='\n' && c!=':' && c != ' ' && c != '(' && c!='\0' && c!='\t')
641     { 
642       if (c!=0x9)
643         g_temp+=c; 
644     }
645     if (c=='\0') return;
646     if (!g_temp.isEmpty()) wordCounter++;
647
648     if (!g_temp.isEmpty())
649     {
650       // different kinds of component instantiations
651       // xxx:yyy (generic/port) map(
652       // xxx:(entity/component/configuration) yyy (generic/port) map(
653       // xxx: entity yyy(zzz) (generic/port) map(
654       if (wordCounter==2 || wordCounter==3)
655       {
656         QCString q=g_temp.lower(); // consider (upper/lower) cases
657         if (q=="entity" || q=="component" || q=="configuration" || q=="port" || q=="generic")
658         {
659           generateMemLink(*g_code,g_CurrClass,g_temp); 
660         }
661         else
662         {
663           g_PortMapComp=g_temp;
664           generateClassOrGlobalLink(*g_code,g_temp);
665         }
666       }
667       else 
668       {
669         generateMemLink(*g_code,g_CurrClass,g_temp); 
670       }
671     }
672     ctemp.fill(c,1);
673     codifyLines(ctemp.data()); 
674     ctemp.resize(0);
675     g_temp.resize(0); 
676   }//while
677 }//codifymaplines
678
679 /*
680 * writes a function|procedure prototype and links the function|procedure name 
681 */
682
683 static void writeFuncProto()
684 {
685   QList<Argument> ql;
686   QCString name,ret;
687   VhdlDocGen::parseFuncProto(g_FuncProto,ql,name,ret,FALSE);
688
689   if (name.isEmpty())
690   {
691     codifyLines(g_FuncProto.data(),g_CurrClass.data());
692     return;
693   }
694   QCStringList qlist=QCStringList::split(name,g_FuncProto);
695   QCString temp=qlist[0];
696   codifyLines(temp.data(),g_CurrClass.data());
697   g_FuncProto.stripPrefix(temp.data());
698   temp.resize(0);
699   temp=g_CurrClass;
700   if (isPackageBody) 
701   {
702     temp.stripPrefix("_");// _{package body name}
703   }
704   MemberDef *mdef=VhdlDocGen::findFunction(ql,name,temp,FALSE);
705
706   if (mdef)
707   {
708     generateFuncLink(*g_code,mdef);
709     g_FuncProto.stripPrefix(name.data());
710     codifyLines(g_FuncProto.data(),g_CurrClass.data());
711   }
712   else
713   {
714     codifyLines(g_FuncProto.data(),g_CurrClass.data());
715   }
716 }// writeFuncProto
717
718 /* writes a process prototype to the output */
719
720  static void writeProcessProto(){
721  codifyLines(g_FuncProto.data(),g_CurrClass.data());
722  g_vhdlKeyDict.clear();
723 }// writeProcessProto
724
725 /* writes a keyword */
726
727 static bool writeColoredWord(QCString& word )
728 {
729   QCString qcs=word.lower();
730   QCString *ss=VhdlDocGen::findKeyWord(qcs);
731   if (ss) 
732   {
733     writeFont(ss->data(),word.data());
734     return TRUE;
735   }
736   return FALSE;
737 }
738
739 #undef        YY_INPUT
740 #define       YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
741
742 static int yyread(char *buf,int max_size)
743 {
744   int c=0;
745   while( c < max_size && g_inputString[g_inputPosition] )
746   {
747     *buf = g_inputString[g_inputPosition++] ;
748     c++; buf++;
749   }
750   return c;
751 }
752
753 %}
754
755
756 B             [ \t]
757 BN            [ \t\n\r]
758 STRING      ["][^"\n]*["]
759 NAME          [a-z_A-Z][ a-z_A-Z0-9]*
760 FUNCNAME      [a-z_A-Z"][a-z_A-Z0-9+*"/=<>-]*
761 ID            "$"?[a-z_A-Z][a-z_A-Z0-9]*
762 SPECSIGN      [:;, +*&\/=<>'\t]*
763 DIGITSS       [0-9]+|[0-9]+("#")*[0-9_a-fA-F\+\.\-]+("#")*
764 ALLTYPESMAP   {B}*[_a-zA-Z0-9. ]+{BN}*
765 ALLTYPESMAP1  {BN}*[_a-zA-Z0-9.() ]+{BN}*
766
767 ARCHITECTURE  ^{B}*("architecture"){BN}+{FUNCNAME}{BN}+("of"){BN}+{FUNCNAME}{BN}+("is")
768 PROCESS       ({BN}*{FUNCNAME}{BN}*[:]+{BN}*("process"){BN}*[(]*)|[^a-zA-Z]("process "|"process("){BN}*[ (]*|[^a-zA-Z]("process"){BN}+
769
770 END1          {B}*("end "){BN}+("if"|"case"|"loop"|"generate"|"for")
771 END2          [^a-zA-Z_]("end"){BN}*[;]
772 END3          {BN}*[^a-zA-Z]("end"){BN}+{FUNCNAME}{BN}*[;]
773 END4          {B}*("end"){BN}+"function"{BN}+{FUNCNAME}{BN}*[;]
774 ENDEFUNC      {END3}|{END4}|{END2}
775
776 KEYWORD       ("of"|"new"|"event"|"break"|"case"|"end"|"loop"|"else"|"for"|"goto"|"if"|"return"|"generate"|"is"|"while"|"in")
777 TYPEKW        ^{B}*("type"|"subtype"|"constant"|"attribute"|"signal"|"variable","alias","configuration")
778 FUNC          ^{B}*("function"|"procedure"){BN}*{FUNCNAME}{BN}*("(")
779
780 ARITHOP       "+"|"-"|"/"|"*"|"%"|"/="|":="
781 ASSIGNOP      "="|"*="|"/="|"%="|"+="|"-="|"<<="|">>="|"&="|"^="|"|="
782 LOGICOP       "=="|"!="|">"|"<"|">="|"<="|"&&"|"||"|"!"
783 BITOP         "&"|"|"|"^"|"<<"|">>"|"~"
784 OPERATOR      {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
785
786 PORT          {B}*("port"){BN}*("(")
787 GENERIC       {B}*("generic"){BN}*("(")
788
789 BRACEOPEN     [(]{1}
790 BRACECLOSE    [)]{1}
791
792 TEXTT         {B}*"--"[^\n]*
793
794 MAPCOMPONENT1 ({ALLTYPESMAP}[:]{ALLTYPESMAP}{TEXTT}*{BN}+("port"|"generic"){BN}+("map"){BN}*("("){1})
795 MAPCOMPONENT2 {BN}*("port"|"generic"){BN}+("map"){BN}*("("){1}
796 MAPCOMPONENT3 ({ALLTYPESMAP}[:]{BN}*{ALLTYPESMAP1}{TEXTT}*{BN}+("port"|"generic"){BN}+("map"){BN}*("("){1})
797 MAPCOMPONENT4 ({ALLTYPESMAP}[:]{BN}*("entity"|"component"|"configuration"){BN}+{ALLTYPESMAP1}{TEXTT}*{BN}*("port"|"generic"){BN}*("map"){BN}*("("){1})
798
799 XILINX      "INST"|"NET"|"PIN"|"BLKNM"|"BUFG"|"COLLAPSE"|"CPLD"|"COMPGRP"|"CONFIG"|"CONFIG_MODE"|"COOL_CLK"|"DATA_GATE"|"DCI_VALUE"|"DISABLE"|"DRIVE"|"DROP_SPEC"|"ENABLE"|"FAST"|"FEEDBACK"|"FILE"|"FLOAT"|"FROM-THRU-TO"|"FROM-TO"|"HBLKNM"|"HU_SET"|"INREG"|"IOB"|"IOBDELAY"|"IOSTANDARD"|"KEEP"|"KEEPER"|"LOC"|"LOCATE"|"LOCK_PINS"|"MAP"|"MAXDELAY"|"MAXPT"|"MAXSKEW"|"NODELAY"|"NOREDUCE"|"OFFSET"|"OPEN_DRAIN"|"OPT_EFFORT"|"OPTIMIZE"|"PERIOD"|"PIN"|"PRIORITY"|"PROHIBIT"|"PULLDOWN"|"PULLUP"|"PWR_MODE"|"REG"|"RLOC"|"RLOC_ORIGIN"|"RLOC_RANGE"|"SAVE NET"|"FLAG"|"SYSTEM_JITTER"|"TEMPERATURE"|"TIMEGRP"|"TIMESPEC"|"VOLTAGE"
800
801 %option noyywrap
802 %option nounput
803
804 %x Bases
805 %x ParseType
806 %x ParseFuncProto
807 %x ParseComponent
808 %x ParsePackage
809 %x ParseProcessProto
810 %x ClassName
811 %x PackageName
812 %x ClassVar
813 %x ClassesName
814 %x Map
815 %x End
816 %x Body
817         
818 %%
819
820 .                     { 
821                         BEGIN(Bases); 
822                       }
823
824 <Map>{BRACEOPEN}      {
825                         g_braceCount++;
826                         writeFont("vhdlchar",vhdlcodeYYtext);
827                         BEGIN(Map);
828                       }
829
830 <Map>[^()\n,--]*        { /* write and link a port map lines */
831                         QCString tt(vhdlcodeYYtext);
832                         VhdlDocGen::deleteAllChars(tt,',');
833                         QRegExp r("=>");
834                         QCStringList ql=QCStringList::split(r,tt);
835                         if (ql.count()>=2)
836                         {
837                           unsigned int index=0;
838                           QCString t1=ql[0];
839                           char cc=t1.at(index);
840                           while (cc==' ' || cc=='\t') 
841                           {
842                             char c2[2];
843                             c2[0]=cc;
844                             c2[1]=0;
845                             g_code->codify(c2);
846                             index++;
847                             if (index>=t1.size()) break;
848                             cc=t1.at(index);
849                           }        
850
851                           QCString s1=t1;
852                           s1=s1.stripWhiteSpace();
853
854                           //         if (!g_PortMapComp.isEmpty())
855                           generateMemLink(*g_code,g_PortMapComp,s1); 
856                           while (index++<t1.size()) 
857                           { 
858                             char cc=t1.at(index);
859                             if (cc==' ' || cc=='\t')
860                             {
861                               char c2[2];
862                               c2[0]=cc;
863                               c2[1]=0;
864                               g_code->codify(c2);
865                             }
866                           }        
867                           codifyLines("=>");
868                           index=0;
869                           QCString s2=ql[1];
870                           t1=s2;
871                           cc=t1.at(index);
872                           while (cc==' ' || cc=='\t') 
873                           {
874                             char c2[2];
875                             c2[0]=cc;
876                             c2[1]=0;
877                             g_code->codify(c2);
878                             index++;
879                             if (index>=t1.size()) break;
880                             cc=t1.at(index);
881                           }        
882                           s2=s2.stripWhiteSpace();
883                             if (!checkVhdlString(s2))
884                           generateMemLink(*g_code,g_CurrClass,s2); 
885                           while (index++<t1.size()) 
886                           { 
887                             if (t1.at(index)==' ')
888                             {
889                               g_code->codify(" "); 
890                             }
891                           }        
892                         }
893                         else
894                         {
895                           codifyLines(vhdlcodeYYtext,g_CurrClass.data());
896                         }
897                         BEGIN(Map);
898                       }
899
900 <Map>"\n"|","         {
901                         codifyLines(vhdlcodeYYtext);
902                         BEGIN(Map);
903                       }
904
905 <Map>{BRACECLOSE}     {
906                         g_braceCount--;
907                         writeFont("vhdlchar",vhdlcodeYYtext);
908                         if (g_braceCount==0)
909                         {
910                           BEGIN(Bases);
911                         }
912                       }
913
914 <ParseFuncProto>{NAME} {
915                          QCString tmp(vhdlcodeYYtext);
916                          tmp=tmp.stripWhiteSpace();
917                          appStringLower(g_PrevString,vhdlcodeYYtext);
918                          g_vhdlKeyDict.insert(g_PrevString,new QCString(g_PrevString.data()));
919                          if (!writeColoredWord(tmp))
920                          {
921                            generateMemLink(*g_code,g_CurrClass,tmp); 
922                          }
923                          BEGIN(Bases);
924                        }
925
926 <ParseType>{STRING} {
927                        QCString qcs(vhdlcodeYYtext);
928                        VhdlDocGen::deleteAllChars(qcs,'"');
929                        VhdlDocGen::deleteAllChars(qcs,' ');
930                         if (VhdlDocGen::isNumber(qcs))
931                        writeFont("vhdllogic",vhdlcodeYYtext);
932                        else
933                        writeFont("keyword",vhdlcodeYYtext);
934                 }
935
936 <ParseType>"\n"       {
937                         g_FuncProto.append(vhdlcodeYYtext);
938                         if (isProto)
939                         {
940                           codifyLines(vhdlcodeYYtext);
941                         }
942                         BEGIN(ParseType);
943                       }
944
945
946 <ParseType>{TEXTT}    {
947                         g_FuncProto.append(vhdlcodeYYtext);                
948                         if (isProto)                                                                 
949                         {
950                           writeFont("keyword",vhdlcodeYYtext);
951                         }
952                         BEGIN(ParseType); 
953                        }
954
955 <ParseType>{ENDEFUNC} {
956                         QRegExp regg("[\\s]");
957                         QCString tt(vhdlcodeYYtext);
958                         codifyLines(vhdlcodeYYtext,g_CurrClass.data());
959                         tt=tt.lower();
960                         VhdlDocGen::deleteAllChars(tt,';');
961                         tt.stripWhiteSpace();
962                         QCStringList ql=QCStringList::split(regg,tt);
963                         int index=ql.findIndex(QCString("if"))+1;
964                         index+=ql.findIndex(QCString("case"))+1;
965                         index+=ql.findIndex(QCString("loop"))+1;
966                         index+=ql.findIndex(QCString("generate"))+1;                        
967                         if (index==0)
968                         {
969                           BEGIN(Bases);
970                         }
971                         else
972                         {
973                           BEGIN(ParseType);
974                         }
975                       }
976
977 <ParseType>{END1}     {
978                         codifyLines(vhdlcodeYYtext,g_CurrClass.data());
979                         g_vhdlKeyDict.clear();
980                       }
981
982 <ParseType>^{B}*("begin "|"begin") {
983                         codifyLines(vhdlcodeYYtext,g_CurrClass.data());
984                         isFuncProto=FALSE;
985                       }
986
987 <ParseType>{SPECSIGN} {
988                         g_FuncProto.append(vhdlcodeYYtext);
989                         if (isProto)
990                         {
991                           codifyLines(vhdlcodeYYtext,g_CurrClass.data());
992                         }
993                       }
994
995 <ParseType>["_a-zA-Z0-9]* {
996                         QCString val(vhdlcodeYYtext);
997                         g_FuncProto.append(vhdlcodeYYtext);
998                         appStringLower(g_PrevString,vhdlcodeYYtext);
999                                                         
1000                         if (isFuncProto && g_braceCount==0)
1001                         {
1002                           g_vhdlKeyDict.insert(g_PrevString,new QCString(g_PrevString.data()));
1003                         }
1004                                 
1005                         if (isProto) 
1006                         { 
1007                           if (!writeColoredWord(val))
1008                           {
1009                             if (!isFuncProto && !g_vhdlKeyDict.find(g_PrevString))
1010                             {
1011                               val=val.stripWhiteSpace();
1012                               if (VhdlDocGen::isNumber(val))
1013                               {
1014                                 startFontClass("vhdllogic");
1015                                 codifyLines(vhdlcodeYYtext,g_CurrClass.data());
1016                                 endFontClass();
1017                               }
1018                              else
1019                               generateMemLink(*g_code,g_CurrClass,val); 
1020                             }
1021                             else
1022                             {
1023                               codifyLines(vhdlcodeYYtext,g_CurrClass.data());
1024                             }
1025                           }
1026                         }
1027                         BEGIN(ParseType); 
1028                       }
1029
1030 <ParseType>{BRACEOPEN} {
1031                         g_braceCount++;
1032                         g_FuncProto+='(';
1033                         if (isProto)
1034                         {
1035                           writeFont("vhdlchar",vhdlcodeYYtext);
1036                         }
1037                         BEGIN(ParseType);
1038                       }
1039
1040 <ParseType>{BRACECLOSE} {
1041                         g_braceCount--;
1042                         g_FuncProto+=')';
1043                         if (isProto)
1044                         {
1045                           writeFont("vhdlchar",vhdlcodeYYtext);
1046                         }
1047                         if (g_braceCount==0 && !isProto)// && !isPackageBody)
1048                         {
1049                           isProto=TRUE;
1050                           appStringLower(g_PrevString,vhdlcodeYYtext);
1051                           writeFuncProto();
1052                           BEGIN(Bases);
1053                         }
1054                         if (isPackageBody)
1055                         {
1056                           BEGIN(ParseType);
1057                         }
1058                       }
1059
1060
1061 <ClassesName>{FUNCNAME} {
1062                          appStringLower(g_PrevString,vhdlcodeYYtext);
1063                          g_CurrClass.resize(0);
1064                          g_CurrClass.append(vhdlcodeYYtext);
1065                          g_CurrClass=g_CurrClass.stripWhiteSpace();
1066                                                   
1067                          generateClassOrGlobalLink(*g_code,vhdlcodeYYtext);
1068                          BEGIN(Bases);
1069                        }
1070
1071
1072 <ParseComponent>{BRACEOPEN} {
1073                          g_braceCount++;
1074                          g_code->codify(vhdlcodeYYtext);
1075                        }
1076
1077
1078 <ParseComponent>{BRACECLOSE} {
1079                          g_braceCount--;
1080                          g_code->codify(vhdlcodeYYtext);  
1081                          if (g_braceCount==0 && !isComponent)
1082                          {
1083                            g_tempComp.resize(0);
1084                            BEGIN(Bases);
1085                          }
1086                          else
1087                          {
1088                            BEGIN(ParseComponent);
1089                          }
1090                        }
1091
1092 <ParseComponent>{B}*"-" {    
1093                          if (strlen(vhdlcodeYYtext)>=2) // found text ?
1094                          {
1095                            writeFont("keyword",vhdlcodeYYtext);
1096                          }
1097                          else
1098                          {
1099                            writeFont("vhdlchar",vhdlcodeYYtext); 
1100                          }
1101                        }
1102
1103 <ParseComponent>{SPECSIGN} {
1104                          codifyLines(vhdlcodeYYtext);
1105                        }
1106
1107
1108
1109 <ParseComponent>"\n"|" " {
1110                            codifyLines(vhdlcodeYYtext);
1111                          }
1112
1113 <ParseComponent>{DIGITSS} { 
1114                          startFontClass("vhdllogic");
1115                          codifyLines(vhdlcodeYYtext);
1116                          endFontClass();
1117                        }
1118
1119 <ParseComponent>{PORT} { 
1120                          codifyLines(vhdlcodeYYtext);
1121                          g_braceCount=1;
1122                          isComponent=FALSE;
1123                        }
1124
1125 <ParseComponent>{GENERIC} { 
1126                          codifyLines(vhdlcodeYYtext);
1127                          g_braceCount=1;
1128                        }
1129
1130 <ParseComponent>[_a-zA_Z][_a-zA-Z0-9]*  {
1131                          QCString temp(vhdlcodeYYtext);
1132                          appStringLower(g_PrevString,vhdlcodeYYtext);
1133                          if (!checkVhdlString(temp)){
1134                          if (!writeColoredWord(g_PrevString))
1135                          {
1136                            generateMemLink(*g_code,g_tempComp,temp); 
1137                          }
1138                        }
1139                        }
1140
1141 <ParseComponent>{STRING} { 
1142                             QCString temp(vhdlcodeYYtext);
1143                         if (!checkVhdlString(temp))
1144                          codifyLines(vhdlcodeYYtext);
1145                         }
1146
1147
1148 <ParseProcessProto>[^()]* { 
1149                          g_FuncProto.append(vhdlcodeYYtext);
1150                        }
1151
1152
1153
1154 <ParseProcessProto>{BRACEOPEN} {
1155                          g_FuncProto.append(vhdlcodeYYtext);
1156                          g_braceCount++;
1157                        }
1158
1159 <ParseProcessProto>{BRACECLOSE} {
1160                          g_FuncProto.append(vhdlcodeYYtext);
1161                          g_braceCount--;
1162                          if (g_braceCount==0) 
1163                          {
1164                             writeProcessProto();
1165                             BEGIN(Bases);
1166                           }
1167                         }
1168
1169 <ParsePackage>[^:;]*    { //found package 
1170                           QCString temp(vhdlcodeYYtext);
1171                           QCStringList strl=QCStringList::split(".",temp);
1172                           if (strl.count()>2) 
1173                           {
1174                              QCString s1=strl[0];  
1175                              QCString s2=strl[1];  
1176                              QCString s3=strl[2];  
1177                              s1.append(".");
1178                              s3.prepend(".");
1179                              codifyLines(s1.data(),g_CurrClass.data());  
1180                              ClassDef *cd=VhdlDocGen::getPackageName(s2);
1181                              if (cd)
1182                              {
1183                                generateClassOrGlobalLink(*g_code,s2.data());
1184                              }
1185                              else 
1186                              {
1187                                codifyLines(s2.data());
1188                              }
1189                              codifyLines(s3.data());
1190                            }
1191                            else
1192                            {
1193                              writeFont("keywordflow",vhdlcodeYYtext);
1194                            }
1195                            BEGIN(Bases);
1196                          }
1197
1198 <Bases>{MAPCOMPONENT1}|{MAPCOMPONENT2}|{MAPCOMPONENT3}|{MAPCOMPONENT4}  { // found port or generic map
1199                            QCString tt(vhdlcodeYYtext);
1200              /*
1201                            if (tt.contains(':',FALSE))
1202                            {
1203                              isStartMap=TRUE;
1204                            }
1205                            else
1206                            {
1207                              isStartMap=FALSE;                                        
1208                            }
1209                            */
1210                            int j=tt.find('.');
1211                                                     
1212                            if (j>0)
1213                            {
1214                              QCString left=tt.left(j+1); 
1215                              codifyLines(left.data());
1216                              tt=tt.right(tt.length()-j-1);
1217                              left=VhdlDocGen::getIndexWord(tt.data(),0);
1218                              if (!left.isEmpty())
1219                              {          
1220                                if (left.contains('('))
1221                                {
1222                                  j=left.find('(',FALSE);
1223                                  QCString name=left.left(j);
1224                                  generateClassOrGlobalLink(*g_code,name.data()); 
1225                                  g_PortMapComp=name;
1226                                  name=tt.right(tt.length()-name.length());
1227                                  codifyLines(name.data());
1228                                }
1229                                else
1230                                {
1231                                  generateClassOrGlobalLink(*g_code,left.data()); 
1232                                  tt.stripPrefix(left.data()); //=tt.right(tt.length()-left.length()-1);
1233                                  
1234                                  g_PortMapComp=left;
1235                                  codifyLines(tt.data());
1236                                }
1237                              }
1238                            }
1239                            else
1240                            {
1241                            if (tt.contains(':',FALSE)) 
1242                              codifyMapLines(tt.data());
1243                               else
1244                              codifyLines(tt.data()); 
1245                            }
1246                            g_braceCount=1;
1247                            BEGIN(Map);
1248                          }
1249
1250 <Bases>^{B}*("component"){BN}+{FUNCNAME}  { // found component
1251                            appStringLower(g_PrevString,vhdlcodeYYtext);
1252                            //  writeFont("keywordflow",VhdlDocGen::getIndexWord(vhdlcodeYYtext,0).data());
1253                            //  writeFont("vhdlkeyword"," ");
1254                            QCString temp=VhdlDocGen::getIndexWord(vhdlcodeYYtext,1);
1255                            temp=temp.stripWhiteSpace();
1256                            VhdlDocGen::deleteAllChars(temp,'\n');
1257                            g_tempComp=temp;
1258                            codifyLines(vhdlcodeYYtext,temp.data(),TRUE);
1259                            g_braceCount=0;
1260                          
1261                            //if (getClass(temp.data()))
1262                            //  generateClassOrGlobalLink(*g_code,temp.data());
1263                            //else
1264                            //  generateMemLink(*g_code,g_CurrClass,temp);
1265                          
1266                            isComponent=TRUE;
1267                            BEGIN(ParseComponent);
1268                          }
1269                                                 
1270
1271
1272 <Bases>{ARCHITECTURE}    { // found architecture
1273                            g_PortMapComp.resize(0);
1274                            //        writeFont("vhdlkeyword",VhdlDocGen::getIndexWord(vhdlcodeYYtext,0).data());
1275                            //        writeFont("vhdlkeyword"," ");
1276                            //        writeFont("vhdlchar",VhdlDocGen::getIndexWord(vhdlcodeYYtext,1).data());
1277                            //        writeFont("vhdlkeyword"," ");
1278                            //        writeFont("vhdlkeyword",VhdlDocGen::getIndexWord(vhdlcodeYYtext,2).data());
1279                            //        writeFont("vhdlkeyword"," ");
1280                            //QCString temp=VhdlDocGen::getIndexWord(vhdlcodeYYtext,1);
1281                            //temp=temp.stripWhiteSpace();
1282                            //temp+=("-");
1283                            //temp+=VhdlDocGen::getIndexWord(vhdlcodeYYtext,3);
1284                            QCString temp = VhdlDocGen::getIndexWord(vhdlcodeYYtext,3);
1285                            g_CurrARCH = TRUE;
1286                            temp+="::";
1287                            temp+=VhdlDocGen::getIndexWord(vhdlcodeYYtext,1);
1288                            g_CurrClass=temp;
1289                            VhdlDocGen::deleteAllChars(temp,'\n');
1290                            codifyLines(vhdlcodeYYtext,temp.data(),TRUE);
1291                            //generateClassOrGlobalLink(*g_code,temp.data());
1292                            isPackageBody=FALSE;
1293                          }
1294
1295
1296 <Bases>^{B}*("package "){BN}*("body"){BN}*{FUNCNAME}  { // found package body  
1297                            QCString ss(vhdlcodeYYtext);
1298                            QCString temp=VhdlDocGen::getIndexWord(vhdlcodeYYtext,2);
1299                            QCStringList ql=QCStringList::split(temp,ss);
1300                            QCString ll=ql[0];
1301                            codifyLines(ll.data(),g_CurrClass.data());
1302                            temp=temp.stripWhiteSpace();
1303                                      temp.prepend("_");
1304                            generateClassOrGlobalLink(*g_code,temp.data());
1305                            g_CurrClass.resize(0);
1306                            g_CurrClass=temp;
1307                            isProto=FALSE;
1308                            isPackageBody=TRUE;
1309                            // BEGIN(ClassesName);
1310                          }
1311
1312 <Bases>{PROCESS}         { // found process
1313                            isFuncProto=TRUE;
1314                            g_FuncProto.resize(0);
1315                            g_FuncProto.append(vhdlcodeYYtext);
1316                            g_vhdlKeyDict.clear();
1317                            appStringLower(g_PrevString,vhdlcodeYYtext);
1318                            if (g_PrevString.contains('(')) 
1319                            {
1320                              g_braceCount=1;
1321                              BEGIN(ParseProcessProto);
1322                            }
1323                            else
1324                            {
1325                              writeProcessProto();
1326                            }
1327                          }
1328
1329 <Bases>("end"){BN}+("process") { // end of process
1330                            isFuncProto=FALSE;
1331                            codifyLines(vhdlcodeYYtext);
1332                            BEGIN(Bases);
1333                          }
1334
1335
1336 <Bases>^{B}*("begin "|"begin") { 
1337                            isFuncProto=FALSE;
1338                            writeFont("vhdlkeyword",vhdlcodeYYtext);
1339                          }
1340
1341 <Bases>^{B}*("use"|"library"){BN}+ { //found package or library
1342                            writeFont("vhdlkeyword",vhdlcodeYYtext);
1343                            BEGIN(ParsePackage);
1344                          }
1345
1346
1347 <Bases>^{B}*("use"){BN}+("configuration")[^\n]* { 
1348                            codifyLines(vhdlcodeYYtext);
1349                          }
1350
1351
1352
1353 <Bases>{FUNC}            {  // found function|procedure
1354                            g_vhdlKeyDict.clear();
1355                            g_FuncProto.resize(0);
1356                            isProto=FALSE;
1357                            g_FuncProto.append(vhdlcodeYYtext);
1358                            g_braceCount=1;
1359                            BEGIN(ParseType);
1360                          }
1361                                         
1362
1363
1364 <Bases>^{B}*("entity"|"package"){BN}+ { 
1365                            appStringLower(g_PrevString,vhdlcodeYYtext);
1366                            writeFont("keywordflow",vhdlcodeYYtext);
1367                            isPackageBody=FALSE;
1368                            BEGIN(ClassesName);
1369                          }
1370                                         
1371
1372 <Bases>"end"{BN}+"architecture"{BN}+{FUNCNAME} {
1373                            codifyLines(vhdlcodeYYtext,g_CurrClass.data(),TRUE);
1374                            g_CurrARCH = FALSE;
1375                          }
1376 <Bases>"end"{BN}+{FUNCNAME} {
1377                            if (g_CurrARCH)
1378                            {
1379                              codifyLines(vhdlcodeYYtext,g_CurrClass.data(),TRUE);
1380                              g_CurrARCH = FALSE;
1381                            }
1382                            else
1383                               REJECT;
1384                          }
1385 <Bases>"end"             {
1386                            appStringLower(g_PrevString,vhdlcodeYYtext);
1387                            QCString temp(vhdlcodeYYtext);
1388                            temp=temp.stripWhiteSpace();
1389
1390                            writeColoredWord(temp);
1391                            BEGIN(End);
1392                          }
1393 <End>{ID}                {
1394                            appStringLower(g_PrevString,vhdlcodeYYtext);
1395                            QCString temp(vhdlcodeYYtext);
1396                            temp=temp.stripWhiteSpace();
1397
1398                            if (!writeColoredWord(temp))
1399                            {
1400                              generateClassOrGlobalLink(*g_code,temp.data());
1401                            }
1402                          }
1403 <End>";"                 {
1404                            codifyLines(vhdlcodeYYtext);
1405                            BEGIN(Bases);
1406                          }
1407 <Bases>{KEYWORD}         { // found keyword
1408                            QCString qcs(vhdlcodeYYtext);
1409                            if (!writeColoredWord(qcs))
1410                            {
1411                              startFontClass("vhdlchar");
1412                              g_code->codify(vhdlcodeYYtext);
1413                              endFontClass();
1414                            }
1415                          }
1416
1417
1418 <Bases>{ID}              {
1419                            appStringLower(g_PrevString,vhdlcodeYYtext);
1420                            QCString temp(vhdlcodeYYtext);
1421                            temp=temp.stripWhiteSpace();
1422                         
1423                            if (!writeColoredWord(temp))
1424                            {
1425                              startFontClass("vhdlchar");
1426                              generateMemLink(*g_code,g_CurrClass,temp);
1427                              endFontClass();
1428                            }
1429                          }
1430
1431 <Bases,ParseComponent>{DIGITSS} { 
1432                            startFontClass("vhdllogic");
1433                            codifyLines(vhdlcodeYYtext);
1434                            endFontClass();
1435                          }
1436
1437 <Bases>^{B}*("use"){BN}+("entity"|"component")[^\n]* { 
1438                             codifyLines(vhdlcodeYYtext,g_CurrClass.data(),TRUE);
1439                          }
1440
1441
1442 <Bases>{TYPEKW}          { 
1443                            codifyLines(vhdlcodeYYtext);
1444                            if (isFuncProto)
1445                            {
1446                              BEGIN(ParseFuncProto);
1447                            }
1448                            else 
1449                            {
1450                              BEGIN(Bases);
1451                            }
1452                          }
1453
1454 <Bases>{OPERATOR}        {                            
1455                            startFontClass("vhdlchar");
1456                            g_code->codify(vhdlcodeYYtext);
1457                            endFontClass();
1458                          }
1459    
1460 <Bases>","|"."|":"|"'"|"("|")" { 
1461                            startFontClass("vhdlchar");
1462                            g_code->codify(vhdlcodeYYtext);
1463                            endFontClass();
1464                          }
1465                                           
1466 <Bases>{STRING} {
1467                        QCString qcs(vhdlcodeYYtext);
1468                        VhdlDocGen::deleteAllChars(qcs,'"');
1469                        VhdlDocGen::deleteAllChars(qcs,' ');
1470                     
1471                        if (VhdlDocGen::isNumber(qcs))
1472                        writeFont("vhdllogic",vhdlcodeYYtext);
1473                        else
1474                        writeFont("keyword",vhdlcodeYYtext);
1475                 }
1476
1477 <Bases>{B}*"#"[^\n]*  { 
1478                                       writeFont("keyword",vhdlcodeYYtext);
1479                                     }
1480                                      
1481 <Bases>^{B}*{XILINX}/[^a-zA-Z0-9_] {
1482                                       writeWord(yytext);
1483                                       //codifyLines(vhdlcodeYYtext,g_CurrClass.data(),TRUE);
1484                                    }
1485
1486 <Bases>^{B}*"set_"[^\n]*  { 
1487                                       writeWord(yytext);
1488                                     }
1489                                     
1490 <*>\n                    {
1491                            codifyLines(vhdlcodeYYtext);
1492                            BEGIN(Bases);
1493                          }
1494
1495 <*>.                     {
1496                            g_code->codify(vhdlcodeYYtext);
1497                          }
1498
1499 <*>\n{TEXTT}             { // found normal or special comment on its own line
1500                            QCString text(vhdlcodeYYtext);
1501                            int i=text.find("--");
1502                            if (text.mid(i,3)=="--!") // && // hide special comment
1503                            {
1504                              if (!Config_getBool(STRIP_CODE_COMMENTS))
1505                              {
1506                                codifyLines(text,0,FALSE,TRUE);
1507                              }
1508                              else g_yyLineNr++; // skip complete line, but count line
1509                            }
1510                            else // normal comment
1511                            {
1512                              codifyLines(text,0,FALSE,TRUE);
1513                            }
1514                          }
1515 <*>{TEXTT}               { // found normal or special comment after something
1516                            QCString text(vhdlcodeYYtext);
1517                            int i=text.find("--");
1518                            if (text.mid(i,3)=="--!")
1519                            {
1520                              // hide special comment
1521                              if (!Config_getBool(STRIP_CODE_COMMENTS))
1522                              {
1523                                codifyLines(text,0,FALSE,TRUE);
1524                              }
1525                            }
1526                            else // normal comment
1527                            {
1528                              codifyLines(text,0,FALSE,TRUE);
1529                            }
1530                          }
1531
1532 %%
1533
1534 /*@ ----------------------------------------------------------------------------
1535  */
1536
1537 void resetVhdlCodeParserState()
1538 {
1539   g_vhdlKeyDict.setAutoDelete(TRUE);
1540   g_vhdlKeyDict.clear();
1541 }
1542
1543 void parseVhdlCode(CodeOutputInterface &od,const char *className,const QCString &s, 
1544                   bool exBlock, const char *exName,FileDef *fd,
1545                   int startLine,int endLine,bool inlineFragment,
1546                   MemberDef *memberDef,bool,Definition *searchCtx,
1547                   bool /* collectXRefs */)
1548 {
1549   //printf("***parseCode() exBlock=%d exName=%s fd=%p\n",exBlock,exName,fd);
1550   if (s.isEmpty()) return;
1551   printlex(yy_flex_debug, TRUE, __FILE__, fd ? fd->fileName().data(): NULL);
1552   TooltipManager::instance()->clearTooltips();
1553   if (memberDef)
1554   {
1555     ClassDef *dd=memberDef->getClassDef();
1556     if (dd) g_CurrClass=dd->name();
1557     startLine--;
1558   }
1559   resetVhdlCodeParserState();
1560   g_code = &od;
1561   g_inputString   = s;
1562   g_inputPosition = 0;
1563   g_currentFontClass = 0;
1564   g_needsTermination = FALSE;
1565   g_searchCtx = searchCtx;
1566
1567   if (startLine!=-1)
1568     g_yyLineNr    = startLine;
1569   else
1570     g_yyLineNr    = 1;
1571
1572   if (endLine!=-1)
1573     g_inputLines  = endLine+1;
1574   else
1575     g_inputLines  = g_yyLineNr + countLines() - 1;
1576
1577
1578   // g_theCallContext.clear();
1579   g_classScope    = className;
1580   g_exampleBlock  = exBlock; 
1581   g_exampleName   = exName;
1582   g_sourceFileDef = fd;
1583   bool cleanupSourceDef = FALSE;
1584   if (exBlock && fd==0)
1585   {
1586     // create a dummy filedef for the example
1587     g_sourceFileDef = new FileDef("",exName);
1588     cleanupSourceDef = TRUE;
1589   }
1590   if (g_sourceFileDef) 
1591   {
1592     setCurrentDoc("l00001");
1593   }
1594   g_currentDefinition = 0;
1595   g_currentMemberDef = 0;
1596   g_vhdlMember=0;
1597   if (!g_exampleName.isEmpty())
1598   {
1599     g_exampleFile = convertNameToFile(g_exampleName+"-example");
1600   }
1601   g_includeCodeFragment = inlineFragment;
1602   if (!memberDef)
1603   {
1604     startCodeLine();
1605   }
1606   // g_type.resize(0);
1607   // g_name.resize(0);
1608   // g_args.resize(0);
1609   g_parmName.resize(0);
1610   g_parmType.resize(0);
1611   if(!g_lexInit)
1612     VhdlDocGen::init();
1613   if (memberDef) 
1614   {
1615     setParameterList(memberDef);
1616   }
1617   /*int iLine=*/countLines();
1618   vhdlcodeYYrestart( vhdlcodeYYin );
1619   BEGIN( Bases );
1620   vhdlcodeYYlex();
1621   g_lexInit=TRUE;
1622   if (g_needsTermination)
1623   {
1624     endCodeLine();
1625   }
1626   if (fd)
1627   {
1628     TooltipManager::instance()->writeTooltips(*g_code);
1629   }
1630   if (cleanupSourceDef)
1631   {
1632     // delete the temporary file definition used for this example
1633     delete g_sourceFileDef;
1634     g_sourceFileDef=0;
1635   }
1636   g_startCode=FALSE;
1637   printlex(yy_flex_debug, FALSE, __FILE__, fd ? fd->fileName().data(): NULL);
1638 }
1639
1640 void codeFreeVhdlScanner()
1641 {
1642 #if defined(YY_FLEX_SUBMINOR_VERSION) 
1643   if (g_lexInit)
1644   {
1645     vhdlcodeYYlex_destroy();
1646   }
1647 #endif
1648 }
1649
1650 #if !defined(YY_FLEX_SUBMINOR_VERSION) 
1651 extern "C" { // some bogus code to keep the compiler happy
1652   void vhdlcodeYYdummy() { yy_flex_realloc(0,0); } 
1653 }
1654 #elif YY_FLEX_MAJOR_VERSION<=2 && YY_FLEX_MINOR_VERSION<=5 && YY_FLEX_SUBMINOR_VERSION<33
1655 #error "You seem to be using a version of flex newer than 2.5.4 but older than 2.5.33. These versions do NOT work with doxygen! Please use version <=2.5.4 or >=2.5.33 or expect things to be parsed wrongly!"
1656 #endif
1657
1658
1659
1660