1 /******************************************************************************
3 * Copyright (C) 1997-2012 by Dimitri van Heesch.
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.
11 * Documents produced by Doxygen are derivative works derived from the
12 * input used in their production; they are not affected by this license.
15 /******************************************************************************
16 * Parser for syntax hightlighting and references for vhdl subset
19 * does not support VHDL-AMS
20 ******************************************************************************/
32 #include <qstringlist.h>
38 #include "outputlist.h"
40 #include "membername.h"
41 #include "searchindex.h"
42 #include "vhdldocgen.h"
43 #include "arguments.h"
45 #define YY_NEVER_INTERACTIVE 1
48 // Toggle for some debugging info
49 //#define DBG_CTX(x) fprintf x
50 #define DBG_CTX(x) do { } while(0)
53 /* -----------------------------------------------------------------
57 // ----------------- <vhdl> ----------------------------------
59 //static bool isPackBody=FALSE;
60 //static bool isStartMap;
61 static bool isFuncProto=FALSE;
62 static bool isComponent=FALSE;
63 static bool isPackageBody=FALSE;
64 static bool isProto = FALSE;
66 static QCString g_PrevString;
67 static QCString g_CurrClass;
68 static QDict<QCString>g_vhdlKeyDict;
69 static QCString g_tempClass;
70 static QCString g_tempComp;
71 static QCString g_PortMapComp;
72 static MemberDef *g_vhdlMember;
73 static QCString g_FuncProto;
75 //-----------------------------------------------------------
77 static CodeOutputInterface * g_code;
78 static QCString g_curClassName;
79 static QCString g_parmType;
80 static QCString g_parmName;
81 static const char * g_inputString; //!< the code fragment as text
82 static int g_inputPosition; //!< read offset during parsing
83 static int g_inputLines; //!< number of line in the code fragment
84 static int g_yyLineNr; //!< current line number
85 static bool g_needsTermination;
86 static Definition *g_searchCtx;
88 static QCString g_exampleName;
89 static QCString g_exampleFile;
91 static QCString g_type;
92 static QCString g_name;
93 static QCString g_args;
94 static QCString g_classScope;
96 static QCString g_CurrScope;
98 static FileDef * g_sourceFileDef;
99 static Definition * g_currentDefinition;
100 static MemberDef * g_currentMemberDef;
101 static bool g_includeCodeFragment;
102 static const char * g_currentFontClass;
104 static bool g_lexInit = FALSE;
105 static int g_braceCount=0;
108 static void writeFont(const char *s,const char* text);
109 static void generateMemLink(CodeOutputInterface &ol,QCString &clName,QCString& memberName);
110 static bool writeColoredWord(QCString& word );
111 static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName, bool typeOnly=FALSE);
112 static void endFontClass();
113 static void startFontClass(const char *s);
114 //-------------------------------------------------------------------
117 static void setCurrentDoc(const QCString &anchor)
119 if (Doxygen::searchIndex)
123 Doxygen::searchIndex->setCurrentDoc(g_searchCtx,g_searchCtx->anchor(),FALSE);
127 Doxygen::searchIndex->setCurrentDoc(g_sourceFileDef,anchor,TRUE);
132 static bool checkVhdlString(QCString &name)
134 if (name.isEmpty()) return FALSE;
135 static QRegExp regg("[\\s\"]");
137 int len=name.length();
138 if (name.at(0)=='"' && name.at(len-1)=='"' && len > 2)
140 QStringList qrl=QStringList::split(regg,name,FALSE);
141 if (VhdlDocGen::isNumber(qrl[0].utf8()))
143 g_code->codify("\"");
144 startFontClass("vhdllogic");
145 QCString mid=name.mid(1,len-2); //" 1223 "
146 g_code->codify(mid.data());
148 g_code->codify("\"");
152 startFontClass("keyword");
153 g_code->codify(name.data());
159 if (VhdlDocGen::isNumber(name))
161 startFontClass("vhdllogic");
162 g_code->codify(name.data());
169 static void addToSearchIndex(const char *text)
171 if (Doxygen::searchIndex)
173 Doxygen::searchIndex->addWord(text,FALSE);
178 /*! start a new line of code, inserting a line number if g_sourceFileDef
179 * is TRUE. If a definition starts at the current line, then the line
180 * number is linked to the documentation of that definition.
182 static void startCodeLine()
184 //if (g_currentFontClass) { g_code->endFontClass(); }
187 //QCString lineNumber,lineAnchor;
188 //lineNumber.sprintf("%05d",g_yyLineNr);
189 //lineAnchor.sprintf("l%05d",g_yyLineNr);
190 // if ((g_yyLineNr % 500) == 0)
191 // fprintf(stderr,"\n starting Line %d:",g_yyLineNr);
192 Definition *d = g_sourceFileDef->getSourceDefinition(g_yyLineNr);
193 //printf("startCodeLine %d d=%s\n", g_yyLineNr,d ? d->name().data() : "<null>");
194 if (!g_includeCodeFragment && d)
196 g_currentDefinition = d;
197 g_currentMemberDef = g_sourceFileDef->getSourceMember(g_yyLineNr);
198 if (!g_tempComp.isEmpty() && g_currentMemberDef )
200 //ClassDef *cf=VhdlDocGen::getClass(g_tempComp.data());
201 QCString nn=g_currentMemberDef->name();
202 MemberDef* mdeff=VhdlDocGen::findMember(g_tempComp,nn);
205 g_currentMemberDef=mdeff;
209 g_parmType.resize(0);
210 g_parmName.resize(0);
212 lineAnchor.sprintf("l%05d",g_yyLineNr);
213 if (g_currentMemberDef)
215 g_code->writeLineNumber(g_currentMemberDef->getReference(),
216 g_currentMemberDef->getOutputFileBase(),
217 g_currentMemberDef->anchor(),g_yyLineNr);
218 setCurrentDoc(lineAnchor);
220 else if (d->isLinkableInProject())
222 g_code->writeLineNumber(d->getReference(),
223 d->getOutputFileBase(),
225 setCurrentDoc(lineAnchor);
230 g_code->writeLineNumber(0,0,0,g_yyLineNr);
233 g_code->startCodeLine(g_sourceFileDef);
234 if (g_currentFontClass)
236 g_code->startFontClass(g_currentFontClass);
240 static void endFontClass();
241 static void endCodeLine()
244 g_code->endCodeLine();
247 static void nextCodeLine()
249 const char *fc = g_currentFontClass;
251 if (g_yyLineNr<g_inputLines)
253 g_currentFontClass = fc;
258 /*! writes a word to the output.
259 * If curr_class is defined, the word belongs to a class
260 * and will be linked.
263 static void writeWord(const char *word,const char* curr_class=0,bool classLink=FALSE)
267 QCString tclass(curr_class);
269 if (ttt.isEmpty()) return;
270 for (unsigned int j=0;j<ttt.length();j++)
273 if (c==' '|| c==',' || c==';' || c==':' || c=='(' || c==')' || c=='\r' || c=='\t' || c=='.')
277 if (!writeColoredWord(temp)) // is it a keyword ?
279 //if (VhdlDocGen::findKeyWord(temp))
280 // writeFont("vhdlkeyword",temp.data());
281 //printf("writeWord: %s\n",temp.data());
282 if (!tclass.isEmpty())
286 generateMemLink(*g_code,tclass,temp);
290 generateClassOrGlobalLink(*g_code,temp);
295 if (!checkVhdlString(temp))
296 g_code->codify(temp.data());
317 if (!writeColoredWord(temp))
319 if (!tclass.isEmpty())
323 generateMemLink(*g_code,tclass,temp); // generateMemLink(*g_code,g_CurrClass,left);
327 generateClassOrGlobalLink(*g_code,temp);
332 QCString qc(temp.data());
333 if (VhdlDocGen::isNumber(qc)){
334 startFontClass("vhdllogic");
335 g_code->codify(temp.data());
339 g_code->codify(temp.data());
346 /*! write a code fragment `text' that may span multiple lines, inserting
347 * line numbers for each line.
349 static void codifyLines(const char *text,const char *cl=0,bool classlink=FALSE)
352 //printf("codifyLines(%d,\"%s\")\n",g_yyLineNr,text);
353 const char *p=text,*sp=p;
359 while ((c=*p++) && c!='\n') {}
364 line = line.left(p-sp-1);
366 //g_code->codify(sp);
367 writeWord(line,cl,classlink);
372 //g_code->codify(sp);
373 writeWord(sp,cl,classlink);
379 /*! writes a link to a fragment \a text that may span multiple lines, inserting
380 * line numbers for each line. If \a text contains newlines, the link will be
381 * split into multiple links with the same destination, one for each line.
383 static void writeMultiLineCodeLink(CodeOutputInterface &ol,
384 const char *ref,const char *file,
385 const char *anchor,const char *text,
389 char *p=(char *)text;
394 while ((c=*p++) && c!='\n') {}
399 // printf("writeCodeLink(%s,%s,%s,%s)\n",ref,file,anchor,sp);
400 ol.writeCodeLink(ref,file,anchor,sp,tooltip);
405 ol.writeCodeLink(ref,file,anchor,sp,tooltip);
411 static void setParameterList(MemberDef *md)
413 g_classScope = md->getClassDef() ? md->getClassDef()->name().data() : "";
414 LockingPtr<ArgumentList> al = md->argumentList();
416 Argument *a = al->first();
419 g_parmName = a->name.copy();
420 g_parmType = a->type.copy();
421 int i = g_parmType.find('*');
422 if (i!=-1) g_parmType = g_parmType.left(i);
423 i = g_parmType.find('&');
424 if (i!=-1) g_parmType = g_parmType.left(i);
425 g_parmType.stripPrefix("const ");
426 g_parmType=g_parmType.stripWhiteSpace();
427 // g_theVarContext.addVariable(g_parmType,g_parmName);
433 /*! writes a link to a function or procedure
436 static void generateFuncLink(CodeOutputInterface &ol,MemberDef* mdef)
439 //printf("generateFuncLink(FuncName=%s)\n",mdef->name().data());
440 QCString memberName=mdef->name();
442 if (mdef && mdef->isLinkable()) // is it a linkable class
444 writeMultiLineCodeLink(ol,mdef->getReference(),
445 mdef->getOutputFileBase(),
448 mdef->briefDescriptionAsTooltip());
449 addToSearchIndex(memberName);
452 ol.linkableSymbol(g_yyLineNr,memberName,0,g_currentMemberDef?g_currentMemberDef:g_currentDefinition);
453 codifyLines(memberName.data());
454 addToSearchIndex(memberName);
455 } // generateFuncLink
458 static void generateMemLink(CodeOutputInterface &ol,QCString &clName,QCString& memberName)
460 if (memberName.isEmpty()) return;
461 if (clName.isEmpty())
463 codifyLines(memberName.data());
468 QCString className=clName;
472 //bool isLocal=FALSE;
474 md=VhdlDocGen::findMember(className,memberName);
475 ClassDef *po=VhdlDocGen::getClass(className.data());
477 if (md==0 && po && (VhdlDocGen::VhdlClasses)po->protection()==VhdlDocGen::PACKBODYCLASS)
479 QCString temp=className;//.stripPrefix("_");
480 temp.stripPrefix("_");
481 md=VhdlDocGen::findMember(temp,memberName);
484 if (md && md->isLinkable()) // is it a linkable class
486 writeMultiLineCodeLink(ol,md->getReference(),
487 md->getOutputFileBase(),
490 md->briefDescriptionAsTooltip());
491 addToSearchIndex(memberName);
494 // nothing found, just write out the word
495 ol.linkableSymbol(g_yyLineNr,memberName,0,g_currentMemberDef?g_currentMemberDef:g_currentDefinition);
496 codifyLines(memberName.data());
497 addToSearchIndex(memberName);
501 static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName, bool /*typeOnly*/)
503 QCString className=clName;
505 if (className.isEmpty()) return;
509 //bool isLocal=FALSE;
510 className.stripPrefix("_");
511 cd = getClass(className.data());
514 //className.stripPrefix("_");
515 QCString temp(clName);
516 temp.stripPrefix("_");
517 if (cd && cd->isLinkable()) // is it a linkable class
519 //if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ARCHITECTURECLASS)
521 // temp=VhdlDocGen::getClassName(cd);
523 ol.linkableSymbol(g_yyLineNr,temp,cd,
526 g_currentDefinition);
527 writeMultiLineCodeLink(ol,cd->getReference(),
528 cd->getOutputFileBase(),
531 cd->briefDescriptionAsTooltip());
532 addToSearchIndex(className);
535 Definition *d = cd->getOuterScope();
536 if (d && d->definitionType()==Definition::TypeClass)
546 // nothing found, just write out the word
547 ol.linkableSymbol(g_yyLineNr,clName,0,g_currentMemberDef?g_currentMemberDef:g_currentDefinition);
549 addToSearchIndex(clName);
550 }// generateClasss or global link
553 /*! counts the number of lines in the input */
554 static int countLines()
556 const char *p=g_inputString;
562 if (c=='\n') count++;
564 if (p>g_inputString && *(p-1)!='\n')
565 { // last line does not end with a \n, so we add an extra
566 // line and explicitly terminate the line after parsing.
568 g_needsTermination=TRUE;
573 static void endFontClass()
575 if (g_currentFontClass)
577 g_code->endFontClass();
578 g_currentFontClass=0;
582 static void startFontClass(const char *s)
586 g_code->startFontClass(s);
587 g_currentFontClass=s;
590 static void writeFont(const char *s,const char* text)
592 if (s==0 || text==0) return;
593 //printf("writeFont(%d,\"%s\")\n",g_yyLineNr,text);
594 g_code->startFontClass(s);
595 g_code->codify(text);
596 g_code->endFontClass();
599 //----------------------------------------------------------------------------
601 static void appStringLower(QCString& qcs,const char* text)
606 qcs=qcs.stripWhiteSpace();
609 //static void appString(QCString& qcs,const char* text)
615 static QCString g_temp;
617 /* writes and links a port map statement */
618 static void codifyMapLines(char *text)
625 //printf("codifyLines(%d,\"%s\")\n",g_yyLineNr,text);
626 char *p=text; //,*sp=p;
632 while ((c=*p++) && c!='\n' && c!=':' && c != ' ' && c != '(' && c!='\0' && c!='\t')
638 if (!g_temp.isEmpty()) wordCounter++;
640 if (!g_temp.isEmpty())
642 // different kinds of component instantiations
643 // xxx:yyy (generic/port) map(
644 // xxx:(entity/component/configuration) yyy (generic/port) map(
645 // xxx: entity yyy(zzz) (generic/port) map(
646 if (wordCounter==2 || wordCounter==3)
648 QCString q=g_temp.lower(); // consider (upper/lower) cases
649 if (q=="entity" || q=="component" || q=="configuration" || q=="port" || q=="generic")
651 generateMemLink(*g_code,g_CurrClass,g_temp);
655 g_PortMapComp=g_temp;
656 generateClassOrGlobalLink(*g_code,g_temp);
661 generateMemLink(*g_code,g_CurrClass,g_temp);
665 codifyLines(ctemp.data());
672 * writes a function|procedure prototype and links the function|procedure name
675 static void writeFuncProto()
679 VhdlDocGen::parseFuncProto(g_FuncProto,ql,name,ret,FALSE);
683 codifyLines(g_FuncProto.data(),g_CurrClass.data());
686 QStringList qlist=QStringList::split(name,g_FuncProto,FALSE);
687 QCString temp=qlist[0].utf8();
688 codifyLines(temp.data(),g_CurrClass.data());
689 g_FuncProto.stripPrefix(temp.data());
694 temp.stripPrefix("_");// _{package body name}
696 MemberDef *mdef=VhdlDocGen::findFunction(ql,name,temp,FALSE);
700 generateFuncLink(*g_code,mdef);
701 g_FuncProto.stripPrefix(name.data());
702 codifyLines(g_FuncProto.data(),g_CurrClass.data());
706 codifyLines(g_FuncProto.data(),g_CurrClass.data());
710 /* writes a process prototype to the ouput */
712 static void writeProcessProto(){
713 codifyLines(g_FuncProto.data(),g_CurrClass.data());
714 g_vhdlKeyDict.clear();
715 }// writeProcessProto
717 /* writes a keyword */
719 static bool writeColoredWord(QCString& word )
721 QCString qcs=word.lower();
722 QCString *ss=VhdlDocGen::findKeyWord(qcs);
725 writeFont(ss->data(),word.data());
732 #define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
734 static int yyread(char *buf,int max_size)
737 while( c < max_size && g_inputString[g_inputPosition] )
739 *buf = g_inputString[g_inputPosition++] ;
751 NAME [a-z_A-Z][ a-z_A-Z0-9]*
752 FUNCNAME [a-z_A-Z"][a-z_A-Z0-9+*"/=<>-]*
753 ID "$"?[a-z_A-Z][a-z_A-Z0-9]*
754 SPECSIGN [:;, +*&\/=<>'\t]*
755 DIGITSS [0-9]+|[0-9]+("#")*[0-9_a-fA-F\+\.\-]+("#")*
756 ALLTYPESMAP {B}*[_a-zA-Z0-9. ]+{BN}*
757 ALLTYPESMAP1 {BN}*[_a-zA-Z0-9.() ]+{BN}*
759 ARCHITECTURE ^{B}*("architecture"){BN}+{FUNCNAME}{BN}+("of"){BN}+{FUNCNAME}
760 PROCESS ({BN}*{FUNCNAME}{BN}*[:]+{BN}*("process"){BN}*[(]*)|[^a-zA-Z]("process "|"process("){BN}*[ (]*|[^a-zA-Z]("process"){BN}+
762 END1 {B}*("end "){BN}+("if"|"case"|"loop"|"generate"|"for")
763 END2 [^a-zA-Z_]("end"){BN}*[;]
764 END3 {BN}*[^a-zA-Z]("end"){BN}+{FUNCNAME}{BN}*[;]
765 END4 {B}*("end"){BN}+"function"{BN}+{FUNCNAME}{BN}*[;]
766 ENDEFUNC {END3}|{END4}|{END2}
768 KEYWORD ("new"|"event"|"break"|"case"|"end"|"loop"|"else"|"for"|"goto"|"if"|"return"|"generate"|"is"|"while"|"in")
769 TYPEKW ^{B}*("type"|"subtype"|"constant"|"attribute"|"signal"|"variable","alias","configuration")
770 FUNC ^{B}*("function"|"procedure"){BN}*{FUNCNAME}{BN}*("(")
772 ARITHOP "+"|"-"|"/"|"*"|"%"|"/="|":="
773 ASSIGNOP "="|"*="|"/="|"%="|"+="|"-="|"<<="|">>="|"&="|"^="|"|="
774 LOGICOP "=="|"!="|">"|"<"|">="|"<="|"&&"|"||"|"!"
775 BITOP "&"|"|"|"^"|"<<"|">>"|"~"
776 OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
778 PORT {B}*("port"){BN}*("(")
779 GENERIC {B}*("generic"){BN}*("(")
786 MAPCOMPONENT1 ({ALLTYPESMAP}[:]{ALLTYPESMAP}{TEXTT}*{BN}+("port"|"generic"){BN}+("map"){BN}*("("){1})
787 MAPCOMPONENT2 {BN}*("port"|"generic"){BN}+("map"){BN}*("("){1}
788 MAPCOMPONENT3 ({ALLTYPESMAP}[:]{BN}*{ALLTYPESMAP1}{TEXTT}*{BN}+("port"|"generic"){BN}+("map"){BN}*("("){1})
789 MAPCOMPONENT4 ({ALLTYPESMAP}[:]{BN}*("entity"|"component"|"configuration"){BN}+{ALLTYPESMAP1}{TEXTT}*{BN}*("port"|"generic"){BN}*("map"){BN}*("("){1})
791 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"
817 writeFont("vhdlchar",vhdlcodeYYtext);
821 <Map>[^()\n,--]* { /* write and link a port map lines */
822 QCString tt(vhdlcodeYYtext);
823 VhdlDocGen::deleteAllChars(tt,',');
825 QStringList ql=QStringList::split(r,tt,FALSE);
828 unsigned int index=0;
829 QCString t1=ql[0].utf8();
830 char cc=t1.at(index);
831 while (cc==' ' || cc=='\t')
838 if (index>=t1.size()) break;
843 s1=s1.stripWhiteSpace();
845 // if (!g_PortMapComp.isEmpty())
846 generateMemLink(*g_code,g_PortMapComp,s1);
847 while (index++<t1.size())
849 char cc=t1.at(index);
850 if (cc==' ' || cc=='\t')
860 QCString s2=ql[1].utf8();
863 while (cc==' ' || cc=='\t')
870 if (index>=t1.size()) break;
873 s2=s2.stripWhiteSpace();
874 if (!checkVhdlString(s2))
875 generateMemLink(*g_code,g_CurrClass,s2);
876 while (index++<t1.size())
878 if (t1.at(index)==' ')
886 codifyLines(vhdlcodeYYtext,g_CurrClass.data());
892 codifyLines(vhdlcodeYYtext);
898 writeFont("vhdlchar",vhdlcodeYYtext);
905 <ParseFuncProto>{NAME} {
906 QCString tmp(vhdlcodeYYtext);
907 tmp=tmp.stripWhiteSpace();
908 appStringLower(g_PrevString,vhdlcodeYYtext);
909 g_vhdlKeyDict.insert(g_PrevString,new QCString(g_PrevString.data()));
910 if (!writeColoredWord(tmp))
912 generateMemLink(*g_code,g_CurrClass,tmp);
917 <ParseType>{STRING} {
918 QCString qcs(vhdlcodeYYtext);
919 VhdlDocGen::deleteAllChars(qcs,'"');
920 VhdlDocGen::deleteAllChars(qcs,' ');
921 if (VhdlDocGen::isNumber(qcs))
922 writeFont("vhdllogic",vhdlcodeYYtext);
924 writeFont("keyword",vhdlcodeYYtext);
928 g_FuncProto.append(vhdlcodeYYtext);
931 codifyLines(vhdlcodeYYtext);
938 g_FuncProto.append(vhdlcodeYYtext);
941 writeFont("keyword",vhdlcodeYYtext);
946 <ParseType>{ENDEFUNC} {
947 QRegExp regg("[\\s]");
948 QCString tt(vhdlcodeYYtext);
949 codifyLines(vhdlcodeYYtext,g_CurrClass.data());
951 VhdlDocGen::deleteAllChars(tt,';');
952 tt.stripWhiteSpace();
953 QStringList ql=QStringList::split(regg,tt,FALSE);
954 int index=ql.findIndex(QCString("if"))+1;
955 index+=ql.findIndex(QCString("case"))+1;
956 index+=ql.findIndex(QCString("loop"))+1;
957 index+=ql.findIndex(QCString("generate"))+1;
969 codifyLines(vhdlcodeYYtext,g_CurrClass.data());
970 g_vhdlKeyDict.clear();
973 <ParseType>^{B}*("begin "|"begin") {
974 codifyLines(vhdlcodeYYtext,g_CurrClass.data());
978 <ParseType>{SPECSIGN} {
979 g_FuncProto.append(vhdlcodeYYtext);
982 codifyLines(vhdlcodeYYtext,g_CurrClass.data());
986 <ParseType>["_a-zA-Z0-9]* {
987 QCString val(vhdlcodeYYtext);
988 g_FuncProto.append(vhdlcodeYYtext);
989 appStringLower(g_PrevString,vhdlcodeYYtext);
991 if (isFuncProto && g_braceCount==0)
993 g_vhdlKeyDict.insert(g_PrevString,new QCString(g_PrevString.data()));
998 if (!writeColoredWord(val))
1000 if (!isFuncProto && !g_vhdlKeyDict.find(g_PrevString))
1002 val=val.stripWhiteSpace();
1003 if (VhdlDocGen::isNumber(val))
1005 startFontClass("vhdllogic");
1006 codifyLines(vhdlcodeYYtext,g_CurrClass.data());
1010 generateMemLink(*g_code,g_CurrClass,val);
1014 codifyLines(vhdlcodeYYtext,g_CurrClass.data());
1021 <ParseType>{BRACEOPEN} {
1026 writeFont("vhdlchar",vhdlcodeYYtext);
1031 <ParseType>{BRACECLOSE} {
1036 writeFont("vhdlchar",vhdlcodeYYtext);
1038 if (g_braceCount==0 && !isProto)// && !isPackageBody)
1041 appStringLower(g_PrevString,vhdlcodeYYtext);
1052 <ClassesName>{FUNCNAME} {
1053 QDict<QCString> mem;
1054 appStringLower(g_PrevString,vhdlcodeYYtext);
1055 g_CurrClass.resize(0);
1056 g_CurrClass.append(vhdlcodeYYtext);
1057 g_CurrClass=g_CurrClass.stripWhiteSpace();
1059 if (!writeColoredWord(g_CurrScope))
1061 generateClassOrGlobalLink(*g_code,vhdlcodeYYtext);
1065 codifyLines(vhdlcodeYYtext,g_CurrClass.data());
1071 <ParseComponent>{BRACEOPEN} {
1073 g_code->codify(vhdlcodeYYtext);
1077 <ParseComponent>{BRACECLOSE} {
1079 g_code->codify(vhdlcodeYYtext);
1080 if (g_braceCount==0 && !isComponent)
1082 g_tempComp.resize(0);
1087 BEGIN(ParseComponent);
1091 <ParseComponent>{B}*"-" {
1092 if (strlen(vhdlcodeYYtext)>=2) // found text ?
1094 writeFont("keyword",vhdlcodeYYtext);
1098 writeFont("vhdlchar",vhdlcodeYYtext);
1102 <ParseComponent>{SPECSIGN} {
1103 codifyLines(vhdlcodeYYtext);
1108 <ParseComponent>"\n"|" " {
1109 codifyLines(vhdlcodeYYtext);
1112 <ParseComponent>{DIGITSS} {
1113 startFontClass("vhdllogic");
1114 codifyLines(vhdlcodeYYtext);
1118 <ParseComponent>{PORT} {
1119 codifyLines(vhdlcodeYYtext);
1124 <ParseComponent>{GENERIC} {
1125 codifyLines(vhdlcodeYYtext);
1129 <ParseComponent>[_a-zA_Z][_a-zA-Z0-9]* {
1130 QCString temp(vhdlcodeYYtext);
1131 appStringLower(g_PrevString,vhdlcodeYYtext);
1132 if (!checkVhdlString(temp)){
1133 if (!writeColoredWord(g_PrevString))
1135 generateMemLink(*g_code,g_tempComp,temp);
1140 <ParseComponent>{STRING} {
1141 QCString temp(vhdlcodeYYtext);
1142 if (!checkVhdlString(temp))
1143 codifyLines(vhdlcodeYYtext);
1147 <ParseProcessProto>[^()]* {
1148 g_FuncProto.append(vhdlcodeYYtext);
1153 <ParseProcessProto>{BRACEOPEN} {
1154 g_FuncProto.append(vhdlcodeYYtext);
1158 <ParseProcessProto>{BRACECLOSE} {
1159 g_FuncProto.append(vhdlcodeYYtext);
1161 if (g_braceCount==0)
1163 writeProcessProto();
1168 <ParsePackage>[^:;]* { //found package
1169 QCString temp(vhdlcodeYYtext);
1170 QStringList strl=QStringList::split(".",temp,FALSE);
1174 QCString s1=strl[0].utf8();
1175 QCString s2=strl[1].utf8();
1176 QCString s3=strl[2].utf8();
1179 codifyLines(s1.data(),g_CurrClass.data());
1180 ClassDef *cd=VhdlDocGen::getPackageName(s2);
1183 generateClassOrGlobalLink(*g_code,s2.data());
1187 codifyLines(s2.data());
1189 codifyLines(s3.data());
1193 writeFont("keywordflow",vhdlcodeYYtext);
1198 <Bases>{MAPCOMPONENT1}|{MAPCOMPONENT2}|{MAPCOMPONENT3}|{MAPCOMPONENT4} { // found port or generic map
1199 QCString tt(vhdlcodeYYtext);
1201 if (tt.contains(':',FALSE))
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())
1220 if (left.contains('('))
1222 j=left.find('(',FALSE);
1223 QCString name=left.left(j);
1224 generateClassOrGlobalLink(*g_code,name.data());
1226 name=tt.right(tt.length()-name.length());
1227 codifyLines(name.data());
1231 generateClassOrGlobalLink(*g_code,left.data());
1232 tt.stripPrefix(left.data()); //=tt.right(tt.length()-left.length()-1);
1235 codifyLines(tt.data());
1241 if (tt.contains(':',FALSE))
1242 codifyMapLines(tt.data());
1244 codifyLines(tt.data());
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');
1258 codifyLines(vhdlcodeYYtext,temp.data(),TRUE);
1261 //if (getClass(temp.data()))
1262 // generateClassOrGlobalLink(*g_code,temp.data());
1264 // generateMemLink(*g_code,g_CurrClass,temp);
1267 BEGIN(ParseComponent);
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();
1283 //temp+=VhdlDocGen::getIndexWord(vhdlcodeYYtext,3);
1284 QCString temp = VhdlDocGen::getIndexWord(vhdlcodeYYtext,3);
1286 temp+=VhdlDocGen::getIndexWord(vhdlcodeYYtext,1);
1288 VhdlDocGen::deleteAllChars(temp,'\n');
1289 codifyLines(vhdlcodeYYtext,temp.data(),TRUE);
1290 //generateClassOrGlobalLink(*g_code,temp.data());
1291 isPackageBody=FALSE;
1296 <Bases>^{B}*("package "){BN}*("body"){BN}*{FUNCNAME} { // found package body
1297 QCString ss(vhdlcodeYYtext);
1298 QCString temp=VhdlDocGen::getIndexWord(vhdlcodeYYtext,2);
1299 QStringList ql=QStringList::split(temp,ss,FALSE);
1300 QCString ll=ql[0].utf8();
1301 codifyLines(ll.data(),g_CurrClass.data());
1302 temp=temp.stripWhiteSpace();
1304 generateClassOrGlobalLink(*g_code,temp.data());
1305 g_CurrClass.resize(0);
1309 // BEGIN(ClassesName);
1312 <Bases>{PROCESS} { // found process
1314 g_FuncProto.resize(0);
1315 g_FuncProto.append(vhdlcodeYYtext);
1316 g_vhdlKeyDict.clear();
1317 appStringLower(g_PrevString,vhdlcodeYYtext);
1318 if (g_PrevString.contains('('))
1321 BEGIN(ParseProcessProto);
1325 writeProcessProto();
1329 <Bases>("end"){BN}+("process") { // end of process
1331 codifyLines(vhdlcodeYYtext);
1336 <Bases>^{B}*("begin "|"begin") {
1338 writeFont("vhdlkeyword",vhdlcodeYYtext);
1341 <Bases>^{B}*("use"|"library"){BN}+ { //found package or library
1342 writeFont("vhdlkeyword",vhdlcodeYYtext);
1343 BEGIN(ParsePackage);
1347 <Bases>^{B}*("use"){BN}+("configuration")[^\n]* {
1348 codifyLines(vhdlcodeYYtext);
1353 <Bases>{FUNC} { // found function|procedure
1354 g_vhdlKeyDict.clear();
1355 g_FuncProto.resize(0);
1357 g_FuncProto.append(vhdlcodeYYtext);
1364 <Bases>^{B}*("entity"|"package"){BN}+ {
1365 appStringLower(g_PrevString,vhdlcodeYYtext);
1366 writeFont("keywordflow",vhdlcodeYYtext);
1367 isPackageBody=FALSE;
1372 <Bases>{KEYWORD} { // found keyword
1373 QCString qcs(vhdlcodeYYtext);
1374 if (!writeColoredWord(qcs))
1376 startFontClass("vhdlchar");
1377 g_code->codify(vhdlcodeYYtext);
1384 appStringLower(g_PrevString,vhdlcodeYYtext);
1385 QCString temp(vhdlcodeYYtext);
1386 temp=temp.stripWhiteSpace();
1388 if (!writeColoredWord(temp))
1390 startFontClass("vhdlchar");
1391 generateMemLink(*g_code,g_CurrClass,temp);
1396 <Bases,ParseComponent>{DIGITSS} {
1397 startFontClass("vhdllogic");
1398 codifyLines(vhdlcodeYYtext);
1402 <Bases>^{B}*("use"){BN}+("entity"|"component")[^\n]* {
1403 codifyLines(vhdlcodeYYtext,g_CurrClass.data(),TRUE);
1408 codifyLines(vhdlcodeYYtext);
1411 BEGIN(ParseFuncProto);
1420 startFontClass("vhdlchar");
1421 g_code->codify(vhdlcodeYYtext);
1425 <Bases>","|"."|":"|"'"|"("|")" {
1426 startFontClass("vhdlchar");
1427 g_code->codify(vhdlcodeYYtext);
1432 QCString qcs(vhdlcodeYYtext);
1433 VhdlDocGen::deleteAllChars(qcs,'"');
1434 VhdlDocGen::deleteAllChars(qcs,' ');
1436 if (VhdlDocGen::isNumber(qcs))
1437 writeFont("vhdllogic",vhdlcodeYYtext);
1439 writeFont("keyword",vhdlcodeYYtext);
1442 <Bases>{B}*"#"[^\n]* {
1443 writeFont("keyword",vhdlcodeYYtext);
1446 <Bases>^{B}*{XILINX}[^\n]* {
1448 //codifyLines(vhdlcodeYYtext,g_CurrClass.data(),TRUE);
1451 <Bases>^{B}*"set_"[^\n]* {
1456 codifyLines(vhdlcodeYYtext);
1461 g_code->codify(vhdlcodeYYtext);
1464 <*>\n{TEXTT} { // found normal or special comment on its own line
1465 QCString text(vhdlcodeYYtext);
1466 int i=text.find("--");
1467 if (text.mid(i,3)=="--!" && // hide special comment
1468 Config_getBool("STRIP_CODE_COMMENTS"))
1470 g_yyLineNr++; // skip complete line
1472 else // normal comment
1474 startFontClass("keyword");
1479 <*>{TEXTT} { // found normal or special comment after something
1480 QCString text(vhdlcodeYYtext);
1481 int i=text.find("--");
1482 if (text.mid(i,3)=="--!" &&
1483 Config_getBool("STRIP_CODE_COMMENTS"))
1485 // hide special comment
1487 else // normal comment
1489 startFontClass("keyword");
1498 /*@ ----------------------------------------------------------------------------
1501 void resetVhdlCodeParserState()
1503 g_vhdlKeyDict.setAutoDelete(TRUE);
1504 g_vhdlKeyDict.clear();
1507 void parseVhdlCode(CodeOutputInterface &od,const char *className,const QCString &s,
1508 bool /*exBlock*/, const char *exName,FileDef *fd,
1509 int startLine,int endLine,bool inlineFragment,
1510 MemberDef *memberDef,bool,Definition *searchCtx)
1512 //printf("***parseCode() exBlock=%d exName=%s fd=%p\n",exBlock,exName,fd);
1513 if (s.isEmpty()) return;
1516 ClassDef *dd=memberDef->getClassDef();
1517 if (dd) g_CurrClass=dd->className();
1520 resetVhdlCodeParserState();
1523 g_inputPosition = 0;
1524 g_currentFontClass = 0;
1525 g_needsTermination = FALSE;
1526 g_searchCtx = searchCtx;
1529 g_inputLines = endLine+1;
1531 g_inputLines = countLines();
1534 g_yyLineNr = startLine;
1539 // g_theCallContext.clear();
1540 g_classScope = className;
1541 g_exampleName = exName;
1542 g_sourceFileDef = fd;
1543 bool cleanupSourceDef = FALSE;
1546 // create a dummy filedef for the example
1547 g_sourceFileDef = new FileDef("",exName);
1548 cleanupSourceDef = TRUE;
1550 if (g_sourceFileDef)
1552 setCurrentDoc("l00001");
1554 g_currentDefinition = 0;
1555 g_currentMemberDef = 0;
1557 if (!g_exampleName.isEmpty())
1559 g_exampleFile = convertNameToFile(g_exampleName+"-example");
1561 g_includeCodeFragment = inlineFragment;
1566 // g_type.resize(0);
1567 // g_name.resize(0);
1568 // g_args.resize(0);
1569 g_parmName.resize(0);
1570 g_parmType.resize(0);
1573 setParameterList(memberDef);
1575 int iLine=countLines();
1576 vhdlcodeYYrestart( vhdlcodeYYin );
1580 if (g_needsTermination)
1584 if (cleanupSourceDef)
1586 // delete the temporary file definition used for this example
1587 delete g_sourceFileDef;
1590 assert(g_yyLineNr==iLine);
1594 void codeFreeVhdlScanner()
1596 #if defined(YY_FLEX_SUBMINOR_VERSION)
1599 vhdlcodeYYlex_destroy();
1604 #if !defined(YY_FLEX_SUBMINOR_VERSION)
1605 extern "C" { // some bogus code to keep the compiler happy
1606 void vhdlcodeYYdummy() { yy_flex_realloc(0,0); }
1608 #elif YY_FLEX_SUBMINOR_VERSION<33
1609 #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!"