1 /******************************************************************************
3 * Copyright (C) 1997-2015 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 highlighting and references for vhdl subset
18 * supports VHDL-87/93/2008
19 ******************************************************************************/
20 %option never-interactive
21 %option case-insensitive
22 %option prefix="vhdlcodeYY"
34 #include <qstringlist.h>
39 #include "outputlist.h"
41 #include "membername.h"
42 #include "searchindex.h"
43 #include "vhdldocgen.h"
44 #include "arguments.h"
51 #define YY_NO_UNISTD_H 1
53 // Toggle for some debugging info
54 //#define DBG_CTX(x) fprintf x
55 #define DBG_CTX(x) do { } while(0)
58 /* -----------------------------------------------------------------
62 // ----------------- <vhdl> ----------------------------------
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;
79 //-----------------------------------------------------------
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;
91 static bool g_exampleBlock;
92 static QCString g_exampleName;
93 static QCString g_exampleFile;
95 static QCString g_classScope;
97 static QCString g_CurrScope;
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;
105 static bool g_lexInit = FALSE;
106 static int g_braceCount=0;
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);
113 static void endFontClass();
114 static void startFontClass(const char *s);
115 //-------------------------------------------------------------------
118 static void setCurrentDoc(const QCString &anchor)
120 if (Doxygen::searchIndex)
124 Doxygen::searchIndex->setCurrentDoc(g_searchCtx,g_searchCtx->anchor(),FALSE);
128 Doxygen::searchIndex->setCurrentDoc(g_sourceFileDef,anchor,TRUE);
133 static bool checkVhdlString(QCString &name)
135 if (name.isEmpty()) return FALSE;
136 static QRegExp regg("[\\s\"]");
138 int len=name.length();
139 if (name.at(0)=='"' && name.at(len-1)=='"' && len > 2)
141 QStringList qrl=QStringList::split(regg,name,FALSE);
142 if (VhdlDocGen::isNumber(qrl[0].utf8()))
144 g_code->codify("\"");
145 startFontClass("vhdllogic");
146 QCString mid=name.mid(1,len-2); //" 1223 "
147 g_code->codify(mid.data());
149 g_code->codify("\"");
153 startFontClass("keyword");
154 g_code->codify(name.data());
160 if (VhdlDocGen::isNumber(name))
162 startFontClass("vhdllogic");
163 g_code->codify(name.data());
170 static void addToSearchIndex(const char *text)
172 if (Doxygen::searchIndex)
174 Doxygen::searchIndex->addWord(text,FALSE);
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.
183 static void startCodeLine()
185 //if (g_currentFontClass) { g_code->endFontClass(); }
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)
197 g_currentDefinition = d;
198 g_currentMemberDef = g_sourceFileDef->getSourceMember(g_yyLineNr);
199 if (!g_tempComp.isEmpty() && g_currentMemberDef )
201 //ClassDef *cf=VhdlDocGen::getClass(g_tempComp.data());
202 QCString nn=g_currentMemberDef->name();
203 MemberDef* mdeff=VhdlDocGen::findMember(g_tempComp,nn);
206 g_currentMemberDef=mdeff;
210 g_parmType.resize(0);
211 g_parmName.resize(0);
213 lineAnchor.sprintf("l%05d",g_yyLineNr);
214 if (g_currentMemberDef)
216 g_code->writeLineNumber(g_currentMemberDef->getReference(),
217 g_currentMemberDef->getOutputFileBase(),
218 g_currentMemberDef->anchor(),g_yyLineNr);
219 setCurrentDoc(lineAnchor);
221 else if (d->isLinkableInProject())
223 g_code->writeLineNumber(d->getReference(),
224 d->getOutputFileBase(),
226 setCurrentDoc(lineAnchor);
231 g_code->writeLineNumber(0,0,0,g_yyLineNr);
234 g_code->startCodeLine(g_sourceFileDef);
236 if (g_currentFontClass)
238 g_code->startFontClass(g_currentFontClass);
242 static void endCodeLine()
245 g_code->endCodeLine();
248 static void nextCodeLine()
252 endCodeLine(); // </div>
254 const char *fc = g_currentFontClass;
255 if (g_yyLineNr<g_inputLines)
257 g_currentFontClass = fc;
258 startCodeLine(); //<div>
262 /*! writes a word to the output.
263 * If curr_class is defined, the word belongs to a class
264 * and will be linked.
267 static void writeWord(const char *word,const char* curr_class=0,bool classLink=FALSE)
271 QCString tclass(curr_class);
273 if (ttt.isEmpty()) return;
274 for (unsigned int j=0;j<ttt.length();j++)
277 if (c==' '|| c==',' || c==';' || c==':' || c=='(' || c==')' || c=='\r' || c=='\t' || c=='.')
281 if (!writeColoredWord(temp)) // is it a keyword ?
283 //if (VhdlDocGen::findKeyWord(temp))
284 // writeFont("vhdlkeyword",temp.data());
285 //printf("writeWord: %s\n",temp.data());
286 if (!tclass.isEmpty())
290 generateMemLink(*g_code,tclass,temp);
294 generateClassOrGlobalLink(*g_code,temp);
299 if (!checkVhdlString(temp))
300 g_code->codify(temp.data());
321 if (!writeColoredWord(temp))
323 if (!tclass.isEmpty())
327 generateMemLink(*g_code,tclass,temp); // generateMemLink(*g_code,g_CurrClass,left);
331 generateClassOrGlobalLink(*g_code,temp);
336 QCString qc(temp.data());
337 if (VhdlDocGen::isNumber(qc)){
338 startFontClass("vhdllogic");
339 g_code->codify(temp.data());
343 g_code->codify(temp.data());
350 /*! write a code fragment `text' that may span multiple lines, inserting
351 * line numbers for each line.
353 static void codifyLines(const char *text,const char *cl=0,bool classlink=FALSE,bool comment=FALSE)
356 //printf("codifyLines(%d,\"%s\")\n",g_yyLineNr,text);
357 const char *p=text,*sp=p;
363 while ((c=*p++) && c!='\n') {}
368 line = line.left((int)(p-sp)-1);
370 //g_code->codify(sp);
373 writeFont("keyword",line.data());
377 writeWord(line,cl,classlink);
384 writeFont("keyword",sp);
386 writeWord(sp,cl,classlink);
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.
396 static void writeMultiLineCodeLink(CodeOutputInterface &ol,
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();
406 if (!sourceTooltips) // fall back to simple "title" tooltips
408 tooltip = d->briefDescriptionAsTooltip();
411 char *p=(char *)text;
416 while ((c=*p++) && c!='\n') {}
421 // printf("writeCodeLink(%s,%s,%s,%s)\n",ref,file,anchor,sp);
422 ol.writeCodeLink(ref,file,anchor,sp,tooltip);
427 ol.writeCodeLink(ref,file,anchor,sp,tooltip);
433 static void setParameterList(MemberDef *md)
435 g_classScope = md->getClassDef() ? md->getClassDef()->name().data() : "";
436 ArgumentList *al = md->argumentList();
438 ArgumentListIterator ali(*al);
440 for (ali.toFirst();(a=ali.current());++ali)
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);
455 /*! writes a link to a function or procedure
458 static void generateFuncLink(CodeOutputInterface &ol,MemberDef* mdef)
461 //printf("generateFuncLink(FuncName=%s)\n",mdef->name().data());
462 QCString memberName=mdef->name();
464 if (mdef && mdef->isLinkable()) // is it a linkable class
466 writeMultiLineCodeLink(ol,mdef,mdef->name());
467 addToSearchIndex(memberName);
470 codifyLines(memberName.data());
471 addToSearchIndex(memberName);
472 } // generateFuncLink
475 static void generateMemLink(CodeOutputInterface &ol,QCString &clName,QCString& memberName)
477 if (memberName.isEmpty()) return;
478 if (clName.isEmpty())
480 codifyLines(memberName.data());
485 QCString className=clName;
489 //bool isLocal=FALSE;
491 md=VhdlDocGen::findMember(className,memberName);
492 ClassDef *po=VhdlDocGen::getClass(className.data());
494 if (md==0 && po && (VhdlDocGen::VhdlClasses)po->protection()==VhdlDocGen::PACKBODYCLASS)
496 QCString temp=className;//.stripPrefix("_");
497 temp.stripPrefix("_");
498 md=VhdlDocGen::findMember(temp,memberName);
501 if (md && md->isLinkable()) // is it a linkable class
503 writeMultiLineCodeLink(ol,md,memberName);
504 addToSearchIndex(memberName);
507 // nothing found, just write out the word
508 codifyLines(memberName.data());
509 addToSearchIndex(memberName);
513 static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName, bool /*typeOnly*/)
515 QCString className=clName;
517 if (className.isEmpty()) return;
521 //bool isLocal=FALSE;
522 className.stripPrefix("_");
523 cd = getClass(className.data());
526 //className.stripPrefix("_");
527 QCString temp(clName);
528 temp.stripPrefix("_");
529 if (cd && cd->isLinkable()) // is it a linkable class
531 //if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ARCHITECTURECLASS)
533 // temp=VhdlDocGen::getClassName(cd);
535 writeMultiLineCodeLink(ol,cd,temp);
536 addToSearchIndex(className);
539 Definition *d = cd->getOuterScope();
540 if (d && d->definitionType()==Definition::TypeClass)
550 // nothing found, just write out the word
552 addToSearchIndex(clName);
553 }// generateClasss or global link
556 /*! counts the number of lines in the input */
557 static int countLines()
559 const char *p=g_inputString;
565 if (c=='\n') count++;
567 if (p>g_inputString && *(p-1)!='\n')
568 { // last line does not end with a \n, so we add an extra
569 // line and explicitly terminate the line after parsing.
571 g_needsTermination=TRUE;
576 static void endFontClass()
578 if (g_currentFontClass)
580 g_code->endFontClass();
581 g_currentFontClass=0;
585 static void startFontClass(const char *s)
589 g_code->startFontClass(s);
590 g_currentFontClass=s;
593 static void writeFont(const char *s,const char* text)
595 if (s==0 || text==0) return;
596 //printf("writeFont(%d,\"%s\")\n",g_yyLineNr,text);
597 g_code->startFontClass(s);
598 g_code->codify(text);
599 g_code->endFontClass();
602 //----------------------------------------------------------------------------
604 static void appStringLower(QCString& qcs,const char* text)
609 qcs=qcs.stripWhiteSpace();
612 //static void appString(QCString& qcs,const char* text)
618 static QCString g_temp;
620 /* writes and links a port map statement */
621 static void codifyMapLines(const char *text)
628 //printf("codifyLines(%d,\"%s\")\n",g_yyLineNr,text);
629 const char *p=text; //,*sp=p;
635 while ((c=*p++) && c!='\n' && c!=':' && c != ' ' && c != '(' && c!='\0' && c!='\t')
641 if (!g_temp.isEmpty()) wordCounter++;
643 if (!g_temp.isEmpty())
645 // different kinds of component instantiations
646 // xxx:yyy (generic/port) map(
647 // xxx:(entity/component/configuration) yyy (generic/port) map(
648 // xxx: entity yyy(zzz) (generic/port) map(
649 if (wordCounter==2 || wordCounter==3)
651 QCString q=g_temp.lower(); // consider (upper/lower) cases
652 if (q=="entity" || q=="component" || q=="configuration" || q=="port" || q=="generic")
654 generateMemLink(*g_code,g_CurrClass,g_temp);
658 g_PortMapComp=g_temp;
659 generateClassOrGlobalLink(*g_code,g_temp);
664 generateMemLink(*g_code,g_CurrClass,g_temp);
668 codifyLines(ctemp.data());
675 * writes a function|procedure prototype and links the function|procedure name
678 static void writeFuncProto()
682 VhdlDocGen::parseFuncProto(g_FuncProto,ql,name,ret,FALSE);
686 codifyLines(g_FuncProto.data(),g_CurrClass.data());
689 QStringList qlist=QStringList::split(name,g_FuncProto,FALSE);
690 QCString temp=qlist[0].utf8();
691 codifyLines(temp.data(),g_CurrClass.data());
692 g_FuncProto.stripPrefix(temp.data());
697 temp.stripPrefix("_");// _{package body name}
699 MemberDef *mdef=VhdlDocGen::findFunction(ql,name,temp,FALSE);
703 generateFuncLink(*g_code,mdef);
704 g_FuncProto.stripPrefix(name.data());
705 codifyLines(g_FuncProto.data(),g_CurrClass.data());
709 codifyLines(g_FuncProto.data(),g_CurrClass.data());
713 /* writes a process prototype to the output */
715 static void writeProcessProto(){
716 codifyLines(g_FuncProto.data(),g_CurrClass.data());
717 g_vhdlKeyDict.clear();
718 }// writeProcessProto
720 /* writes a keyword */
722 static bool writeColoredWord(QCString& word )
724 QCString qcs=word.lower();
725 QCString *ss=VhdlDocGen::findKeyWord(qcs);
728 writeFont(ss->data(),word.data());
735 #define YY_INPUT(buf,result,max_size) result=yyread(buf,max_size);
737 static int yyread(char *buf,int max_size)
740 while( c < max_size && g_inputString[g_inputPosition] )
742 *buf = g_inputString[g_inputPosition++] ;
754 NAME [a-z_A-Z][ a-z_A-Z0-9]*
755 FUNCNAME [a-z_A-Z"][a-z_A-Z0-9+*"/=<>-]*
756 ID "$"?[a-z_A-Z][a-z_A-Z0-9]*
757 SPECSIGN [:;, +*&\/=<>'\t]*
758 DIGITSS [0-9]+|[0-9]+("#")*[0-9_a-fA-F\+\.\-]+("#")*
759 ALLTYPESMAP {B}*[_a-zA-Z0-9. ]+{BN}*
760 ALLTYPESMAP1 {BN}*[_a-zA-Z0-9.() ]+{BN}*
762 ARCHITECTURE ^{B}*("architecture"){BN}+{FUNCNAME}{BN}+("of"){BN}+{FUNCNAME}
763 PROCESS ({BN}*{FUNCNAME}{BN}*[:]+{BN}*("process"){BN}*[(]*)|[^a-zA-Z]("process "|"process("){BN}*[ (]*|[^a-zA-Z]("process"){BN}+
765 END1 {B}*("end "){BN}+("if"|"case"|"loop"|"generate"|"for")
766 END2 [^a-zA-Z_]("end"){BN}*[;]
767 END3 {BN}*[^a-zA-Z]("end"){BN}+{FUNCNAME}{BN}*[;]
768 END4 {B}*("end"){BN}+"function"{BN}+{FUNCNAME}{BN}*[;]
769 ENDEFUNC {END3}|{END4}|{END2}
771 KEYWORD ("new"|"event"|"break"|"case"|"end"|"loop"|"else"|"for"|"goto"|"if"|"return"|"generate"|"is"|"while"|"in")
772 TYPEKW ^{B}*("type"|"subtype"|"constant"|"attribute"|"signal"|"variable","alias","configuration")
773 FUNC ^{B}*("function"|"procedure"){BN}*{FUNCNAME}{BN}*("(")
775 ARITHOP "+"|"-"|"/"|"*"|"%"|"/="|":="
776 ASSIGNOP "="|"*="|"/="|"%="|"+="|"-="|"<<="|">>="|"&="|"^="|"|="
777 LOGICOP "=="|"!="|">"|"<"|">="|"<="|"&&"|"||"|"!"
778 BITOP "&"|"|"|"^"|"<<"|">>"|"~"
779 OPERATOR {ARITHOP}|{ASSIGNOP}|{LOGICOP}|{BITOP}
781 PORT {B}*("port"){BN}*("(")
782 GENERIC {B}*("generic"){BN}*("(")
789 MAPCOMPONENT1 ({ALLTYPESMAP}[:]{ALLTYPESMAP}{TEXTT}*{BN}+("port"|"generic"){BN}+("map"){BN}*("("){1})
790 MAPCOMPONENT2 {BN}*("port"|"generic"){BN}+("map"){BN}*("("){1}
791 MAPCOMPONENT3 ({ALLTYPESMAP}[:]{BN}*{ALLTYPESMAP1}{TEXTT}*{BN}+("port"|"generic"){BN}+("map"){BN}*("("){1})
792 MAPCOMPONENT4 ({ALLTYPESMAP}[:]{BN}*("entity"|"component"|"configuration"){BN}+{ALLTYPESMAP1}{TEXTT}*{BN}*("port"|"generic"){BN}*("map"){BN}*("("){1})
794 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"
820 writeFont("vhdlchar",vhdlcodeYYtext);
824 <Map>[^()\n,--]* { /* write and link a port map lines */
825 QCString tt(vhdlcodeYYtext);
826 VhdlDocGen::deleteAllChars(tt,',');
828 QStringList ql=QStringList::split(r,tt,FALSE);
831 unsigned int index=0;
832 QCString t1=ql[0].utf8();
833 char cc=t1.at(index);
834 while (cc==' ' || cc=='\t')
841 if (index>=t1.size()) break;
846 s1=s1.stripWhiteSpace();
848 // if (!g_PortMapComp.isEmpty())
849 generateMemLink(*g_code,g_PortMapComp,s1);
850 while (index++<t1.size())
852 char cc=t1.at(index);
853 if (cc==' ' || cc=='\t')
863 QCString s2=ql[1].utf8();
866 while (cc==' ' || cc=='\t')
873 if (index>=t1.size()) break;
876 s2=s2.stripWhiteSpace();
877 if (!checkVhdlString(s2))
878 generateMemLink(*g_code,g_CurrClass,s2);
879 while (index++<t1.size())
881 if (t1.at(index)==' ')
889 codifyLines(vhdlcodeYYtext,g_CurrClass.data());
895 codifyLines(vhdlcodeYYtext);
901 writeFont("vhdlchar",vhdlcodeYYtext);
908 <ParseFuncProto>{NAME} {
909 QCString tmp(vhdlcodeYYtext);
910 tmp=tmp.stripWhiteSpace();
911 appStringLower(g_PrevString,vhdlcodeYYtext);
912 g_vhdlKeyDict.insert(g_PrevString,new QCString(g_PrevString.data()));
913 if (!writeColoredWord(tmp))
915 generateMemLink(*g_code,g_CurrClass,tmp);
920 <ParseType>{STRING} {
921 QCString qcs(vhdlcodeYYtext);
922 VhdlDocGen::deleteAllChars(qcs,'"');
923 VhdlDocGen::deleteAllChars(qcs,' ');
924 if (VhdlDocGen::isNumber(qcs))
925 writeFont("vhdllogic",vhdlcodeYYtext);
927 writeFont("keyword",vhdlcodeYYtext);
931 g_FuncProto.append(vhdlcodeYYtext);
934 codifyLines(vhdlcodeYYtext);
941 g_FuncProto.append(vhdlcodeYYtext);
944 writeFont("keyword",vhdlcodeYYtext);
949 <ParseType>{ENDEFUNC} {
950 QRegExp regg("[\\s]");
951 QCString tt(vhdlcodeYYtext);
952 codifyLines(vhdlcodeYYtext,g_CurrClass.data());
954 VhdlDocGen::deleteAllChars(tt,';');
955 tt.stripWhiteSpace();
956 QStringList ql=QStringList::split(regg,tt,FALSE);
957 int index=ql.findIndex(QCString("if"))+1;
958 index+=ql.findIndex(QCString("case"))+1;
959 index+=ql.findIndex(QCString("loop"))+1;
960 index+=ql.findIndex(QCString("generate"))+1;
972 codifyLines(vhdlcodeYYtext,g_CurrClass.data());
973 g_vhdlKeyDict.clear();
976 <ParseType>^{B}*("begin "|"begin") {
977 codifyLines(vhdlcodeYYtext,g_CurrClass.data());
981 <ParseType>{SPECSIGN} {
982 g_FuncProto.append(vhdlcodeYYtext);
985 codifyLines(vhdlcodeYYtext,g_CurrClass.data());
989 <ParseType>["_a-zA-Z0-9]* {
990 QCString val(vhdlcodeYYtext);
991 g_FuncProto.append(vhdlcodeYYtext);
992 appStringLower(g_PrevString,vhdlcodeYYtext);
994 if (isFuncProto && g_braceCount==0)
996 g_vhdlKeyDict.insert(g_PrevString,new QCString(g_PrevString.data()));
1001 if (!writeColoredWord(val))
1003 if (!isFuncProto && !g_vhdlKeyDict.find(g_PrevString))
1005 val=val.stripWhiteSpace();
1006 if (VhdlDocGen::isNumber(val))
1008 startFontClass("vhdllogic");
1009 codifyLines(vhdlcodeYYtext,g_CurrClass.data());
1013 generateMemLink(*g_code,g_CurrClass,val);
1017 codifyLines(vhdlcodeYYtext,g_CurrClass.data());
1024 <ParseType>{BRACEOPEN} {
1029 writeFont("vhdlchar",vhdlcodeYYtext);
1034 <ParseType>{BRACECLOSE} {
1039 writeFont("vhdlchar",vhdlcodeYYtext);
1041 if (g_braceCount==0 && !isProto)// && !isPackageBody)
1044 appStringLower(g_PrevString,vhdlcodeYYtext);
1055 <ClassesName>{FUNCNAME} {
1056 appStringLower(g_PrevString,vhdlcodeYYtext);
1057 g_CurrClass.resize(0);
1058 g_CurrClass.append(vhdlcodeYYtext);
1059 g_CurrClass=g_CurrClass.stripWhiteSpace();
1061 if (!writeColoredWord(g_CurrScope))
1063 generateClassOrGlobalLink(*g_code,vhdlcodeYYtext);
1067 codifyLines(vhdlcodeYYtext,g_CurrClass.data());
1073 <ParseComponent>{BRACEOPEN} {
1075 g_code->codify(vhdlcodeYYtext);
1079 <ParseComponent>{BRACECLOSE} {
1081 g_code->codify(vhdlcodeYYtext);
1082 if (g_braceCount==0 && !isComponent)
1084 g_tempComp.resize(0);
1089 BEGIN(ParseComponent);
1093 <ParseComponent>{B}*"-" {
1094 if (strlen(vhdlcodeYYtext)>=2) // found text ?
1096 writeFont("keyword",vhdlcodeYYtext);
1100 writeFont("vhdlchar",vhdlcodeYYtext);
1104 <ParseComponent>{SPECSIGN} {
1105 codifyLines(vhdlcodeYYtext);
1110 <ParseComponent>"\n"|" " {
1111 codifyLines(vhdlcodeYYtext);
1114 <ParseComponent>{DIGITSS} {
1115 startFontClass("vhdllogic");
1116 codifyLines(vhdlcodeYYtext);
1120 <ParseComponent>{PORT} {
1121 codifyLines(vhdlcodeYYtext);
1126 <ParseComponent>{GENERIC} {
1127 codifyLines(vhdlcodeYYtext);
1131 <ParseComponent>[_a-zA_Z][_a-zA-Z0-9]* {
1132 QCString temp(vhdlcodeYYtext);
1133 appStringLower(g_PrevString,vhdlcodeYYtext);
1134 if (!checkVhdlString(temp)){
1135 if (!writeColoredWord(g_PrevString))
1137 generateMemLink(*g_code,g_tempComp,temp);
1142 <ParseComponent>{STRING} {
1143 QCString temp(vhdlcodeYYtext);
1144 if (!checkVhdlString(temp))
1145 codifyLines(vhdlcodeYYtext);
1149 <ParseProcessProto>[^()]* {
1150 g_FuncProto.append(vhdlcodeYYtext);
1155 <ParseProcessProto>{BRACEOPEN} {
1156 g_FuncProto.append(vhdlcodeYYtext);
1160 <ParseProcessProto>{BRACECLOSE} {
1161 g_FuncProto.append(vhdlcodeYYtext);
1163 if (g_braceCount==0)
1165 writeProcessProto();
1170 <ParsePackage>[^:;]* { //found package
1171 QCString temp(vhdlcodeYYtext);
1172 QStringList strl=QStringList::split(".",temp,FALSE);
1176 QCString s1=strl[0].utf8();
1177 QCString s2=strl[1].utf8();
1178 QCString s3=strl[2].utf8();
1181 codifyLines(s1.data(),g_CurrClass.data());
1182 ClassDef *cd=VhdlDocGen::getPackageName(s2);
1185 generateClassOrGlobalLink(*g_code,s2.data());
1189 codifyLines(s2.data());
1191 codifyLines(s3.data());
1195 writeFont("keywordflow",vhdlcodeYYtext);
1200 <Bases>{MAPCOMPONENT1}|{MAPCOMPONENT2}|{MAPCOMPONENT3}|{MAPCOMPONENT4} { // found port or generic map
1201 QCString tt(vhdlcodeYYtext);
1203 if (tt.contains(':',FALSE))
1216 QCString left=tt.left(j+1);
1217 codifyLines(left.data());
1218 tt=tt.right(tt.length()-j-1);
1219 left=VhdlDocGen::getIndexWord(tt.data(),0);
1220 if (!left.isEmpty())
1222 if (left.contains('('))
1224 j=left.find('(',FALSE);
1225 QCString name=left.left(j);
1226 generateClassOrGlobalLink(*g_code,name.data());
1228 name=tt.right(tt.length()-name.length());
1229 codifyLines(name.data());
1233 generateClassOrGlobalLink(*g_code,left.data());
1234 tt.stripPrefix(left.data()); //=tt.right(tt.length()-left.length()-1);
1237 codifyLines(tt.data());
1243 if (tt.contains(':',FALSE))
1244 codifyMapLines(tt.data());
1246 codifyLines(tt.data());
1252 <Bases>^{B}*("component"){BN}+{FUNCNAME} { // found component
1253 appStringLower(g_PrevString,vhdlcodeYYtext);
1254 // writeFont("keywordflow",VhdlDocGen::getIndexWord(vhdlcodeYYtext,0).data());
1255 // writeFont("vhdlkeyword"," ");
1256 QCString temp=VhdlDocGen::getIndexWord(vhdlcodeYYtext,1);
1257 temp=temp.stripWhiteSpace();
1258 VhdlDocGen::deleteAllChars(temp,'\n');
1260 codifyLines(vhdlcodeYYtext,temp.data(),TRUE);
1263 //if (getClass(temp.data()))
1264 // generateClassOrGlobalLink(*g_code,temp.data());
1266 // generateMemLink(*g_code,g_CurrClass,temp);
1269 BEGIN(ParseComponent);
1274 <Bases>{ARCHITECTURE} { // found architecture
1275 g_PortMapComp.resize(0);
1276 // writeFont("vhdlkeyword",VhdlDocGen::getIndexWord(vhdlcodeYYtext,0).data());
1277 // writeFont("vhdlkeyword"," ");
1278 // writeFont("vhdlchar",VhdlDocGen::getIndexWord(vhdlcodeYYtext,1).data());
1279 // writeFont("vhdlkeyword"," ");
1280 // writeFont("vhdlkeyword",VhdlDocGen::getIndexWord(vhdlcodeYYtext,2).data());
1281 // writeFont("vhdlkeyword"," ");
1282 //QCString temp=VhdlDocGen::getIndexWord(vhdlcodeYYtext,1);
1283 //temp=temp.stripWhiteSpace();
1285 //temp+=VhdlDocGen::getIndexWord(vhdlcodeYYtext,3);
1286 QCString temp = VhdlDocGen::getIndexWord(vhdlcodeYYtext,3);
1288 temp+=VhdlDocGen::getIndexWord(vhdlcodeYYtext,1);
1290 VhdlDocGen::deleteAllChars(temp,'\n');
1291 codifyLines(vhdlcodeYYtext,temp.data(),TRUE);
1292 //generateClassOrGlobalLink(*g_code,temp.data());
1293 isPackageBody=FALSE;
1298 <Bases>^{B}*("package "){BN}*("body"){BN}*{FUNCNAME} { // found package body
1299 QCString ss(vhdlcodeYYtext);
1300 QCString temp=VhdlDocGen::getIndexWord(vhdlcodeYYtext,2);
1301 QStringList ql=QStringList::split(temp,ss,FALSE);
1302 QCString ll=ql[0].utf8();
1303 codifyLines(ll.data(),g_CurrClass.data());
1304 temp=temp.stripWhiteSpace();
1306 generateClassOrGlobalLink(*g_code,temp.data());
1307 g_CurrClass.resize(0);
1311 // BEGIN(ClassesName);
1314 <Bases>{PROCESS} { // found process
1316 g_FuncProto.resize(0);
1317 g_FuncProto.append(vhdlcodeYYtext);
1318 g_vhdlKeyDict.clear();
1319 appStringLower(g_PrevString,vhdlcodeYYtext);
1320 if (g_PrevString.contains('('))
1323 BEGIN(ParseProcessProto);
1327 writeProcessProto();
1331 <Bases>("end"){BN}+("process") { // end of process
1333 codifyLines(vhdlcodeYYtext);
1338 <Bases>^{B}*("begin "|"begin") {
1340 writeFont("vhdlkeyword",vhdlcodeYYtext);
1343 <Bases>^{B}*("use"|"library"){BN}+ { //found package or library
1344 writeFont("vhdlkeyword",vhdlcodeYYtext);
1345 BEGIN(ParsePackage);
1349 <Bases>^{B}*("use"){BN}+("configuration")[^\n]* {
1350 codifyLines(vhdlcodeYYtext);
1355 <Bases>{FUNC} { // found function|procedure
1356 g_vhdlKeyDict.clear();
1357 g_FuncProto.resize(0);
1359 g_FuncProto.append(vhdlcodeYYtext);
1366 <Bases>^{B}*("entity"|"package"){BN}+ {
1367 appStringLower(g_PrevString,vhdlcodeYYtext);
1368 writeFont("keywordflow",vhdlcodeYYtext);
1369 isPackageBody=FALSE;
1374 <Bases>{KEYWORD} { // found keyword
1375 QCString qcs(vhdlcodeYYtext);
1376 if (!writeColoredWord(qcs))
1378 startFontClass("vhdlchar");
1379 g_code->codify(vhdlcodeYYtext);
1386 appStringLower(g_PrevString,vhdlcodeYYtext);
1387 QCString temp(vhdlcodeYYtext);
1388 temp=temp.stripWhiteSpace();
1390 if (!writeColoredWord(temp))
1392 startFontClass("vhdlchar");
1393 generateMemLink(*g_code,g_CurrClass,temp);
1398 <Bases,ParseComponent>{DIGITSS} {
1399 startFontClass("vhdllogic");
1400 codifyLines(vhdlcodeYYtext);
1404 <Bases>^{B}*("use"){BN}+("entity"|"component")[^\n]* {
1405 codifyLines(vhdlcodeYYtext,g_CurrClass.data(),TRUE);
1410 codifyLines(vhdlcodeYYtext);
1413 BEGIN(ParseFuncProto);
1422 startFontClass("vhdlchar");
1423 g_code->codify(vhdlcodeYYtext);
1427 <Bases>","|"."|":"|"'"|"("|")" {
1428 startFontClass("vhdlchar");
1429 g_code->codify(vhdlcodeYYtext);
1434 QCString qcs(vhdlcodeYYtext);
1435 VhdlDocGen::deleteAllChars(qcs,'"');
1436 VhdlDocGen::deleteAllChars(qcs,' ');
1438 if (VhdlDocGen::isNumber(qcs))
1439 writeFont("vhdllogic",vhdlcodeYYtext);
1441 writeFont("keyword",vhdlcodeYYtext);
1444 <Bases>{B}*"#"[^\n]* {
1445 writeFont("keyword",vhdlcodeYYtext);
1448 <Bases>^{B}*{XILINX}[^\n]* {
1450 //codifyLines(vhdlcodeYYtext,g_CurrClass.data(),TRUE);
1453 <Bases>^{B}*"set_"[^\n]* {
1458 codifyLines(vhdlcodeYYtext);
1463 g_code->codify(vhdlcodeYYtext);
1466 <*>\n{TEXTT} { // found normal or special comment on its own line
1467 QCString text(vhdlcodeYYtext);
1468 int i=text.find("--");
1469 if (text.mid(i,3)=="--!" && // hide special comment
1470 Config_getBool(STRIP_CODE_COMMENTS))
1472 g_yyLineNr++; // skip complete line
1474 else // normal comment
1476 // startFontClass("keyword");
1477 codifyLines(text,0,FALSE,TRUE);
1481 <*>{TEXTT} { // found normal or special comment after something
1482 QCString text(vhdlcodeYYtext);
1483 int i=text.find("--");
1484 if (text.mid(i,3)=="--!" &&
1485 Config_getBool(STRIP_CODE_COMMENTS))
1487 // hide special comment
1489 else // normal comment
1491 // startFontClass("keyword");
1492 codifyLines(text,0,FALSE,TRUE);
1500 /*@ ----------------------------------------------------------------------------
1503 void resetVhdlCodeParserState()
1505 g_vhdlKeyDict.setAutoDelete(TRUE);
1506 g_vhdlKeyDict.clear();
1509 void parseVhdlCode(CodeOutputInterface &od,const char *className,const QCString &s,
1510 bool exBlock, const char *exName,FileDef *fd,
1511 int startLine,int endLine,bool inlineFragment,
1512 MemberDef *memberDef,bool,Definition *searchCtx,
1513 bool /* collectXRefs */)
1515 //printf("***parseCode() exBlock=%d exName=%s fd=%p\n",exBlock,exName,fd);
1516 if (s.isEmpty()) return;
1517 printlex(yy_flex_debug, TRUE, __FILE__, fd ? fd->fileName().data(): NULL);
1518 TooltipManager::instance()->clearTooltips();
1521 ClassDef *dd=memberDef->getClassDef();
1522 if (dd) g_CurrClass=dd->name();
1525 resetVhdlCodeParserState();
1528 g_inputPosition = 0;
1529 g_currentFontClass = 0;
1530 g_needsTermination = FALSE;
1531 g_searchCtx = searchCtx;
1534 g_yyLineNr = startLine;
1539 g_inputLines = endLine+1;
1541 g_inputLines = g_yyLineNr + countLines() - 1;
1544 // g_theCallContext.clear();
1545 g_classScope = className;
1546 g_exampleBlock = exBlock;
1547 g_exampleName = exName;
1548 g_sourceFileDef = fd;
1549 bool cleanupSourceDef = FALSE;
1550 if (exBlock && fd==0)
1552 // create a dummy filedef for the example
1553 g_sourceFileDef = new FileDef("",exName);
1554 cleanupSourceDef = TRUE;
1556 if (g_sourceFileDef)
1558 setCurrentDoc("l00001");
1560 g_currentDefinition = 0;
1561 g_currentMemberDef = 0;
1563 if (!g_exampleName.isEmpty())
1565 g_exampleFile = convertNameToFile(g_exampleName+"-example");
1567 g_includeCodeFragment = inlineFragment;
1572 // g_type.resize(0);
1573 // g_name.resize(0);
1574 // g_args.resize(0);
1575 g_parmName.resize(0);
1576 g_parmType.resize(0);
1581 setParameterList(memberDef);
1583 /*int iLine=*/countLines();
1584 vhdlcodeYYrestart( vhdlcodeYYin );
1588 if (g_needsTermination)
1594 TooltipManager::instance()->writeTooltips(*g_code);
1596 if (cleanupSourceDef)
1598 // delete the temporary file definition used for this example
1599 delete g_sourceFileDef;
1603 printlex(yy_flex_debug, FALSE, __FILE__, fd ? fd->fileName().data(): NULL);
1606 void codeFreeVhdlScanner()
1608 #if defined(YY_FLEX_SUBMINOR_VERSION)
1611 vhdlcodeYYlex_destroy();
1616 #if !defined(YY_FLEX_SUBMINOR_VERSION)
1617 extern "C" { // some bogus code to keep the compiler happy
1618 void vhdlcodeYYdummy() { yy_flex_realloc(0,0); }
1620 #elif YY_FLEX_MAJOR_VERSION<=2 && YY_FLEX_MINOR_VERSION<=5 && YY_FLEX_SUBMINOR_VERSION<33
1621 #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!"