diff options
author | Dimitri van Heesch <doxygen@gmail.com> | 2020-01-03 09:36:17 (GMT) |
---|---|---|
committer | Dimitri van Heesch <doxygen@gmail.com> | 2020-01-03 09:36:17 (GMT) |
commit | 5b9bf6e3549ac9011f607cc50e764da6af347689 (patch) | |
tree | dd3dc39e4a58b02a9f75b66b1b25401c40fd5c49 /src | |
parent | 76613eb3154778cc1b34efc338cc2ba05e88b645 (diff) | |
download | Doxygen-5b9bf6e3549ac9011f607cc50e764da6af347689.zip Doxygen-5b9bf6e3549ac9011f607cc50e764da6af347689.tar.gz Doxygen-5b9bf6e3549ac9011f607cc50e764da6af347689.tar.bz2 |
Make VHDL parser reentrant
Diffstat (limited to 'src')
-rw-r--r-- | src/entry.h | 2 | ||||
-rw-r--r-- | src/fortranscanner.l | 2 | ||||
-rw-r--r-- | src/vhdldocgen.cpp | 37 | ||||
-rw-r--r-- | src/vhdldocgen.h | 27 | ||||
-rw-r--r-- | src/vhdljjparser.cpp | 585 | ||||
-rw-r--r-- | src/vhdljjparser.h | 74 |
6 files changed, 350 insertions, 377 deletions
diff --git a/src/entry.h b/src/entry.h index 0391075..802a212 100644 --- a/src/entry.h +++ b/src/entry.h @@ -337,4 +337,6 @@ class Entry FileDef *m_fileDef; }; +typedef std::vector< std::shared_ptr<Entry> > EntryList; + #endif diff --git a/src/fortranscanner.l b/src/fortranscanner.l index 18cfdcb..d0ca22d 100644 --- a/src/fortranscanner.l +++ b/src/fortranscanner.l @@ -143,8 +143,6 @@ struct CommentInPrepass CommentInPrepass(int column, QCString str) : column(column), str(str) {} }; -typedef std::vector< std::shared_ptr<Entry> > EntryList; - /* ----------------------------------------------------------------- * * statics diff --git a/src/vhdldocgen.cpp b/src/vhdldocgen.cpp index 3c30174..4619b7a 100644 --- a/src/vhdldocgen.cpp +++ b/src/vhdldocgen.cpp @@ -2727,29 +2727,7 @@ void assignBinding(VhdlConfNode * conf) entBind=conf->binding; QCString conf2=VhdlDocGen::parseForBinding(entBind,arcBind); - if (qstricmp(conf2,"configuration")==0) - { - QList<VhdlConfNode> confList = getVhdlConfiguration(); - VhdlConfNode* vconf; - // bool found=false; - for (uint iter=0;iter<confList.count(); iter++) - { - vconf= (VhdlConfNode *)confList.at(iter); - QCString n=VhdlDocGen::getIndexWord(vconf->confVhdl.data(),0); - if (n==entBind) - { - // found=true; - entBind=VhdlDocGen::getIndexWord(vconf->confVhdl.data(),1); - QCString a=VhdlDocGen::getIndexWord(conf->compSpec.data(),0); - QCString e=VhdlDocGen::getIndexWord(conf->confVhdl.data(),1); - a=e+"::"+a; - archClass= VhdlDocGen::findVhdlClass(a.data());//Doxygen::classSDict->find(a.data()); - entClass= VhdlDocGen::findVhdlClass(e.data());//Doxygen::classSDict->find(e.data()); - break; - } - } - } - else // conf2!=configuration + if (conf2!="configuration") { QCString a,c,e; if (conf->isInlineConf) @@ -2852,17 +2830,6 @@ void VhdlDocGen::computeVhdlComponentRelations() { QCString entity,arch,inst; - QList<VhdlConfNode> confList = getVhdlConfiguration(); - - for (uint iter=0;iter<confList.count(); iter++) - { - VhdlConfNode* conf= (VhdlConfNode *)confList.at(iter); - if (!(conf->isInlineConf || conf->isLeaf)) - { - continue; - } - assignBinding(conf); - } for (const auto &cur : getVhdlInstList()) { @@ -3630,7 +3597,7 @@ void FlowChart::addFlowChart(int type,const char* text,const char* exp, const ch FlowChart *fl=new FlowChart(type,typeString.data(),expression.data(),label); - fl->line=vhdl::parser::VhdlParser::getLine(); + fl->line=1; // TODO: use getLine(); of the parser if (type & (START_NO | VARIABLE_NO)) { diff --git a/src/vhdldocgen.h b/src/vhdldocgen.h index 6203196..a557c27 100644 --- a/src/vhdldocgen.h +++ b/src/vhdldocgen.h @@ -39,6 +39,33 @@ class FileDef; class NamespaceDef; struct Argument; + + +struct VhdlConfNode +{ + VhdlConfNode(const char* a,const char* b,const char* config,const char* cs,bool leaf) + { + arch=a; // architecture e.g. for iobuffer + arch=arch.lower(); + binding=b; // binding e.g. use entity work.xxx(bev) + binding=binding.lower(); + confVhdl=config; // configuration foo is bar + compSpec=cs; + isInlineConf=false; // primary configuration? + isLeaf=leaf; + }; + + QCString confVhdl; + QCString arch; + QCString binding; + QCString compSpec; + int level = 0; + bool isLeaf = false; + bool isInlineConf = false; + +}; + + /** Class for generating documentation specific for VHDL */ class VhdlDocGen { diff --git a/src/vhdljjparser.cpp b/src/vhdljjparser.cpp index c79bb5c..a7bac68 100644 --- a/src/vhdljjparser.cpp +++ b/src/vhdljjparser.cpp @@ -28,207 +28,213 @@ #include "outputlist.h" #include "arguments.h" #include "types.h" -#include "VhdlParserIF.h" #include "growbuf.h" #include "markdown.h" +#include "VhdlParserTokenManager.h" +#include "VhdlParserErrorHandler.hpp" using namespace vhdl::parser; -using namespace std; - -static OutlineParserInterface *g_thisParser; -static CommentScanner g_commentScanner; - -static QCString yyFileName; -static int yyLineNr = 1; -static int* lineParse; -static int iDocLine = -1; -static QCString inputString; -static Entry* gBlock = 0; -static Entry* previous = 0; -//------------------------------------------------------- - -static Entry* oldEntry; -static bool varr=FALSE; -static QCString varName; - -static std::vector< std::shared_ptr<Entry> > instFiles; -static std::vector< std::shared_ptr<Entry> > libUse; -static std::vector<Entry*> lineEntry; - -Entry* VhdlParser::tempEntry=0; -Entry* VhdlParser::lastEntity=0 ; -Entry* VhdlParser::lastCompound=0 ; -Entry* VhdlParser::current_root = 0; -std::shared_ptr<Entry> VhdlParser::current=0; -QCString VhdlParser::compSpec; -QCString VhdlParser::currName; -QCString VhdlParser::confName; -QCString VhdlParser::genLabels; -QCString VhdlParser::lab; -QCString VhdlParser::forL; -int VhdlParser::param_sec = 0; -int VhdlParser::parse_sec=0; -int VhdlParser::currP=0; -int VhdlParser::levelCounter; - -static QList<VhdlConfNode> configL; - -static struct +struct VHDLDocInfo { QCString doc; bool brief; - bool pending; - int iDocLine; -} str_doc; + bool pending = false; + int iDocLine = 1; +}; -static QCString strComment; -static int iCodeLen; -static const char *vhdlFileName = 0; -static bool checkMultiComment(QCString& qcs,int line); -static void insertEntryAtLine(const Entry* ce,int line); +static bool isConstraintFile(const QCString &fileName,const QCString &ext) +{ + return fileName.right(ext.length())==ext; +} + //------------------------------------- -const QList<VhdlConfNode>& getVhdlConfiguration() { return configL; } -const std::vector<std::shared_ptr<Entry> > &getVhdlInstList() { return instFiles; } +static EntryList g_instFiles; -Entry* getVhdlCompound() +struct VHDLOutlineParser::Private { - if (VhdlParser::lastEntity) return VhdlParser::lastEntity; - if (VhdlParser::lastCompound) return VhdlParser::lastCompound; - return NULL; + void parseVhdlfile(const char *fileName,const char* inputBuffer,bool inLine); + + VHDLOutlineParser *thisParser = 0; + VhdlParser *vhdlParser = 0; + CommentScanner commentScanner; + + QCString yyFileName; + int yyLineNr = 1; + std::vector<int> lineParse; + int iDocLine = -1; + QCString inputString; + Entry* gBlock = 0; + Entry* previous = 0; +//------------------------------------------------------- + + Entry* oldEntry = 0; + bool varr = FALSE; + QCString varName; + EntryList libUse; + EntryList lineEntry; + QCString strComment; + int iCodeLen; + VHDLDocInfo str_doc; + VhdlParser::SharedState shared; + QCString forL; + +}; + +void VHDLOutlineParser::Private::parseVhdlfile(const char *fileName, + const char* inputBuffer,bool inLine) +{ + JAVACC_STRING_TYPE s =inputBuffer; + CharStream *stream = new CharStream(s.c_str(), (int)s.size(), 1, 1); + VhdlParserTokenManager *tokenManager = new VhdlParserTokenManager(stream); + VhdlTokenManagerErrorHandler *tokErrHandler=new VhdlTokenManagerErrorHandler(fileName); + vhdlParser=new VhdlParser(tokenManager); + vhdlParser->setOutlineParser(thisParser); + vhdlParser->setSharedState(&shared); + tokenManager->ReInit(stream,0,vhdlParser); + tokenManager->setErrorHandler(tokErrHandler); + VhdlErrorHandler *parserErrHandler=new VhdlErrorHandler(fileName); + vhdlParser->setErrorHandler(parserErrHandler); + try + { + if(inLine) + { + vhdlParser->parseInline(); + } + else + { + vhdlParser->design_file(); + } + } + catch( std::exception &){ /* fprintf(stderr,"\n[%s]",e.what()); */ } + // fprintf(stderr,"\n\nparsed lines: %d\n",yyLineNr); + // fprintf(stderr,"\n\nerrors : %d\n\n",myErr->getErrorCount()); + delete vhdlParser; } -bool isConstraintFile(const QCString &fileName,const QCString &ext) +VHDLOutlineParser::VHDLOutlineParser() : p(std::make_unique<Private>()) { - return fileName.right(ext.length())==ext; } +VHDLOutlineParser::~VHDLOutlineParser() +{ +} void VHDLOutlineParser::parseInput(const char *fileName,const char *fileBuf, - const std::shared_ptr<Entry> &root, bool ,QStrList&) + const std::shared_ptr<Entry> &root, bool ,QStrList&) { - g_thisParser=this; - bool inLine=false; - inputString=fileBuf; + VhdlParser::SharedState *s = &p->shared; + p->thisParser=this; + p->inputString=fileBuf; // fprintf(stderr,"\n ============= %s\n ==========\n",fileBuf); - if (strlen(fileName)==0) - { - inLine=true; - } + bool inLine = (fileName==0 || strlen(fileName)==0); - yyFileName+=fileName; + p->yyFileName=fileName; - bool xilinx_ucf=isConstraintFile(yyFileName,".ucf"); - bool altera_qsf=isConstraintFile(yyFileName,".qsf"); + bool xilinx_ucf=isConstraintFile(p->yyFileName,".ucf"); + bool altera_qsf=isConstraintFile(p->yyFileName,".qsf"); // support XILINX(ucf) and ALTERA (qsf) file if (xilinx_ucf) { - VhdlDocGen::parseUCF(fileBuf,root.get(),yyFileName,FALSE); + VhdlDocGen::parseUCF(fileBuf,root.get(),p->yyFileName,FALSE); return; } if (altera_qsf) { - VhdlDocGen::parseUCF(fileBuf,root.get(),yyFileName,TRUE); + VhdlDocGen::parseUCF(fileBuf,root.get(),p->yyFileName,TRUE); return; } - yyLineNr=1; - VhdlParser::current_root=root.get(); - VhdlParser::lastCompound=0; - VhdlParser::lastEntity=0; - VhdlParser::lastEntity=0; - oldEntry = 0; - VhdlParser::current=std::make_shared<Entry>(); - VhdlParser::initEntry(VhdlParser::current.get()); - Doxygen::docGroup.enterFile(fileName,yyLineNr); - vhdlFileName = fileName; - lineParse=new int[200]; // Dimitri: dangerous constant: should be bigger than largest token id in VhdlParserConstants.h - VhdlParserIF::parseVhdlfile(fileBuf,inLine); - - VhdlParser::current.reset(); + p->yyLineNr=1; + s->current_root=root; + s->lastCompound=0; + s->lastEntity=0; + s->lastEntity=0; + p->oldEntry = 0; + s->current=std::make_shared<Entry>(); + initEntry(s->current.get()); + Doxygen::docGroup.enterFile(fileName,p->yyLineNr); + p->lineParse.reserve(200); + p->parseVhdlfile(fileName,fileBuf,inLine); + + s->current.reset(); if (!inLine) - VhdlParser::mapLibPackage(root.get()); + mapLibPackage(root.get()); - delete[] lineParse; - yyFileName.resize(0); - libUse.clear(); - VhdlDocGen::resetCodeVhdlParserState(); - vhdlFileName = 0; + p->yyFileName.resize(0); + p->libUse.clear(); } -void VhdlParser::lineCount() +void VHDLOutlineParser::lineCount() { - yyLineNr++; + p->yyLineNr++; } -void VhdlParser::lineCount(const char* text) +void VHDLOutlineParser::lineCount(const char* text) { for (const char* c=text ; *c ; ++c ) { - if (*c == '\n') yyLineNr++; + if (*c == '\n') p->yyLineNr++; } } -void isVhdlDocPending() -{ - if (!str_doc.pending) return; - - str_doc.pending=FALSE; - oldEntry=0; // prevents endless recursion - iDocLine=str_doc.iDocLine; - VhdlParser::handleCommentBlock(str_doc.doc,str_doc.brief); - iDocLine=-1; -} - -void VhdlParser::initEntry(Entry *e) +void VHDLOutlineParser::initEntry(Entry *e) { - e->fileName = yyFileName; + e->fileName = p->yyFileName; e->lang = SrcLangExt_VHDL; - isVhdlDocPending(); + if (p->str_doc.pending) + { + p->str_doc.pending=FALSE; + p->oldEntry=0; // prevents endless recursion + p->iDocLine=p->str_doc.iDocLine; + handleCommentBlock(p->str_doc.doc,p->str_doc.brief); + p->iDocLine=-1; + } Doxygen::docGroup.initGroupInfo(e); } -void VhdlParser::newEntry() +void VHDLOutlineParser::newEntry() { - previous = current.get(); - if (current->spec==VhdlDocGen::ENTITY || - current->spec==VhdlDocGen::PACKAGE || - current->spec==VhdlDocGen::ARCHITECTURE || - current->spec==VhdlDocGen::PACKAGE_BODY) + VhdlParser::SharedState *s = &p->shared; + p->previous = s->current.get(); + if (s->current->spec==VhdlDocGen::ENTITY || + s->current->spec==VhdlDocGen::PACKAGE || + s->current->spec==VhdlDocGen::ARCHITECTURE || + s->current->spec==VhdlDocGen::PACKAGE_BODY) { - current_root->moveToSubEntryAndRefresh(current); + s->current_root->moveToSubEntryAndRefresh(s->current); } else { - if (lastCompound) + if (s->lastCompound) { - lastCompound->moveToSubEntryAndRefresh(current); + s->lastCompound->moveToSubEntryAndRefresh(s->current); } else { - if (lastEntity) + if (s->lastEntity) { - lastEntity->moveToSubEntryAndRefresh(current); + s->lastEntity->moveToSubEntryAndRefresh(s->current); } else { - current_root->moveToSubEntryAndRefresh(current); + s->current_root->moveToSubEntryAndRefresh(s->current); } } } - initEntry(current.get()); + initEntry(s->current.get()); } -void VhdlParser::handleFlowComment(const char* doc) +void VHDLOutlineParser::handleFlowComment(const char* doc) { - lineCount(doc); + lineCount(doc); if (VhdlDocGen::getFlowMember()) { @@ -240,16 +246,16 @@ void VhdlParser::handleFlowComment(const char* doc) } -void VhdlParser::handleCommentBlock(const char* doc1,bool brief) +void VHDLOutlineParser::handleCommentBlock(const char* doc1,bool brief) { - QCString doc; - doc.append(doc1); + VhdlParser::SharedState *s = &p->shared; + QCString doc = doc1; // fprintf(stderr,"\n %s",doc.data()); if (doc.isEmpty()) return; - if (checkMultiComment(doc,yyLineNr)) + if (checkMultiComment(doc,p->yyLineNr)) { - strComment.resize(0); + p->strComment.resize(0); return; } @@ -257,44 +263,44 @@ void VhdlParser::handleCommentBlock(const char* doc1,bool brief) Protection protection=Public; - if (oldEntry==current.get()) + if (p->oldEntry==s->current.get()) { //printf("\n find pending message < %s > at line: %d \n ",doc.data(),iDocLine); - str_doc.doc=doc; - str_doc.iDocLine=iDocLine; - str_doc.brief=brief; - str_doc.pending=TRUE; + p->str_doc.doc=doc; + p->str_doc.iDocLine=p->iDocLine; + p->str_doc.brief=brief; + p->str_doc.pending=TRUE; return; } - oldEntry=current.get(); + p->oldEntry=s->current.get(); if (brief) { - current->briefLine = yyLineNr; + s->current->briefLine = p->yyLineNr; } else { - current->docLine = yyLineNr; + s->current->docLine = p->yyLineNr; } - // printf("parseCommentBlock file<%s>\n [%s]\n at line [%d] \n ",yyFileName.data(),doc.data(),iDocLine); + // printf("parseCommentBlock file<%s>\n [%s]\n at line [%d] \n ",yyFileName.data(),doc.data(),p->iDocLine); int j=doc.find("[plant]"); if (j>=0) { doc=doc.remove(j,7); - current->stat=true; + s->current->stat=true; } int position=0; bool needsEntry=FALSE; - QCString processedDoc = processMarkdownForCommentBlock(doc,yyFileName,iDocLine); - while (g_commentScanner.parseCommentBlock( - g_thisParser, - current.get(), + QCString processedDoc = processMarkdownForCommentBlock(doc,p->yyFileName,p->iDocLine); + while (p->commentScanner.parseCommentBlock( + p->thisParser, + s->current.get(), processedDoc, // text - yyFileName, // file - iDocLine, // line of block start + p->yyFileName, // file + p->iDocLine, // line of block start brief, 0, FALSE, @@ -309,57 +315,60 @@ void VhdlParser::handleCommentBlock(const char* doc1,bool brief) } if (needsEntry) { - if (varr) + if (p->varr) { - varr=FALSE; - current->name=varName; - current->section=Entry::VARIABLEDOC_SEC; - varName=""; + p->varr=FALSE; + s->current->name=p->varName; + s->current->section=Entry::VARIABLEDOC_SEC; + p->varName=""; } newEntry(); } - iDocLine=-1; - strComment.resize(0); + p->iDocLine=-1; + p->strComment.resize(0); } void VHDLOutlineParser::parsePrototype(const char *text) { - varName=text; - varr=TRUE; + p->varName=text; + p->varr=TRUE; } -void VhdlParser::addCompInst(const char *n, const char* instName, const char* comp,int iLine) +void VHDLOutlineParser::addCompInst(const char *n, const char* instName, const char* comp,int iLine) { - current->spec=VhdlDocGen::INSTANTIATION; - current->section=Entry::VARIABLE_SEC; - current->startLine=iLine; - current->bodyLine=iLine; - current->type=instName; // foo:instname e.g proto or work. proto(ttt) - current->exception=genLabels.lower(); // |arch|label1:label2... - current->name=n; // foo - if (lastCompound) + VhdlParser::SharedState *s = &p->shared; + s->current->spec=VhdlDocGen::INSTANTIATION; + s->current->section=Entry::VARIABLE_SEC; + s->current->startLine=iLine; + s->current->bodyLine=iLine; + s->current->type=instName; // foo:instname e.g proto or work. proto(ttt) + s->current->exception=s->genLabels.lower(); // |arch|label1:label2... + s->current->name=n; // foo + if (s->lastCompound) { - current->args=lastCompound->name; // architecture name + s->current->args=s->lastCompound->name; // architecture name } - current->includeName=comp; // component/entity/configuration - int u=genLabels.find("|",1); + s->current->includeName=comp; // component/entity/configuration + int u=s->genLabels.find("|",1); if (u>0) { - current->write=genLabels.right(genLabels.length()-u); - current->read=genLabels.left(u); + s->current->write=s->genLabels.right(s->genLabels.length()-u); + s->current->read=s->genLabels.left(u); } //printf (" \n genlabel: [%s] inst: [%s] name: [%s] %d\n",n,instName,comp,iLine); - if (lastCompound) + if (s->lastCompound) { - current->args=lastCompound->name; + s->current->args=s->lastCompound->name; if (true) // !findInstant(current->type)) { - initEntry(current.get()); - instFiles.emplace_back(std::make_shared<Entry>(*current)); + initEntry(s->current.get()); + // TODO: protect with mutex + g_instFiles.emplace_back(std::make_shared<Entry>(*s->current)); + // TODO: end protect with mutex } - current=std::make_shared<Entry>(); + s->current=std::make_shared<Entry>(); } else { @@ -367,13 +376,14 @@ void VhdlParser::addCompInst(const char *n, const char* instName, const char* co } } -void VhdlParser::addVhdlType(const char *n,int startLine,int section, +void VHDLOutlineParser::addVhdlType(const char *n,int startLine,int section, uint64 spec,const char* args,const char* type,Protection prot) { + VhdlParser::SharedState *s = &p->shared; QCString name(n); if (isFuncProcProced() || VhdlDocGen::getFlowMember()) return; - if (parse_sec==GEN_SEC) + if (s->parse_sec==GEN_SEC) { spec= VhdlDocGen::GENERIC; } @@ -382,61 +392,62 @@ void VhdlParser::addVhdlType(const char *n,int startLine,int section, for (uint u=0;u<ql.count();u++) { - current->name=ql[u]; - current->startLine=startLine; - current->bodyLine=startLine; - current->section=section; - current->spec=spec; - current->fileName=yyFileName; - if (current->args.isEmpty()) + s->current->name=ql[u]; + s->current->startLine=startLine; + s->current->bodyLine=startLine; + s->current->section=section; + s->current->spec=spec; + s->current->fileName=p->yyFileName; + if (s->current->args.isEmpty()) { - current->args=args; + s->current->args=args; } - current->type=type; - current->protection=prot; + s->current->type=type; + s->current->protection=prot; - if (!lastCompound && (section==Entry::VARIABLE_SEC) && (spec == VhdlDocGen::USE || spec == VhdlDocGen::LIBRARY) ) + if (!s->lastCompound && (section==Entry::VARIABLE_SEC) && (spec == VhdlDocGen::USE || spec == VhdlDocGen::LIBRARY) ) { - libUse.emplace_back(std::make_shared<Entry>(*current)); - current->reset(); + p->libUse.emplace_back(std::make_shared<Entry>(*s->current)); + s->current->reset(); } newEntry(); } } -void VhdlParser::createFunction(const char *imp,uint64 spec,const char *fn) +void VHDLOutlineParser::createFunction(const char *imp,uint64 spec,const char *fn) { + VhdlParser::SharedState *s = &p->shared; QCString impure(imp); QCString fname(fn); - current->spec=spec; - current->section=Entry::FUNCTION_SEC; + s->current->spec=spec; + s->current->section=Entry::FUNCTION_SEC; if (impure=="impure" || impure=="pure") { - current->exception=impure; + s->current->exception=impure; } - if (parse_sec==GEN_SEC) + if (s->parse_sec==GEN_SEC) { - current->spec= VhdlDocGen::GENERIC; - current->section=Entry::FUNCTION_SEC; + s->current->spec= VhdlDocGen::GENERIC; + s->current->section=Entry::FUNCTION_SEC; } - if (currP==VhdlDocGen::PROCEDURE) + if (s->currP==VhdlDocGen::PROCEDURE) { - current->name=impure; - current->exception=""; + s->current->name=impure; + s->current->exception=""; } else { - current->name=fname; + s->current->name=fname; } if (spec==VhdlDocGen::PROCESS) { - current->args=fname; - current->name=impure; - VhdlDocGen::deleteAllChars(current->args,' '); + s->current->args=fname; + s->current->name=impure; + VhdlDocGen::deleteAllChars(s->current->args,' '); if (!fname.isEmpty()) { QCStringList q1=QCStringList::split(",",fname); @@ -444,19 +455,19 @@ void VhdlParser::createFunction(const char *imp,uint64 spec,const char *fn) { Argument arg; arg.name=q1[ii]; - current->argList.push_back(arg); + s->current->argList.push_back(arg); } } - return; } - } +} -bool VhdlParser::isFuncProcProced() +bool VHDLOutlineParser::isFuncProcProced() { - if (currP==VhdlDocGen::FUNCTION || - currP==VhdlDocGen::PROCEDURE || - currP==VhdlDocGen::PROCESS + VhdlParser::SharedState *s = &p->shared; + if (s->currP==VhdlDocGen::FUNCTION || + s->currP==VhdlDocGen::PROCEDURE || + s->currP==VhdlDocGen::PROCESS ) { return TRUE; @@ -464,13 +475,13 @@ bool VhdlParser::isFuncProcProced() return FALSE; } -void VhdlParser::pushLabel( QCString &label,QCString & val) +void VHDLOutlineParser::pushLabel( QCString &label,QCString & val) { label+="|"; label+=val; } - QCString VhdlParser::popLabel(QCString & q) +QCString VHDLOutlineParser::popLabel(QCString & q) { int i=q.findRev("|"); if (i<0) return ""; @@ -478,63 +489,12 @@ void VhdlParser::pushLabel( QCString &label,QCString & val) return q; } -void VhdlParser::addConfigureNode(const char* a,const char*b, bool,bool isLeaf,bool inlineConf) -{ - VhdlConfNode* co=0; - QCString ent; - ent=a; - - if (b) - { - ent=b; - } - int level=0; - - if (!configL.isEmpty()) - { - VhdlConfNode* vc=configL.getLast(); - level=vc->level; - if (levelCounter==0) - { - pushLabel(forL,ent); - } - else if (level<levelCounter) - { - if (!isLeaf) - { - pushLabel(forL,ent); - } - } - else if (level>levelCounter) - { - forL=popLabel(forL); - } - } - else - { - pushLabel(forL,ent); - } - - if (inlineConf) - { - confName=lastCompound->name; - } - - //fprintf(stderr,"\n[%s %d %d]\n",forL.data(),levelCounter,level); - co=new VhdlConfNode(a,b,confName.lower().data(),forL.lower().data(),isLeaf); - - if (inlineConf) - { - co->isInlineConf=TRUE; - } - - configL.append(co); -} -void VhdlParser::addProto(const char *s1,const char *s2,const char *s3, +void VHDLOutlineParser::addProto(const char *s1,const char *s2,const char *s3, const char *s4,const char *s5,const char *s6) { + VhdlParser::SharedState *s = &p->shared; (void)s5; // avoid unused warning QCString name=s2; QCStringList ql=QCStringList::split(",",name); @@ -553,12 +513,12 @@ void VhdlParser::addProto(const char *s1,const char *s2,const char *s3, { arg.type+=s6; } - if (parse_sec==GEN_SEC && param_sec==0) + if (s->parse_sec==GEN_SEC && s->param_sec==0) { arg.defval="gen!"; } - if (parse_sec==PARAM_SEC) + if (s->parse_sec==PARAM_SEC) { // assert(false); } @@ -566,9 +526,9 @@ void VhdlParser::addProto(const char *s1,const char *s2,const char *s3, arg.defval+=s1; arg.attrib="";//s6; - current->argList.push_back(arg); - current->args+=s2; - current->args+=","; + s->current->argList.push_back(arg); + s->current->args+=s2; + s->current->args+=","; } } @@ -584,13 +544,13 @@ void VhdlParser::addProto(const char *s1,const char *s2,const char *s3, * ..... * and so on.. */ -void VhdlParser::mapLibPackage( Entry* root) +void VHDLOutlineParser::mapLibPackage( Entry* root) { //QList<Entry> epp=libUse; //EntryListIterator eli(epp); //Entry *rt; //for (;(rt=eli.current());++eli) - for (const auto &rt : libUse) + for (const auto &rt : p->libUse) { if (addLibUseClause(rt->name)) { @@ -615,7 +575,7 @@ void VhdlParser::mapLibPackage( Entry* root) }// for }//MapLib -bool VhdlParser::addLibUseClause(const QCString &type) +bool VHDLOutlineParser::addLibUseClause(const QCString &type) { static bool showIEEESTD=Config_getBool(FORCE_LOCAL_INCLUDES); @@ -627,48 +587,50 @@ bool VhdlParser::addLibUseClause(const QCString &type) return TRUE; } -int VhdlParser::getLine() +int VHDLOutlineParser::getLine() { - return yyLineNr; + return p->yyLineNr; } -void VhdlParser::setLineParsed(int tok) +void VHDLOutlineParser::setLineParsed(int tok) { - lineParse[tok]=yyLineNr; + p->lineParse.reserve(tok+1); + p->lineParse[tok]=p->yyLineNr; } -int VhdlParser::getLine(int tok) +int VHDLOutlineParser::getLine(int tok) { - int val=lineParse[tok]; + int val=p->lineParse[tok]; if (val<0) val=0; //assert(val>=0 && val<=yyLineNr); return val; } -void VhdlParser::createFlow() +void VHDLOutlineParser::createFlow() { + VhdlParser::SharedState *s = &p->shared; if (!VhdlDocGen::getFlowMember()) { return; } QCString q,ret; - if (currP==VhdlDocGen::FUNCTION) + if (s->currP==VhdlDocGen::FUNCTION) { q=":function( "; - FlowChart::alignFuncProc(q,tempEntry->argList,true); + FlowChart::alignFuncProc(q,s->tempEntry->argList,true); q+=")"; } - else if (currP==VhdlDocGen::PROCEDURE) + else if (s->currP==VhdlDocGen::PROCEDURE) { q=":procedure ("; - FlowChart::alignFuncProc(q,tempEntry->argList,false); + FlowChart::alignFuncProc(q,s->tempEntry->argList,false); q+=")"; } else { - q=":process( "+tempEntry->args; + q=":process( "+s->tempEntry->args; q+=")"; } @@ -676,11 +638,11 @@ void VhdlParser::createFlow() FlowChart::addFlowChart(FlowChart::START_NO,q,0); - if (currP==VhdlDocGen::FUNCTION) + if (s->currP==VhdlDocGen::FUNCTION) { ret="end function "; } - else if (currP==VhdlDocGen::PROCEDURE) + else if (s->currP==VhdlDocGen::PROCEDURE) { ret="end procedure"; } @@ -692,60 +654,79 @@ void VhdlParser::createFlow() FlowChart::addFlowChart(FlowChart::END_NO,ret,0); // FlowChart::printFlowList(); FlowChart::writeFlowChart(); - currP=0; + s->currP=0; } -void VhdlParser::setMultCommentLine() +void VHDLOutlineParser::setMultCommentLine() { - iDocLine=yyLineNr; + p->iDocLine=p->yyLineNr; } -void VhdlParser::oneLineComment(QCString qcs) +void VHDLOutlineParser::oneLineComment(QCString qcs) { int j=qcs.find("--!"); qcs=qcs.right(qcs.length()-3-j); - if (!checkMultiComment(qcs,iDocLine)) + if (!checkMultiComment(qcs,p->iDocLine)) { handleCommentBlock(qcs,TRUE); } } -bool checkMultiComment(QCString& qcs,int line) +bool VHDLOutlineParser::checkMultiComment(QCString& qcs,int line) { - insertEntryAtLine(VhdlParser::current_root,line); + VhdlParser::SharedState *s = &p->shared; + insertEntryAtLine(s->current_root,line); - if (lineEntry.empty()) return false; + if (p->lineEntry.empty()) return false; VhdlDocGen::prepareComment(qcs); - while (!lineEntry.empty()) + while (!p->lineEntry.empty()) { - Entry *e=lineEntry.back(); + std::shared_ptr<Entry> e=p->lineEntry.back(); e->briefLine=line; e->brief+=qcs; - lineEntry.pop_back(); + p->lineEntry.pop_back(); } return true; } // returns the vhdl parsed types at line xxx -void insertEntryAtLine(const Entry* ce,int line) +void VHDLOutlineParser::insertEntryAtLine(std::shared_ptr<Entry> ce,int line) { for (const auto &rt : ce->children()) { if (rt->bodyLine==line) { - lineEntry.push_back(rt.get()); + p->lineEntry.push_back(rt); } - insertEntryAtLine(rt.get(),line); + insertEntryAtLine(rt,line); } } -const char *getVhdlFileName(void) +const EntryList &getVhdlInstList() { - return vhdlFileName; + return g_instFiles; +} + +void VHDLOutlineParser::error_skipto(int kind) +{ + Token *op; + do + { + Token *t = p->vhdlParser->getNextToken();// step to next token + op=p->vhdlParser->getToken(1); // get first token + if (op==0) break; + //fprintf(stderr,"\n %s",t->image.data()); + } while (op->kind != kind); + p->vhdlParser->clearError(); + // The above loop consumes tokens all the way up to a token of + // "kind". We use a do-while loop rather than a while because the + // current token is the one immediately before the erroneous token + // (in our case the token immediately before what should have been + // "if"/"while". } QCString filter2008VhdlComment(const char *s) diff --git a/src/vhdljjparser.h b/src/vhdljjparser.h index f3e7d70..9e93e0d 100644 --- a/src/vhdljjparser.h +++ b/src/vhdljjparser.h @@ -19,21 +19,10 @@ #include "entry.h" #include "vhdldocgen.h" #include "vhdlcode.h" -#include "memberlist.h" #include "config.h" - - - enum { GEN_SEC=0x1, PARAM_SEC,CONTEXT_SEC,PROTECTED_SEC } ; -void parserVhdlfile(const char* inputBuffer); - -class Entry; -class ClassSDict; -class ClassDef; -class MemberDef; -struct VhdlConfNode; - +//void parserVhdlfile(const char* inputBuffer); /** \brief VHDL parser using state-based lexical scanning. * @@ -42,7 +31,8 @@ struct VhdlConfNode; class VHDLOutlineParser : public OutlineParserInterface { public: - virtual ~VHDLOutlineParser() {} + VHDLOutlineParser(); + virtual ~VHDLOutlineParser(); void startTranslationUnit(const char *) {} void finishTranslationUnit() {} void parseInput(const char * fileName, @@ -53,35 +43,43 @@ class VHDLOutlineParser : public OutlineParserInterface bool needsPreprocessing(const QCString &) const { return TRUE; } void parsePrototype(const char *text); -}; -struct VhdlConfNode -{ - VhdlConfNode(const char* a,const char* b,const char* config,const char* cs,bool leaf) - { - arch=a; // architecture e.g. for iobuffer - arch=arch.lower(); - binding=b; // binding e.g. use entity work.xxx(bev) - binding=binding.lower(); - confVhdl=config; // configuration foo is bar - compSpec=cs; - isInlineConf=false; // primary configuration? - isLeaf=leaf; - }; - - QCString confVhdl; - QCString arch; - QCString binding; - QCString compSpec; - int level = 0; - bool isLeaf = false; - bool isInlineConf = false; + // interface for generated parser code + + void setLineParsed(int tok); + int getLine(int tok); + int getLine(); + void lineCount(const char*); + void lineCount(); + void addProto(const char *s1,const char *s2,const char *s3,const char *s4,const char *s5,const char *s6); + //void addConfigureNode(const char* a,const char*b, bool,bool isLeaf,bool inlineConf); + void createFunction(const char *impure,uint64 spec,const char *fname); + void addVhdlType(const char *n,int startLine,int section, uint64 spec,const char* args,const char* type,Protection prot); + void addCompInst(const char *n, const char* instName, const char* comp,int iLine); + void handleCommentBlock(const char* doc,bool brief); + void handleFlowComment(const char*); + void initEntry(Entry *e); + void newEntry(); + bool isFuncProcProced(); + void pushLabel(QCString &,QCString&); + QCString popLabel(QCString & q); + bool addLibUseClause(const QCString &type); + void mapLibPackage( Entry* root); + void createFlow(); + void error_skipto(int kind); + void oneLineComment(QCString qcs); + void setMultCommentLine(); + bool checkMultiComment(QCString& qcs,int line); + void insertEntryAtLine(std::shared_ptr<Entry> ce,int line); + + private: + struct Private; + std::unique_ptr<Private> p; }; -void vhdlscanFreeScanner(); +const EntryList &getVhdlInstList(); -const QList<VhdlConfNode>& getVhdlConfiguration(); -const std::vector<std::shared_ptr<Entry> >&getVhdlInstList(); QCString filter2008VhdlComment(const char *s); + #endif |