/* ------------------------------------------------------------------------ */ /* */ /* [stydoc.c] STYX Documentation Generator */ /* */ /* Copyright (c) 1999 by D\olle, Manns, Steffen */ /* ------------------------------------------------------------------------ */ #include "stdosx.h" #include "scn_base.h" #include "scn_pre.h" #include "prs.h" #include "ptm.h" #include "ptm_gen.h" #include "cfg_abs.h" #include "symbols.h" #include "hmap.h" #include "hset.h" #include "sink.h" #include "line_scn.h" #include "pathes.h" #include "hpat.h" #include "styx_int.h" #include "styx_lim.h" #include "styx_pim.h" #include "styd_cim.h" /* ------------------------- Macros, Types & Globals -------------------- */ #define infile CTX_EVAL(c_string,"InFile") #define outfile CTX_EVAL(c_string,"OutFile") #define styxpath CTX_EVAL(c_string,"StyxPath") #define template CTX_EVAL(c_string,"Template") #define refalias CTX_EVAL(c_string,"RefAlias") #define recursiv CTX_EVAL(c_bool,"recursiv") #define prodcom CTX_EVAL(c_bool,"prodcom") #define nts_to_keep CTX_EVAL(c_string,"keepNTs") #define cls_to_split CTX_EVAL(c_string,"noClass") #define excl_prods CTX_EVAL(c_string,"exProds") #define ign_rref CTX_EVAL(c_string,"ignRRef") #define binpath CTX_EVAL(string,"BINSTYX") /* STYX Documentation Pattern */ #define SD_PAT_CFGDFN stringToSymbol("cfgdfn") #define SD_PAT_COMSEC stringToSymbol("comsec") #define SD_PAT_TKMSEC stringToSymbol("tkmsec") #define SD_PAT_NTMSEC stringToSymbol("ntmsec") #define SD_PAT_PRDSEC stringToSymbol("prdsec") #define SD_PAT_MBRSEC stringToSymbol("mbrsec") #define SD_PAT_CFGID stringToSymbol("cfgid") #define SD_PAT_DFNID stringToSymbol("dfnid") #define SD_PAT_DFNREF stringToSymbol("dfnref") #define SD_PAT_LANREF stringToSymbol("lanref") #define SD_PAT_DFNCAT stringToSymbol("dfncat") #define SD_PAT_DFNOPT stringToSymbol("dfnopt") #define SD_PAT_MBRID stringToSymbol("mbrid") #define SD_PAT_DFNCOM stringToSymbol("dfncom") #define SD_PAT_GRPCOM stringToSymbol("grpcom") #define SD_PAT_BOTCOM stringToSymbol("botcom") #define SD_PAT_OPTCOM stringToSymbol("optgrpcom") #define SD_PAT_NEWLINE stringToSymbol("nl") ConcreteType(StyDoc_T) { PT_Term pTree; // STYX derivation tree of 'infile' MAP(symbol,ROW(PT_Term)) pDfnCom; // comments of token, nonterminal // and production definitions MAP(symbol,ROW(PT_Term)) pGrpCom; // post definition --> group comments PLR_Tab pTab; // language parse table int* aPol; // nonterminal/class types SET(int)* aNtm; // nonterminal partition SET(int)* aPrd; // nonterminal productions MAP(symbol,styxQlxDfn) pGMap; // group symbol |--> definition MAP(symbol,styxQlxDfn) pTMap; // token symbol |--> definition MAP(symbol,long) pNTMap; // nonterminal symbol |--> index SET(symbol) pLSet; // embedded languages ROW(_) pDocBase; // language documentation base: // ROW( T/NT symbol, // ROW(ROW(T/NTGroup/Value symbol)) ) HPat_T pHPat; // template pattern // generation context FILE* pSysOut; // output fp long lDocIdx; // 0 .. pDocBase.Count/2-1 oder -1 long lMbrIdx; // 0 .. pDocBase.pCurRow.Count-1 or -1 long lComIdx; // current start index into comment row ROW(symbol) pCurRow; // 0 .. pDocBase.lDocIdx.Count-1 or -1 }; static SET(symbol) pNTsToKeep; static SET(symbol) pClsToSplit; static SET(symbol) pIgnRecRef; static MAP(symbol,SET(symbol)) pExcludedProds; /* ------------------------- Auxiliary ---------------------------------- */ static c_string SD_com_string ( ROW(PT_Term) pComments, long* lIdx ) /* comment token --> string */ { c_string szResult = (string)NULL; long lCnt = OT_CNT(pComments), lDiff, lI = *lIdx; Sink pSnk = Sink_open(); for( ; *lIdx < lCnt; ++(*lIdx) ) { PT_Term t = OT_GET(PT_Term,pComments,*lIdx), p; if( !PT_isComment(t) ) { ++(*lIdx); break; } else { if( *lIdx > lI ) { p = OT_GET(PT_Term,pComments,(*lIdx)-1); lDiff = PT_row(t) - PT_row(p); if( lDiff >= 2 ) Sink_printf(pSnk,"\n\n"); else if( lDiff == 1 ) Sink_printf(pSnk,"\n"); } Sink_printf(pSnk,"\n%s",GLS_Tok_string(t)+1); } } szResult = Sink_close(pSnk); return szResult; } static long SD_getIgnNTIdx(long lPrdIdx, StyDoc_T pStyDoc) { long lMbrCnt, lSym, lTyp, lI; lMbrCnt = PLR_prodSymCnt(pStyDoc->pTab,lPrdIdx); for( lI=0; lI < lMbrCnt; ++lI ) { lSym = PLR_prodSymbol(pStyDoc->pTab,lPrdIdx,lI); lTyp = PLR_symType(pStyDoc->pTab,lSym); if( CFG_NTM(lTyp) ) return lSym - PLR_tokenCnt(pStyDoc->pTab); } C_BUG; return -1; } static c_bool SD_IsLLProd(long lPrdIdx, StyDoc_T pStyDoc) { long lTCnt = PLR_tokenCnt(pStyDoc->pTab), lNTIdx = PLR_prodNonTerm(pStyDoc->pTab,lPrdIdx); return( lNTIdx == PLR_prodSymbol(pStyDoc->pTab,lPrdIdx,0) - lTCnt ); } static c_bool SD_IsNTUnion(ROW(symbol) pNTLine) { long lCnt = OT_CNT(pNTLine), lI; for( lI=0; lI < lCnt; ++lI ) { c_string szSymbol = symbolToString(OT_GET(symbol,pNTLine,lI)); if( ! strcmp(szSymbol,"\"|\"") ) return C_True; } return C_False; } static bool SD_IsNTRecRef(long lNTIdx, StyDoc_T pStyDoc) { long lClsIdx = PLR_ntClassId(pStyDoc->pTab,lNTIdx), lSym = lNTIdx + PLR_tokenCnt(pStyDoc->pTab), lClsSym = lClsIdx + PLR_tokenCnt(pStyDoc->pTab); c_string szSym = PLR_symName(pStyDoc->pTab,lSym), szClsSym = PLR_symName(pStyDoc->pTab,lClsSym); symbol pSym = stringToSymbol(szSym), pClsSym = stringToSymbol(szClsSym); return ACFG_HAS_NTTYP(pStyDoc->aPol[lNTIdx],ACFG_NTTYP_RECREF) && ! HS_MBR_ELM(pSym,pIgnRecRef) && ! HS_MBR_ELM(pClsSym,pIgnRecRef); } static c_bool SD_IsNTSequence(ROW(symbol) pNTLine) { long lCnt = OT_CNT(pNTLine); if( lCnt > 1 ) { c_string szSymbol = symbolToString(OT_GET(symbol,pNTLine,0)); if( ( ! strncmp(szSymbol,"\"(\"",3) || ! strncmp(szSymbol,"\"{\"",3) || ! strncmp(szSymbol,"\"[\"",3) ) && ( atol(szSymbol+3) + 2 == lCnt || ( atol(szSymbol+3) + 2 == lCnt - 1 && !strcmp(symbolToString(OT_GET(symbol,pNTLine,lCnt-1)),"\"+\"") ) ) ) return C_True; else if( lCnt == 2 && ! strcmp(symbolToString(OT_GET(symbol,pNTLine,1)),"\"+\"") ) return C_True; return C_False; } else return C_True; } static ROW(symbol) SD_rowToNTSeq ( c_bool bCond, c_string szSeq, ROW(symbol) pDstRow, ROW(symbol) pSrcRow ) { ROW(symbol) pResRow = pDstRow; if( bCond ) { c_string szSym; if( pDstRow == pSrcRow ) pResRow = OT_CREATE_ADT(symbol); szSym = Str_printf("\"%c\"%ld",szSeq[0],OT_CNT(pSrcRow)); OT_PUSH(stringToSymbol(szSym),pResRow); FreeMem(szSym); OT_APPEND(pResRow,pSrcRow); szSym = Str_printf("\"%c\"",szSeq[1]); OT_PUSH(stringToSymbol(szSym),pResRow); FreeMem(szSym); if( pDstRow == pSrcRow ) OT_DEL_T(pDstRow); } else if( pDstRow != pSrcRow ) OT_APPEND(pResRow,pSrcRow); return pResRow; } static ROW(symbol) SD_symbolToNTSeq ( c_bool bCond, c_string szSeq, ROW(symbol) pDstRow, symbol pSrcSym ) { if( bCond ) { c_string szSym = Str_printf("\"%c\"1",szSeq[0]); OT_PUSH(stringToSymbol(szSym),pDstRow); FreeMem(szSym); OT_PUSH(pSrcSym,pDstRow); szSym = Str_printf("\"%c\"",szSeq[1]); OT_PUSH(stringToSymbol(szSym),pDstRow); FreeMem(szSym); } else OT_PUSH(pSrcSym,pDstRow); return pDstRow; } static c_bool SD_IsNTMetaSym(symbol pNTSym, symbol* ppMetaSym) { c_string szNTSym = symbolToString(pNTSym), szS = szNTSym; if( *szS == '"' ) { char szBuffer[STD_BUFFLEN+1]; int nI = 0; for( szS++; *szS != '"' && *szS != '\0'; ++nI, ++szS ) szBuffer[nI] = *szS; szBuffer[nI] = '\0'; if( ppMetaSym != (symbol*)NULL ) *ppMetaSym = stringToSymbol(szBuffer); return C_True; } else return C_False; } static c_bool SD_IsTMetaSym(symbol pTSym) // Meta-Symbols: ()|+{}[]- and .. { c_string szMetaSet = "(){}[]|+-", szTSym = symbolToString(pTSym); if( strlen(szTSym) == 1 ) return strstr(szMetaSet,szTSym) != (c_string)NULL; if( strlen(szTSym) == 2 ) return !strcmp(szTSym,".."); return C_False; } /* ------------------------- Init & Quit -------------------------------- */ static void SD_init(int argc, c_string argv[]) /* init STYX documentation generation */ { c_string szS, szT; PIT pItr; CTX_init_stydoc(argc,argv); initSymbols(); MAP_init(); styx_initSymbols(); HP_init(); pNTsToKeep = HS_CREATE_ADTSET(symbol); if( strlen(nts_to_keep) > 0 ) { pItr = PIT_make(nts_to_keep); while( ( szS = PIT_read(pItr) ) != NULL ) HS_SET_ELM(stringToSymbol(szS),pNTsToKeep); PIT_drop(pItr); } pClsToSplit = HS_CREATE_ADTSET(symbol); if( strlen(cls_to_split) > 0 ) { pItr = PIT_make(cls_to_split); while( ( szS = PIT_read(pItr) ) != NULL ) HS_SET_ELM(stringToSymbol(szS),pClsToSplit); PIT_drop(pItr); } pIgnRecRef = HS_CREATE_ADTSET(symbol); if( strlen(ign_rref) > 0 ) { pItr = PIT_make(ign_rref); while( ( szS = PIT_read(pItr) ) != NULL ) HS_SET_ELM(stringToSymbol(szS),pIgnRecRef); PIT_drop(pItr); } pExcludedProds = MAP_newPrimMap(); if( strlen(excl_prods) > 0 ) { pItr = PIT_make(excl_prods); while( ( szS = PIT_read(pItr) ) != NULL ) { szT = strstr(szS,"."); if( szT != (c_string)NULL ) { symbol pNTSym, pProdSym; SET(symbol) pProdSet; *szT = '\0'; pNTSym = stringToSymbol(szS); pProdSym = stringToSymbol(szT+1); *szT = '.'; if( MAP_defined(pExcludedProds,pNTSym) ) pProdSet = MAP_apply(SET(symbol),pExcludedProds,pNTSym); else { pProdSet = HS_CREATE_ADTSET(symbol); MAP_dfndom(pExcludedProds,pNTSym,pProdSet); } HS_SET_ELM(pProdSym,pProdSet); } } PIT_drop(pItr); } } static void SD_quit(void) /* quit STYX documentation generation */ { MAPIT pItr; SET(symbol) pProdSet; symbol pNTSym; MAP_forItrAsg(pNTSym,pProdSet,pItr,pExcludedProds) HS_DROP_SET(pProdSet); MAP_freeMap(pExcludedProds); HS_DROP_SET(pNTsToKeep); HS_DROP_SET(pClsToSplit); HS_DROP_SET(pIgnRecRef); HP_quit(); styx_quitSymbols(); MAP_quit(); freeSymbols(); CTX_quit(); } static StyDoc_T SD_init_base(void) /* init documentation base */ { StyDoc_T pStyDoc = New(StyDoc_T); pStyDoc->pDfnCom = MAP_newPrimMap(); pStyDoc->pGrpCom = MAP_newPrimMap(); pStyDoc->pTree = (PT_Term)NULL; pStyDoc->pTab = (PLR_Tab)NULL; pStyDoc->aPol = (int*)NULL; pStyDoc->aNtm = (SET(int)*)NULL; pStyDoc->aPrd = (SET(int)*)NULL; pStyDoc->pGMap = MAP_newPrimMap(); pStyDoc->pTMap = MAP_newPrimMap(); pStyDoc->pNTMap = MAP_newPrimMap(); pStyDoc->pLSet = HS_CREATE_ADTSET(symbol); pStyDoc->pDocBase = OT_CREATE_ADT(_); pStyDoc->pHPat = (HPat_T)NULL; pStyDoc->pSysOut = (FILE*)NULL; pStyDoc->lDocIdx = -1; pStyDoc->lComIdx = -1; pStyDoc->lMbrIdx = -1; pStyDoc->pCurRow = (ROW(symbol))NULL; return pStyDoc; } /* ------------------------- Output Generation -------------------------- */ static void SD_gendoc_raw(StyDoc_T pStyDoc) /* generate raw documentation - without template */ { long lCnt = OT_CNT(pStyDoc->pDocBase)/2, lI, lJ, lK; fprintf(pStyDoc->pSysOut,"\n%s - CFG Section\n",PLR_language(pStyDoc->pTab)); for( lI=0; lI < lCnt; ++lI ) { ROW(ROW(symbol)) pLines = OT_GET ( ROW(ROW(symbol)), pStyDoc->pDocBase,pStyDoc->lDocIdx*2+1 ); symbol pSym = OT_GET ( symbol,pStyDoc->pDocBase,pStyDoc->lDocIdx*2 ), pMbrSym; if( lI == 0 ) fprintf(pStyDoc->pSysOut,"\nToken Section\n"); else if( lI == MAP_count(pStyDoc->pTMap) ) fprintf(pStyDoc->pSysOut,"\nNonterminal Section\n"); fprintf(pStyDoc->pSysOut,"\n"); for( lJ=0; lJ < OT_CNT(pLines); ++lJ ) { ROW(symbol) pCurRow = OT_GET(ROW(symbol),pLines,lJ); fprintf(pStyDoc->pSysOut,"\n\t%s ::",symbolToString(pSym)); for( lK=0; lK < OT_CNT(pCurRow); ++lK ) { pMbrSym = OT_GET(symbol,pCurRow,lK); fprintf(pStyDoc->pSysOut," %s",symbolToString(pMbrSym)); } } } } static void SD_gendoc_txt(HPat_T pHPat, c_string szTxt) /* generate documentation according template */ { StyDoc_T pStyDoc = (StyDoc_T)HP_getContext(pHPat); fprintf(pStyDoc->pSysOut,"%s",szTxt); } static c_bool SD_gendoc_dref(HPat_T pHPat) /* generate definition reference according template */ { StyDoc_T pStyDoc = (StyDoc_T)HP_getContext(pHPat); pStyDoc->lComIdx = 0; if( pStyDoc->lDocIdx >= 0 && pStyDoc->lDocIdx < OT_CNT(pStyDoc->pDocBase)/2 ) { symbol pSym = OT_GET(symbol,pStyDoc->pDocBase,pStyDoc->lDocIdx*2); fprintf(pStyDoc->pSysOut,"%s",symbolToString(pSym)); return C_True; } return C_False; } static c_bool SD_gendoc_did(HPat_T pHPat) /* generate definition id according template */ { StyDoc_T pStyDoc = (StyDoc_T)HP_getContext(pHPat); pStyDoc->lComIdx = 0; if( pStyDoc->lDocIdx >= 0 && pStyDoc->lDocIdx < OT_CNT(pStyDoc->pDocBase)/2 ) { symbol pSym = OT_GET(symbol,pStyDoc->pDocBase,pStyDoc->lDocIdx*2); if( pStyDoc->lDocIdx < MAP_count(pStyDoc->pTMap) ) { styxQlxDfn pQDfn = MAP_apply(styxQlxDfn,pStyDoc->pTMap,pSym); styxQlxGrp pSGrp, pDGrp; GLS_Tok pSId, pDId; assert0( styxQlxDfn_defn(pQDfn,_,_,&pSGrp,_,&pDGrp,_), "" ); if( styxQlxGrp_non(pSGrp) && styxQlxGrp_non(pDGrp) ) fprintf(pStyDoc->pSysOut,"%s",symbolToString(pSym)); else { Sink pSnk = Sink_open(); c_string szID; if( styxQlxGrp_grp(pSGrp,&pSId) ) { Sink_printf(pSnk,"%s:",GLS_Tok_string(pSId)); } Sink_printf(pSnk,"%s",symbolToString(pSym)); if( styxQlxGrp_grp(pDGrp,&pDId) ) { Sink_printf(pSnk,":%s",GLS_Tok_string(pDId)); } szID = Sink_close(pSnk); fprintf(pStyDoc->pSysOut,"%s",szID); FreeMem(szID); } } else fprintf(pStyDoc->pSysOut,"%s",symbolToString(pSym)); return C_True; } return C_False; } static c_bool SD_gendoc_lref(HPat_T pHPat) /* generate embedded language reference according template */ { StyDoc_T pStyDoc = (StyDoc_T)HP_getContext(pHPat); if( pStyDoc->lDocIdx >= 0 && pStyDoc->lDocIdx < OT_CNT(pStyDoc->pDocBase)/2 && pStyDoc->pCurRow != (ROW(symbol))NULL && pStyDoc->lMbrIdx >= 0 && pStyDoc->lMbrIdx < OT_CNT(pStyDoc->pCurRow) ) { symbol pMbrSym = OT_GET(symbol,pStyDoc->pCurRow,pStyDoc->lMbrIdx); if( strlen(outfile) > 0 ) { MAP(symbol,symbol) pReplaceMap = MAP_newPrimMap(); c_string szPath = FilePrefix(outfile), szFile; MAP_dfndom ( pReplaceMap,stringToSymbol(PLR_language(pStyDoc->pTab)),pMbrSym ); szFile = Line_replace(outfile+strlen(szPath),pReplaceMap); fprintf(pStyDoc->pSysOut,"%s%s",szPath,szFile); MAP_freeMap(pReplaceMap); FreeMem(szPath); FreeMem(szFile); } else fprintf(pStyDoc->pSysOut,"#%s",symbolToString(pMbrSym)); return C_True; } return C_False; } static c_bool SD_gendoc_dcom(HPat_T pHPat) /* generate definition comment according template */ { StyDoc_T pStyDoc = (StyDoc_T)HP_getContext(pHPat); if( pStyDoc->lDocIdx >= 0 && pStyDoc->lDocIdx < OT_CNT(pStyDoc->pDocBase)/2 ) { symbol pSym = OT_GET(symbol,pStyDoc->pDocBase,pStyDoc->lDocIdx*2); if( MAP_defined(pStyDoc->pDfnCom,pSym) && ( pStyDoc->lComIdx == 0 || prodcom ) ) { ROW(PT_Term) pComments = MAP_apply(ROW(PT_Term),pStyDoc->pDfnCom,pSym); string szCom = SD_com_string(pComments,&pStyDoc->lComIdx); if( szCom && HP_fun_defined(pHPat,SD_PAT_DFNCOM) ) { c_string szRCom = HP_fun_apply(pHPat,SD_PAT_DFNCOM,szCom); if( szCom != szRCom ) { FreeMem(szCom); szCom = szRCom; } } HP_gendoc_pat(pHPat,SD_PAT_NEWLINE); fprintf(pStyDoc->pSysOut,"%s",szCom); if( szCom != (string)NULL ) FreeMem(szCom); } else fprintf(pStyDoc->pSysOut," "); return C_True; } return C_False; } static c_bool SD_gendoc_ocom(HPat_T pHPat) /* generate group comment section according template or "" */ { StyDoc_T pStyDoc = (StyDoc_T)HP_getContext(pHPat); pStyDoc->lComIdx = 0; if( pStyDoc->lDocIdx >= 0 && pStyDoc->lDocIdx < OT_CNT(pStyDoc->pDocBase)/2 ) { symbol pSym = OT_GET(symbol,pStyDoc->pDocBase,pStyDoc->lDocIdx*2); if( MAP_defined(pStyDoc->pGrpCom,pSym) ) { HP_gendoc_pat(pHPat,SD_PAT_COMSEC); } return C_True; } return C_False; } static c_bool SD_gendoc_gcom(HPat_T pHPat) /* generate group comment according template */ { StyDoc_T pStyDoc = (StyDoc_T)HP_getContext(pHPat); pStyDoc->lComIdx = 0; if( pStyDoc->lDocIdx >= 0 && pStyDoc->lDocIdx < OT_CNT(pStyDoc->pDocBase)/2 ) { symbol pSym = OT_GET(symbol,pStyDoc->pDocBase,pStyDoc->lDocIdx*2); if( MAP_defined(pStyDoc->pGrpCom,pSym) ) { ROW(PT_Term) pComments = MAP_apply(ROW(PT_Term),pStyDoc->pGrpCom,pSym); string szCom = SD_com_string(pComments,&pStyDoc->lComIdx); if( szCom && HP_fun_defined(pHPat,SD_PAT_GRPCOM) ) { c_string szRCom = HP_fun_apply(pHPat,SD_PAT_GRPCOM,szCom); if( szCom != szRCom ) { FreeMem(szCom); szCom = szRCom; } } fprintf(pStyDoc->pSysOut,"%s",szCom); if( szCom != (string)NULL ) FreeMem(szCom); } else fprintf(pStyDoc->pSysOut," "); return C_True; } return C_False; } static c_bool SD_gendoc_bcom(HPat_T pHPat) /* generate last group comment according template */ { StyDoc_T pStyDoc = (StyDoc_T)HP_getContext(pHPat); pStyDoc->lComIdx = 0; if( MAP_defined(pStyDoc->pGrpCom,NULL) ) { ROW(PT_Term) pComments = MAP_apply(ROW(PT_Term),pStyDoc->pGrpCom,NULL); string szCom = SD_com_string(pComments,&pStyDoc->lComIdx); if( szCom && HP_fun_defined(pHPat,SD_PAT_BOTCOM) ) { c_string szRCom = HP_fun_apply(pHPat,SD_PAT_BOTCOM,szCom); if( szCom != szRCom ) { FreeMem(szCom); szCom = szRCom; } } fprintf(pStyDoc->pSysOut,"%s",szCom); if( szCom != (string)NULL ) FreeMem(szCom); } else fprintf(pStyDoc->pSysOut," "); return C_True; } static c_bool SD_gendoc_dcat(HPat_T pHPat) /* generate definition category according template */ { StyDoc_T pStyDoc = (StyDoc_T)HP_getContext(pHPat); if( pStyDoc->lDocIdx >= 0 && pStyDoc->lDocIdx < OT_CNT(pStyDoc->pDocBase)/2 ) { symbol pSym = OT_GET(symbol,pStyDoc->pDocBase,pStyDoc->lDocIdx*2); if( pStyDoc->lDocIdx < MAP_count(pStyDoc->pTMap) ) { styxQlxDfn pQDfn = MAP_apply(styxQlxDfn,pStyDoc->pTMap,pSym); styxQlxCat pQCat; assert0( styxQlxDfn_defn(pQDfn,&pQCat,_,_,_,_,_), "" ); if( styxQlxCat_letC(pQCat) ) fprintf(pStyDoc->pSysOut,"let"); else if( styxQlxCat_comC(pQCat) ) fprintf(pStyDoc->pSysOut,"com"); else if( styxQlxCat_ignC(pQCat) ) fprintf(pStyDoc->pSysOut,"ign"); else if( styxQlxCat_tokC(pQCat) ) fprintf(pStyDoc->pSysOut,"tok"); else if( styxQlxCat_lanC(pQCat) ) fprintf(pStyDoc->pSysOut,"lan"); else if( styxQlxCat_indC(pQCat) ) fprintf(pStyDoc->pSysOut,"ind"); } else { long lNTIdx = MAP_apply(long,pStyDoc->pNTMap,pSym); if( ACFG_HAS_NTTYP(pStyDoc->aPol[lNTIdx],ACFG_NTTYP_START) ) fprintf(pStyDoc->pSysOut,"start"); else fprintf(pStyDoc->pSysOut,"let"); } return C_True; } return C_False; } static c_bool SD_gendoc_dopt(HPat_T pHPat) /* generate definition option according template */ { StyDoc_T pStyDoc = (StyDoc_T)HP_getContext(pHPat); if( pStyDoc->lDocIdx >= 0 && pStyDoc->lDocIdx < OT_CNT(pStyDoc->pDocBase)/2 ) { symbol pSym = OT_GET(symbol,pStyDoc->pDocBase,pStyDoc->lDocIdx*2); if( pStyDoc->lDocIdx < MAP_count(pStyDoc->pTMap) ) { styxQlxDfn pQDfn = MAP_apply(styxQlxDfn,pStyDoc->pTMap,pSym); styxQlxCat pQOpt; assert0( styxQlxDfn_defn(pQDfn,_,&pQOpt,_,_,_,_), "" ); if( styxQlxOpt_ignca(pQOpt) ) fprintf(pStyDoc->pSysOut,"[I]"); } else { long lNTIdx = MAP_apply(long,pStyDoc->pNTMap,pSym); if( PLR_isErrorNt(pStyDoc->pTab,lNTIdx) ) fprintf(pStyDoc->pSysOut,"[E]"); } return C_True; } return C_False; } static c_bool SD_gendoc_mid(HPat_T pHPat) /* generate member id according template */ { StyDoc_T pStyDoc = (StyDoc_T)HP_getContext(pHPat); if( pStyDoc->lDocIdx >= 0 && pStyDoc->lDocIdx < OT_CNT(pStyDoc->pDocBase)/2 && pStyDoc->pCurRow != (ROW(symbol))NULL && pStyDoc->lMbrIdx >= 0 && pStyDoc->lMbrIdx < OT_CNT(pStyDoc->pCurRow) ) { symbol pMbrSym = OT_GET(symbol,pStyDoc->pCurRow,pStyDoc->lMbrIdx), pDocSym = pMbrSym; if( pStyDoc->lDocIdx >= MAP_count(pStyDoc->pTMap) ) SD_IsNTMetaSym(pMbrSym,&pDocSym); if( !HP_fun_defined(pHPat,SD_PAT_MBRID) ) fprintf(pStyDoc->pSysOut,"%s",symbolToString(pDocSym)); else { c_string szRes = HP_fun_apply ( pHPat,SD_PAT_MBRID,symbolToString(pDocSym) ); fprintf(pStyDoc->pSysOut,"%s",szRes); if( szRes != symbolToString(pDocSym) ) FreeMem(szRes); } return C_True; } return C_False; } static c_bool SD_gendoc_cid(HPat_T pHPat) /* generate language id according template */ { StyDoc_T pStyDoc = (StyDoc_T)HP_getContext(pHPat); fprintf(pStyDoc->pSysOut,"%s",PLR_language(pStyDoc->pTab)); return C_True; } static c_bool SD_gendoc_dsec(HPat_T pHPat, symbol pSec) /* generate definition section according template */ { StyDoc_T pStyDoc = (StyDoc_T)HP_getContext(pHPat); long lCnt = ( pSec == SD_PAT_TKMSEC ) ? MAP_count(pStyDoc->pTMap) : OT_CNT(pStyDoc->pDocBase)/2, lBgn = ( pSec == SD_PAT_TKMSEC ) ? 0 : MAP_count(pStyDoc->pTMap), lDocIdx, lMbrIdx, lI, lJ; ROW(symbol) pRow = HP_getListPatRow(pHPat,pSec), pCurRow; symbol pDfn = OT_GET(symbol,pRow,0); lDocIdx = pStyDoc->lDocIdx; lMbrIdx = pStyDoc->lMbrIdx; pCurRow = pStyDoc->pCurRow; for( lI=lBgn, lJ=0; lI < lCnt; ++lI, ++lJ ) { ROW(ROW(symbol)) pLines = OT_GET(ROW(ROW(symbol)),pStyDoc->pDocBase,2*lI+1); if( lJ > 0 ) { HP_gendoc_pat(pHPat,pSec); if( OT_CNT(pRow) > lJ ) pDfn = OT_GET(symbol,pRow,lJ); } pStyDoc->lDocIdx = lI; pStyDoc->lMbrIdx = -1; pStyDoc->pCurRow = ( lI < MAP_count(pStyDoc->pTMap) ) ? OT_GET(ROW(symbol),pLines,0) : (ROW(symbol))NULL; HP_gendoc_pat(pHPat,pDfn); } pStyDoc->lDocIdx = lDocIdx; pStyDoc->lMbrIdx = lMbrIdx; pStyDoc->pCurRow = pCurRow; return C_True; } static c_bool SD_gendoc_tsec(HPat_T pHPat) /* generate token section according template */ { return SD_gendoc_dsec(pHPat,SD_PAT_TKMSEC); } static c_bool SD_gendoc_nsec(HPat_T pHPat) /* generate nonterminal section according template */ { return SD_gendoc_dsec(pHPat,SD_PAT_NTMSEC); } static c_bool SD_gendoc_psec(HPat_T pHPat) /* generate production section according template */ { StyDoc_T pStyDoc = (StyDoc_T)HP_getContext(pHPat); if( pStyDoc->lDocIdx >= 0 && pStyDoc->lDocIdx < OT_CNT(pStyDoc->pDocBase)/2 ) { ROW(ROW(symbol)) pLines = OT_GET ( ROW(ROW(symbol)), pStyDoc->pDocBase,pStyDoc->lDocIdx*2+1 ); ROW(symbol) pRow = HP_getListPatRow(pHPat,SD_PAT_PRDSEC), pCurRow; symbol pDfn = OT_GET(symbol,pRow,0); long lCnt = OT_CNT(pLines), lI; pCurRow = pStyDoc->pCurRow; for( lI=0; lI < lCnt; ++lI ) { if( lI > 0 ) { HP_gendoc_pat(pHPat,SD_PAT_PRDSEC); if( OT_CNT(pRow) > lI ) pDfn = OT_GET(symbol,pRow,lI); } pStyDoc->pCurRow = OT_GET(ROW(symbol),pLines,lI); HP_gendoc_pat(pHPat,pDfn); } pStyDoc->pCurRow = pCurRow; return C_True; } return C_False; } static c_bool SD_gendoc_msec(HPat_T pHPat) /* generate member section according template */ { StyDoc_T pStyDoc = (StyDoc_T)HP_getContext(pHPat); if( pStyDoc->lDocIdx >= 0 && pStyDoc->lDocIdx < OT_CNT(pStyDoc->pDocBase)/2 && pStyDoc->pCurRow != (ROW(symbol))NULL ) { ROW(symbol) pPRow = HP_getListPatRow(pHPat,SD_PAT_MBRSEC); symbol pRPat = OT_GET(symbol,pPRow,0), pMPat = OT_CNT(pPRow) >= 2 ? OT_GET(symbol,pPRow,1) : pRPat, pVPat = OT_CNT(pPRow) >= 3 ? OT_GET(symbol,pPRow,2) : pMPat, pLPat = OT_CNT(pPRow) >= 4 ? OT_GET(symbol,pPRow,3) : pRPat, pMbrSym; long lCnt = OT_CNT(pStyDoc->pCurRow), lMbrIdx, lI; lMbrIdx = pStyDoc->lMbrIdx; for( lI=0; lI < lCnt; ++lI ) { if( lI > 0 ) HP_gendoc_pat(pHPat,SD_PAT_MBRSEC); pMbrSym = OT_GET(symbol,pStyDoc->pCurRow,lI); pStyDoc->lMbrIdx = lI; if( HS_MBR_ELM(pMbrSym,pStyDoc->pLSet) ) { HP_gendoc_pat(pHPat,pLPat); } else if( MAP_defined(pStyDoc->pNTMap,pMbrSym) || MAP_defined(pStyDoc->pTMap,pMbrSym) ) { HP_gendoc_pat(pHPat,pRPat); } else if( pStyDoc->lDocIdx < MAP_count(pStyDoc->pTMap) ) { if( SD_IsTMetaSym(pMbrSym) ) HP_gendoc_pat(pHPat,pMPat); else HP_gendoc_pat(pHPat,pVPat); } else { if( SD_IsNTMetaSym(pMbrSym,(symbol*)NULL) || !strcmp(symbolToString(pMbrSym),PLR_TOK_Other) ) HP_gendoc_pat(pHPat,pMPat); else HP_gendoc_pat(pHPat,pVPat); } } pStyDoc->lMbrIdx = lMbrIdx; return C_True; } return C_False; } static c_bool SD_gendoc_cfg(HPat_T pHPat) /* generate documentation according template */ { HP_gendoc_pat(pHPat,SD_PAT_CFGDFN); return C_True; } /* ------------------------- Load & Unload ------------------------------ */ #define IS_QEXP_UDC(e) ( styxExp_union(e,_,_) \ || styxExp_diff(e,_,_) \ || styxExp_conc(e,_,_) ) static void SD_collectSubExps(styxExp e, SET(styxExp) pSubExps) // collection of sub expression ( ... ) { PT_Itr it; PT_FORALL(it,e) { PT_Term t = PT_termIT(it), p; if (PT_stateIT(it) == PT_PRAE) { styxExp exp; if (styx_Exp(t,&exp) && ignProd(symbolToString(PT_product(exp)))) { p = PT_parts(exp); while( p != (PT_Term)NULL && !PT_isNonTerm(p) ) { if( PT_isKey(p) && !strcmp(symbolToString(PT_value(p)),"(") ) { p = PT_ign_Skip(exp); if( p != (PT_Term)NULL ) HS_SET_ELM(p,pSubExps); } p = PT_next(p); } } } } } static void SD_evalQExp(styxExp e, ROW(symbol) l, SET(styxExp) pSubExps) // Meta-Symbols: ()|+{}[]- and .. { styxExp exp1, exp2, exp3; GLS_Tok tok; if( styxExp_dyck(e,&exp1,&exp2,&exp3) ) { OT_PUSH(stringToSymbol("<"),l); SD_evalQExp(exp1,l,pSubExps); OT_PUSH(stringToSymbol(">"),l); SD_evalQExp(exp2,l,pSubExps); OT_PUSH(stringToSymbol("<"),l); SD_evalQExp(exp3,l,pSubExps); OT_PUSH(stringToSymbol(">"),l); } else if( styxExp_union(e,&exp1,&exp2) ) { if( HS_MBR_ELM(exp1,pSubExps) ) { OT_PUSH(stringToSymbol("("),l); SD_evalQExp(exp1,l,pSubExps); OT_PUSH(stringToSymbol(")"),l); } else SD_evalQExp(exp1,l,pSubExps); OT_PUSH(stringToSymbol("|"),l); if( HS_MBR_ELM(exp2,pSubExps) ) { OT_PUSH(stringToSymbol("("),l); SD_evalQExp(exp2,l,pSubExps); OT_PUSH(stringToSymbol(")"),l); } else SD_evalQExp(exp2,l,pSubExps); } else if( styxExp_diff(e,&exp1,&exp2) ) { if( HS_MBR_ELM(exp1,pSubExps) ) { OT_PUSH(stringToSymbol("("),l); SD_evalQExp(exp1,l,pSubExps); OT_PUSH(stringToSymbol(")"),l); } else SD_evalQExp(exp1,l,pSubExps); OT_PUSH(stringToSymbol("-"),l); if( HS_MBR_ELM(exp2,pSubExps) ) { OT_PUSH(stringToSymbol("("),l); SD_evalQExp(exp2,l,pSubExps); OT_PUSH(stringToSymbol(")"),l); } else SD_evalQExp(exp2,l,pSubExps); } else if( styxExp_conc(e,&exp1,&exp2) ) { if( HS_MBR_ELM(exp1,pSubExps) ) { OT_PUSH(stringToSymbol("("),l); SD_evalQExp(exp1,l,pSubExps); OT_PUSH(stringToSymbol(")"),l); } else SD_evalQExp(exp1,l,pSubExps); if( HS_MBR_ELM(exp2,pSubExps) ) { OT_PUSH(stringToSymbol("("),l); SD_evalQExp(exp2,l,pSubExps); OT_PUSH(stringToSymbol(")"),l); } else SD_evalQExp(exp2,l,pSubExps); } else if( styxExp_opt(e,&exp1) ) { OT_PUSH(stringToSymbol("["),l); SD_evalQExp(exp1,l,pSubExps); OT_PUSH(stringToSymbol("]"),l); } else if( styxExp_star(e,&exp1) ) { OT_PUSH(stringToSymbol("{"),l); SD_evalQExp(exp1,l,pSubExps); OT_PUSH(stringToSymbol("}"),l); } else if( styxExp_plus(e,&exp1) ) { if( HS_MBR_ELM(exp1,pSubExps) ) { OT_PUSH(stringToSymbol("("),l); SD_evalQExp(exp1,l,pSubExps); OT_PUSH(stringToSymbol(")"),l); } else SD_evalQExp(exp1,l,pSubExps); OT_PUSH(stringToSymbol("+"),l); } else if( styxExp_range(e,&exp1,&exp2) ) { SD_evalQExp(exp1,l,pSubExps); OT_PUSH(stringToSymbol(".."),l); SD_evalQExp(exp2,l,pSubExps); } else if( styxExp_set(e,&tok) ) { OT_PUSH(GLS_Tok_symbol(tok),l); } else if( styxExp_sequ(e,&tok) ) { OT_PUSH(GLS_Tok_symbol(tok),l); } else if( styxExp_ident(e,&tok) ) { OT_PUSH(GLS_Tok_symbol(tok),l); } else if( !styxExp_nul(e) ) C_BUG; } static void SD_load_com(StyDoc_T pStyDoc) /* load comments */ { PT_Itr pItr; GLS_Tok pIde; ROW(PT_Term) pComments = NULL; ROW(PT_Term) pGrpComments = NULL; long lRow = 0, lDRow = 0; PT_FORALL(pItr,pStyDoc->pTree) { PT_Term t = PT_termIT(pItr), c; if (PT_stateIT(pItr) == PT_PRAE) { if( PT_hasPos(t) ) { lRow = PT_row(t); if( PT_isComment(t) && strstr(GLS_Tok_string(t),";;") == NULL ) { if( pComments == NULL ) { if( pGrpComments == NULL ) { pGrpComments = OT_CREATE_ADT(PT_Term); } OT_PUSH(t,pGrpComments); } else { if( lDRow == lRow || lDRow + 1 == lRow ) OT_PUSH(t,pComments); else { if( OT_CNT(pComments) > 0 ) { c = OT_TOP(PT_Term,pComments); if( lRow == (long)(PT_row(c) + 1) ) OT_PUSH(t,pComments); else { if( pGrpComments == NULL ) { pGrpComments = OT_CREATE_ADT(PT_Term); } OT_PUSH(t,pGrpComments); } } else { if( pGrpComments == NULL ) { pGrpComments = OT_CREATE_ADT(PT_Term); } OT_PUSH(t,pGrpComments); } } } } else if( PT_isNonTerm(t) ) { if( styx_QlxDfn(t,_) ) { assert0( styxQlxDfn_defn((styxQlxDfn)t,_,_,_,&pIde,_,_) || styxQlxDfn_igrp((styxQlxDfn)t,&pIde) || styxQlxDfn_xgrp((styxQlxDfn)t,&pIde), ""); if( !MAP_defined(pStyDoc->pDfnCom,GLS_Tok_symbol(pIde)) ) { pComments = OT_CREATE_ADT(PT_Term); MAP_dfndom(pStyDoc->pDfnCom,GLS_Tok_symbol(pIde),pComments); if( pGrpComments != NULL ) { MAP_dfndom(pStyDoc->pGrpCom,GLS_Tok_symbol(pIde),pGrpComments); pGrpComments = NULL; } lDRow = lRow; } } else if( styx_Dfn(t,_) ) { styxDfn_defn((styxDfn)t,_,_,&pIde,_); if( !MAP_defined(pStyDoc->pDfnCom,GLS_Tok_symbol(pIde)) ) { pComments = OT_CREATE_ADT(PT_Term); MAP_dfndom(pStyDoc->pDfnCom,GLS_Tok_symbol(pIde),pComments); if( pGrpComments != NULL ) { MAP_dfndom(pStyDoc->pGrpCom,GLS_Tok_symbol(pIde),pGrpComments); pGrpComments = NULL; } lDRow = lRow; } } else if( styx_Prd(t,_) ) { styxPrd_prod((styxPrd)t,_,&pIde,_); OT_PUSH(pIde,pComments); if( pGrpComments != NULL ) { OT_APPEND(pComments,pGrpComments); OT_DEL_T(pGrpComments); pGrpComments = NULL; } lDRow = lRow; } } } } } if( pGrpComments != NULL ) MAP_dfndom(pStyDoc->pGrpCom,NULL,pGrpComments); } static void SD_load_lex(GLS_Lst(styxQlxDfn) pQDfns, StyDoc_T pStyDoc) /* load documentation base for lexical analysis */ { GLS_Lst(styxQlxDfn) pItr; GLS_Tok pIde, pLan; styxQlxGrp pQGrp; styxQlxDfn pQDfn; styxQlxCat pQCat; styxExp pQExp; symbol pTSym; c_string szETok; GLS_FORALL(pItr,pQDfns) // token map { pQDfn = GLS_FIRST(styxQlxDfn,pItr); if( styxQlxDfn_defn(pQDfn,&pQCat,_,&pQGrp,&pIde,_,_) ) { if( styxQlxCat_lanC(pQCat) ) { assert0(styxQlxGrp_grp(pQGrp,&pLan),""); HS_SET_ELM(GLS_Tok_symbol(pLan),pStyDoc->pLSet); szETok = Str_printf("%s%s",GLS_Tok_string(pLan),GLS_Tok_string(pIde)); pTSym = stringToSymbol(szETok); FreeMem(szETok); } else pTSym = GLS_Tok_symbol(pIde); if( ! MAP_defined(pStyDoc->pTMap,pTSym) ) MAP_dfndom(pStyDoc->pTMap,pTSym,pQDfn); } else if( styxQlxDfn_igrp(pQDfn,&pIde) || styxQlxDfn_xgrp(pQDfn,&pIde) ) { if( ! MAP_defined(pStyDoc->pGMap,GLS_Tok_symbol(pIde)) ) MAP_dfndom(pStyDoc->pGMap,GLS_Tok_symbol(pIde),pQDfn); } } GLS_FORALL(pItr,pQDfns) // token document base { ROW(ROW(symbol)) pTLines; ROW(symbol) pTLine; SET(styxExp) pSubExps; pQDfn = GLS_FIRST(styxQlxDfn,pItr); if( styxQlxDfn_defn(pQDfn,&pQCat,_,&pQGrp,&pIde,_,&pQExp) ) { pTLines = OT_CREATE(ROW(symbol),primCopy,OT_delT,primEqual); pTLine = OT_CREATE_ADT(symbol); if( !styxQlxCat_lanC(pQCat) ) pTSym = GLS_Tok_symbol(pIde); else { assert0(styxQlxGrp_grp(pQGrp,&pLan),""); szETok = Str_printf("%s%s",GLS_Tok_string(pLan),GLS_Tok_string(pIde)); pTSym = stringToSymbol(szETok); FreeMem(szETok); } OT_PUSH(pTSym,pStyDoc->pDocBase); OT_PUSH(pTLines,pStyDoc->pDocBase); OT_PUSH(pTLine,pTLines); if( !styxQlxCat_lanC(pQCat) ) { pSubExps = HS_CREATE_ADTSET(styxExp); SD_collectSubExps(pQExp,pSubExps); SD_evalQExp(pQExp,pTLine,pSubExps); HS_DROP_SET(pSubExps); } else { OT_PUSH(GLS_Tok_symbol(pLan),pTLine); } } } } // Meta-Symbols in Productions are enclosed with ". /**/static long SD_load_ntgroup ( long lNTIdx, MAP(long,ROW(ROW(symbol))) pEBNF, StyDoc_T pStyDoc ); static ROW(symbol) SD_load_ntprod ( long lNTIdx, long lPrdIdx, long lDocIdx, c_bool bNTList, MAP(long,ROW(ROW(symbol))) pEBNF, StyDoc_T pStyDoc ) /* load documentation base for a production of nonterminal 'lNTIdx' */ { long lMbrCnt, lSym, lSymIdx, lClsIdx, lTyp, lSubSym, lSubIdx, lI, lJ; ROW(ROW(symbol)) pNTLines = MAP_apply(ROW(ROW(symbol)),pEBNF,lDocIdx), pMbrLines; ROW(symbol) pNTLine = OT_CREATE_ADT(symbol), pMbrLine; c_string szSym; symbol pSym; c_bool bOptNT; lMbrCnt = PLR_prodSymCnt(pStyDoc->pTab,lPrdIdx); for( lI=0; lI < lMbrCnt; ++lI ) { lSym = PLR_prodSymbol(pStyDoc->pTab,lPrdIdx,lI); lTyp = PLR_symType(pStyDoc->pTab,lSym); if( CFG_NTM(lTyp) ) { lSymIdx = lSym-PLR_tokenCnt(pStyDoc->pTab); lClsIdx = PLR_ntClassId(pStyDoc->pTab,lSymIdx); lSubIdx = SD_load_ntgroup(lSymIdx,pEBNF,pStyDoc); lSubSym = lSubIdx + PLR_tokenCnt(pStyDoc->pTab); szSym = PLR_symName(pStyDoc->pTab,lSubSym); pSym = stringToSymbol(szSym); pMbrLines = MAP_apply(ROW(ROW(symbol)),pEBNF,lSubIdx); bOptNT = ACFG_HAS_NTTYP(pStyDoc->aPol[lSubIdx],ACFG_NTTYP_OPT) && ! ACFG_HAS_NTTYP(pStyDoc->aPol[lSubIdx],ACFG_NTTYP_RECTYP); if( ( MAP_defined(pStyDoc->pNTMap,pSym) || HS_MBR_ELM(pSym,pNTsToKeep) || SD_IsNTRecRef(lSymIdx, pStyDoc) || ! ACFG_HAS_NTTYP(pStyDoc->aPol[lClsIdx],ACFG_NTTYP_LIST) ) && ( ACFG_HAS_NTTYP(pStyDoc->aPol[lSubIdx],ACFG_NTTYP_RECTYP) || ( OT_CNT(pMbrLines) > 1 && ! ( ACFG_HAS_NTTYP(pStyDoc->aPol[lSymIdx],ACFG_NTTYP_REF1) && ignProd(PLR_prodName(pStyDoc->pTab,lPrdIdx)) && lMbrCnt == 1 ) ) ) ) { if( ! MAP_defined(pStyDoc->pNTMap,pSym) ) { MAP_dfndom(pStyDoc->pNTMap,pSym,lSubIdx); OT_PUSH(pSym,pStyDoc->pDocBase); OT_PUSH(pMbrLines,pStyDoc->pDocBase); } SD_symbolToNTSeq(bOptNT,"[]",pNTLine,pSym); } else if( OT_CNT(pMbrLines) > 0 ) { if( ! bNTList ) { if( OT_CNT(pMbrLines) == 1 ) { pMbrLine = OT_GET(ROW(symbol),pMbrLines,0); if( ACFG_HAS_NTTYP(pStyDoc->aPol[lClsIdx],ACFG_NTTYP_LIST) ) SD_rowToNTSeq ( lMbrCnt > 1 && SD_IsNTUnion(pMbrLine) && !SD_IsNTSequence(pMbrLine), "()", pNTLine,pMbrLine ); else SD_rowToNTSeq(bOptNT,"[]",pNTLine,pMbrLine); } else { assert0( pMbrLines != pNTLines,szSym ); for( lJ=0; lJ < OT_CNT(pMbrLines); ++lJ ) { pMbrLine = OT_GET(ROW(symbol),pMbrLines,lJ); OT_PUSH(OT_COPY(pMbrLine),pNTLines); } } } else // in this case only one line is possible !!! if( lNTIdx != lSymIdx ) // CONSREF { pMbrLine = OT_GET(ROW(symbol),pMbrLines,0); if( PLR_ntClassId(pStyDoc->pTab,lNTIdx) != lClsIdx && ACFG_HAS_NTTYP(pStyDoc->aPol[lClsIdx],ACFG_NTTYP_LIST) ) SD_rowToNTSeq ( SD_IsNTUnion(pMbrLine) && !SD_IsNTSequence(pMbrLine), "()", pNTLine,pMbrLine ); else SD_rowToNTSeq(bOptNT,"[]",pNTLine,pMbrLine); } } } else { szSym = PLR_symName(pStyDoc->pTab,lSym); OT_PUSH(stringToSymbol(szSym),pNTLine); } } return pNTLine; } static void SD_cons_ntprod ( long lDocIdx, MAP(long,ROW(ROW(symbol))) pEBNF, StyDoc_T pStyDoc ) /* concat simple nonterminal/class productions */ { ROW(ROW(symbol)) pNTLines = MAP_apply(ROW(ROW(symbol)),pEBNF,lDocIdx); ROW(symbol) pNTLine; long lClsIdx = PLR_ntClassId(pStyDoc->pTab,lDocIdx), lCnt, lI; c_bool bSimple; bSimple = ! ACFG_HAS_NTTYP(pStyDoc->aPol[lClsIdx],ACFG_NTTYP_LIST) && ( ACFG_HAS_NTTYP(pStyDoc->aPol[lDocIdx],ACFG_NTTYP_PRIM) || ACFG_HAS_NTTYP(pStyDoc->aPol[lDocIdx],ACFG_NTTYP_PRIMC) ); lCnt = OT_CNT(pNTLines); if( lCnt > 1 && bSimple ) { pNTLine = OT_GET(ROW(symbol),pNTLines,0); if( OT_CNT(pNTLine) > 0 ) { for( lI=1; lI < lCnt; ++lI ) { OT_PUSH(stringToSymbol("\"|\""),pNTLine); OT_APPEND(pNTLine,OT_GET(ROW(symbol),pNTLines,lI)); } OT_DEL_ES(pNTLines,1,lCnt-1); } } } static void SD_load_nt ( long lNTIdx, c_bool bNTClass, MAP(long,ROW(ROW(symbol))) pEBNF, StyDoc_T pStyDoc ) /* load documentation base for a nonterminal/class */ { long lClsIdx = PLR_ntClassId(pStyDoc->pTab,lNTIdx), lDocIdx = bNTClass ? lClsIdx : lNTIdx, lPrdIdx; ROW(ROW(symbol)) pNTLines = MAP_apply(ROW(ROW(symbol)),pEBNF,lDocIdx); ROW(symbol) pNTLine; HS_Itr pItr; symbol pNTSym = stringToSymbol(PLR_symName ( pStyDoc->pTab, PLR_tokenCnt(pStyDoc->pTab) + lNTIdx )), pProdSym; c_bool bExcluded; HS_FORALL(lPrdIdx,pItr,pStyDoc->aPrd[lNTIdx]) { pProdSym = stringToSymbol(PLR_prodName(pStyDoc->pTab,lPrdIdx)); bExcluded = MAP_defined(pExcludedProds,pNTSym) && HS_MBR_ELM ( pProdSym,MAP_apply(SET(symbol),pExcludedProds,pNTSym) ); if( ! bExcluded && ( ! bNTClass || !ignProd(PLR_prodName(pStyDoc->pTab,lPrdIdx)) || PLR_prodSymCnt(pStyDoc->pTab,lPrdIdx) > 1 ) ) { pNTLine = SD_load_ntprod(lNTIdx,lPrdIdx,lDocIdx,C_False,pEBNF,pStyDoc); if( OT_CNT(pNTLine) > 0 ) OT_PUSH(pNTLine,pNTLines); else OT_DEL_T(pNTLine); } } } static c_bool SD_add_listprod ( long lNTIdx, long lPrdIdx, c_bool bNTNil, ROW(symbol) pListLine, MAP(long,ROW(ROW(symbol))) pEBNF, StyDoc_T pStyDoc ) /* appends list production to 'pListLine' if not empty. RC = opt. list */ { ROW(symbol) pNTLine = SD_load_ntprod ( lNTIdx,lPrdIdx,lNTIdx,C_True,pEBNF,pStyDoc ); c_bool bEmpty = ( OT_CNT(pNTLine) == 0 ); if( ! bEmpty ) { bEmpty = bNTNil; if( OT_CNT(pListLine) > 0 ) OT_PUSH(stringToSymbol("\"|\""),pListLine); OT_APPEND(pListLine,pNTLine); } OT_DEL_T(pNTLine); return bEmpty; } static c_bool SD_add_consprod ( long lNTIdx, long lPrdIdx, c_bool bNTNil, ROW(symbol)* pListLine, MAP(long,ROW(ROW(symbol))) pEBNF, StyDoc_T pStyDoc ) /* appends cons production to 'pListLine' if not empty. RC = opt. list */ { ROW(symbol) pNTLine = SD_load_ntprod ( lNTIdx,lPrdIdx,lNTIdx,C_True,pEBNF,pStyDoc ), pTmpLine; c_bool bEmpty = ( OT_CNT(pNTLine) == 0 ); if( ! bEmpty ) { bEmpty = ( bNTNil && OT_CNT(*pListLine) > 0 ); pTmpLine = OT_CREATE_ADT(symbol); SD_rowToNTSeq ( bNTNil || !SD_IsNTSequence(pNTLine), bNTNil?"{}":"()", pTmpLine,pNTLine ); if( ! bNTNil ) OT_PUSH(stringToSymbol("\"+\""),pTmpLine); pTmpLine = SD_rowToNTSeq(!bNTNil && OT_CNT(*pListLine) > 0,"[]",pTmpLine,pTmpLine); if( SD_IsLLProd(lPrdIdx,pStyDoc) ) { OT_APPEND(*pListLine,pTmpLine); OT_DEL_T(pTmpLine); } else { OT_APPEND(pTmpLine,*pListLine); OT_DEL_T(*pListLine); *pListLine = pTmpLine; } } OT_DEL_T(pNTLine); return bEmpty; } static void SD_load_ntlist ( long lNTIdx, MAP(long,ROW(ROW(symbol))) pEBNF, StyDoc_T pStyDoc ) /* load documentation base for a nonterminal list */ { long lConsIdx = -1, lMbrCnt, lPrdIdx, lIgnNTIdx; c_bool bNTNil = ACFG_HAS_NTTYP(pStyDoc->aPol[lNTIdx],ACFG_NTTYP_NIL), bConsRef = ACFG_HAS_NTTYP(pStyDoc->aPol[lNTIdx],ACFG_NTTYP_CONSREF) && ! SD_IsNTRecRef(lNTIdx, pStyDoc); ROW(symbol) pListLine = OT_CREATE_ADT(symbol); HS_Itr pItr; HS_FORALL(lPrdIdx,pItr,pStyDoc->aPrd[lNTIdx]) { lMbrCnt = PLR_prodSymCnt(pStyDoc->pTab,lPrdIdx); if( nilProd(PLR_prodName(pStyDoc->pTab,lPrdIdx)) && lMbrCnt > 0 ) bNTNil = SD_add_listprod(lNTIdx,lPrdIdx,bNTNil,pListLine,pEBNF,pStyDoc); else if( ignProd(PLR_prodName(pStyDoc->pTab,lPrdIdx)) ) { lIgnNTIdx = SD_getIgnNTIdx(lPrdIdx,pStyDoc); if( lMbrCnt > 1 || ( ! ACFG_HAS_NTTYP(pStyDoc->aPol[lIgnNTIdx],ACFG_NTTYP_EMPTY) && lIgnNTIdx != lNTIdx ) ) bNTNil = SD_add_listprod(lNTIdx,lPrdIdx,bNTNil,pListLine,pEBNF,pStyDoc); else bNTNil |= ACFG_HAS_NTTYP(pStyDoc->aPol[lIgnNTIdx],ACFG_NTTYP_EMPTY); } else if( consProd(PLR_prodName(pStyDoc->pTab,lPrdIdx)) ) { if( bConsRef ) lConsIdx = lPrdIdx; else bNTNil = SD_add_listprod(lNTIdx,lPrdIdx,bNTNil,pListLine,pEBNF,pStyDoc); } } if( lConsIdx >= 0 ) bNTNil = SD_add_consprod(lNTIdx,lConsIdx,bNTNil,&pListLine,pEBNF,pStyDoc); pListLine = SD_rowToNTSeq(bNTNil && OT_CNT(pListLine) > 0,"[]",pListLine,pListLine); if( OT_CNT(pListLine) > 0 ) { ROW(ROW(symbol)) pNTLines = MAP_apply(ROW(ROW(symbol)),pEBNF,lNTIdx); OT_PUSH(pListLine,pNTLines); } else OT_DEL_T(pListLine); } static c_bool SD_splitClass(StyDoc_T pStyDoc, long lClsIdx) /* create separat rules for each nonterminal */ { symbol pClsSym = stringToSymbol(PLR_symName ( pStyDoc->pTab, PLR_tokenCnt(pStyDoc->pTab) + lClsIdx )); return HS_MBR_ELM(pClsSym,pClsToSplit); } static long SD_load_ntgroup ( long lNTIdx, MAP(long,ROW(ROW(symbol))) pEBNF, StyDoc_T pStyDoc ) /* load documentation base for a nonterminal/class/list */ { long lClsIdx = PLR_ntClassId(pStyDoc->pTab,lNTIdx), lDocIdx; c_bool bNTList = ACFG_HAS_NTTYP(pStyDoc->aPol[lClsIdx],ACFG_NTTYP_LIST), bNTClass = !bNTList && ACFG_HAS_NTTYP(pStyDoc->aPol[lClsIdx],ACFG_NTTYP_CLASS) && ! SD_splitClass(pStyDoc,lClsIdx); lDocIdx = bNTClass ? lClsIdx : lNTIdx; if( ! MAP_defined(pEBNF,lDocIdx) ) { ROW(ROW(symbol)) pNTLines = OT_CREATE ( ROW(symbol),primCopy,OT_delT,primEqual ); symbol pNTSym = stringToSymbol(PLR_symName ( pStyDoc->pTab, PLR_tokenCnt(pStyDoc->pTab) + lDocIdx )); HS_Itr pItr; MAP_dfndom(pEBNF,lDocIdx,pNTLines); if( ACFG_HAS_NTTYP(pStyDoc->aPol[lNTIdx],ACFG_NTTYP_START) && ! MAP_defined(pStyDoc->pNTMap,pNTSym) ) { MAP_dfndom(pStyDoc->pNTMap,pNTSym,lDocIdx); OT_PUSH(pNTSym,pStyDoc->pDocBase); OT_PUSH(pNTLines,pStyDoc->pDocBase); } if( bNTClass ) { if( ACFG_HAS_NTTYP(pStyDoc->aPol[lClsIdx],ACFG_NTTYP_RECTYP) && ACFG_HAS_NTTYP(pStyDoc->aPol[lClsIdx],ACFG_NTTYP_OPT) ) OT_PUSH(OT_CREATE_ADT(symbol),pNTLines); HS_FORALL(lNTIdx,pItr,pStyDoc->aNtm[lClsIdx]) if( HS_CARD(pStyDoc->aPrd[lNTIdx]) > 1 || ! ACFG_HAS_NTTYP(pStyDoc->aPol[lNTIdx],ACFG_NTTYP_EMPTY) ) { SD_load_nt(lNTIdx,bNTClass,pEBNF,pStyDoc); } } else { if( HS_CARD(pStyDoc->aPrd[lNTIdx]) > 1 || ! ACFG_HAS_NTTYP(pStyDoc->aPol[lNTIdx],ACFG_NTTYP_EMPTY) ) { if( bNTList ) SD_load_ntlist(lNTIdx,pEBNF,pStyDoc); else { if( ACFG_HAS_NTTYP(pStyDoc->aPol[lNTIdx],ACFG_NTTYP_RECTYP) && ACFG_HAS_NTTYP(pStyDoc->aPol[lNTIdx],ACFG_NTTYP_OPT) ) OT_PUSH(OT_CREATE_ADT(symbol),pNTLines); SD_load_nt(lNTIdx,bNTClass,pEBNF,pStyDoc); } } } } return lDocIdx; } static void SD_load_cfg(StyDoc_T pStyDoc) /* load documentation base for context free grammar */ { MAP(long,ROW(ROW(symbol))) pEBNF; ROW(ROW(symbol)) pNTLines; MAPIT pItr; long lCnt = PLR_startCnt(pStyDoc->pTab), lDocIdx, lI; symbol pNTSym; pEBNF = MAP_newPrimMap(); for( lI=0; lI < lCnt; ++lI ) { lDocIdx = SD_load_ntgroup ( PLR_startSymbol(pStyDoc->pTab,lI)-PLR_tokenCnt(pStyDoc->pTab), pEBNF,pStyDoc ); } MAP_forItrAsg(pNTSym,lDocIdx,pItr,pStyDoc->pNTMap) { SD_cons_ntprod(lDocIdx,pEBNF,pStyDoc); MAP_rmvdom(pEBNF,lDocIdx); } MAP_forItrAsg(lDocIdx,pNTLines,pItr,pEBNF) if( pNTLines != (ROW(ROW(symbol)))NULL ) OT_DEL_T(pNTLines); MAP_freeMap(pEBNF); } static c_bool SD_load_pat(StyDoc_T pStyDoc) /* load template */ { if( strlen(template) > 0 ) { Scn_Stream pStream; pStyDoc->pHPat = HP_create(); HP_setContext(pStyDoc->pHPat,pStyDoc); HP_setPrintFun(pStyDoc->pHPat,SD_gendoc_txt); if( strlen(refalias) > 0 ) HP_setRefAlias(pStyDoc->pHPat,stringToSymbol(refalias)); HP_addPatSpec(pStyDoc->pHPat,SD_PAT_CFGDFN,SD_gendoc_cfg,HPAT_REF_PAT); //HP_addPatSpec(pStyDoc->pHPat,SD_PAT_COMSEC,SD_gendoc_csec,HPAT_REF_PAT); HP_addPatSpec(pStyDoc->pHPat,SD_PAT_TKMSEC,SD_gendoc_tsec,HPAT_REF_LIST); HP_addPatSpec(pStyDoc->pHPat,SD_PAT_NTMSEC,SD_gendoc_nsec,HPAT_REF_LIST); HP_addPatSpec(pStyDoc->pHPat,SD_PAT_MBRSEC,SD_gendoc_msec,HPAT_REF_LIST); HP_addPatSpec(pStyDoc->pHPat,SD_PAT_PRDSEC,SD_gendoc_psec,HPAT_REF_LIST); HP_addPatSpec(pStyDoc->pHPat,SD_PAT_CFGID,SD_gendoc_cid,HPAT_REF_PAR); HP_addPatSpec(pStyDoc->pHPat,SD_PAT_DFNID,SD_gendoc_did,HPAT_REF_PAR); HP_addPatSpec(pStyDoc->pHPat,SD_PAT_DFNREF,SD_gendoc_dref,HPAT_REF_PAR); HP_addPatSpec(pStyDoc->pHPat,SD_PAT_LANREF,SD_gendoc_lref,HPAT_REF_PAR); HP_addPatSpec(pStyDoc->pHPat,SD_PAT_DFNCAT,SD_gendoc_dcat,HPAT_REF_PAR); HP_addPatSpec(pStyDoc->pHPat,SD_PAT_DFNOPT,SD_gendoc_dopt,HPAT_REF_PAR); HP_addPatSpec(pStyDoc->pHPat,SD_PAT_MBRID,SD_gendoc_mid,HPAT_REF_PAR); HP_addPatSpec(pStyDoc->pHPat,SD_PAT_DFNCOM,SD_gendoc_dcom,HPAT_REF_PAR); HP_addPatSpec(pStyDoc->pHPat,SD_PAT_GRPCOM,SD_gendoc_gcom,HPAT_REF_PAR); HP_addPatSpec(pStyDoc->pHPat,SD_PAT_BOTCOM,SD_gendoc_bcom,HPAT_REF_PAR); HP_addPatSpec(pStyDoc->pHPat,SD_PAT_OPTCOM,SD_gendoc_ocom,HPAT_REF_PAR); pStream = Stream_file(HP_getScanner(pStyDoc->pHPat),"",template,""); return HP_load(pStyDoc->pHPat,pStream,NULL,SD_PAT_CFGDFN,recursiv) && HP_check(pStyDoc->pHPat); } else return C_True; } static c_bool SD_load(StyDoc_T* ppStyDoc) /* load documentation base */ { PLR_Tab pTab; Scn_T pScn; Scn_Stream pStream; PT_Cfg pCfg; StyDoc_T pStyDoc; MAP(long,symbol) pPreParMap; SPP_T pPP; // init database pStyDoc = *ppStyDoc = SD_init_base(); // parse language definition pPreParMap = MAP_newPrimMap(); MAP_dfndom(pPreParMap,SPP_INC_PATH,stringToSymbol(styxpath)); pPP = SPP_init_reentrant(pPreParMap); Scn_get_styx(&pScn); pStream = Stream_file(pScn,"",infile,""); Stream_premac_set(pStream, SPP_premac); Stream_add_ctxval(pStream,stringToSymbol("SPP_premac"),pPP); pTab = PLR_get_styx(); pCfg = PT_init(pTab,pStream); pStyDoc->pTree = PT_PARSE(pCfg,""); PT_setErrorCnt(PT_synErrorCnt(pCfg)); PT_quit(pCfg); Stream_close(pStream); Stream_free(pStream); Scn_free(pScn); PLR_delTab(pTab); SPP_quit_reentrant(pPP); MAP_freeMap(pPreParMap); if( PT_errorCnt() == 0 ) { styxSource pSrc; GLS_Lst(styxQlxDfn) pQDfns; GLS_Lst(styxDfn) pDfns; GLS_Tok pIde; // fill documentation base styx_Start_Source(pStyDoc->pTree,&pSrc); styxSource_root(pSrc,&pIde,&pQDfns,&pDfns); SD_load_com(pStyDoc); SD_load_lex(pQDfns,pStyDoc); if( ! GLS_EMPTY(pDfns) ) { pStyDoc->pTab = PLR_getTab_env(binpath,GLS_Tok_string(pIde)); if( pStyDoc->pTab != (PLR_Tab)NULL && acfg_init_doc(pStyDoc->pTab, &pStyDoc->aPol,&pStyDoc->aNtm,&pStyDoc->aPrd) ) { SD_load_cfg(pStyDoc); return SD_load_pat(pStyDoc); } } else return SD_load_pat(pStyDoc); } return C_False; } static void SD_unload(StyDoc_T pStyDoc) /* unload documentation base */ { long lCnt = OT_CNT(pStyDoc->pDocBase)/2, lDom, lI; MAPIT pItr; ROW(PT_Term) pRng; if( pStyDoc->pTree != (PT_Term)NULL ) PT_delT(pStyDoc->pTree); if( pStyDoc->pTab != (PLR_Tab)NULL ) { acfg_quit(pStyDoc->pTab,pStyDoc->aPol,pStyDoc->aNtm,pStyDoc->aPrd); PLR_delTab(pStyDoc->pTab); } MAP_forItrAsg(lDom,pRng,pItr,pStyDoc->pDfnCom) OT_DEL_T(pRng); MAP_freeMap(pStyDoc->pDfnCom); MAP_forItrAsg(lDom,pRng,pItr,pStyDoc->pGrpCom) OT_DEL_T(pRng); MAP_freeMap(pStyDoc->pGrpCom); MAP_freeMap(pStyDoc->pGMap); MAP_freeMap(pStyDoc->pTMap); MAP_freeMap(pStyDoc->pNTMap); HS_DROP_SET(pStyDoc->pLSet); for( lI=0; lI < lCnt; ++lI ) OT_DEL_T(OT_GET(ROW(_),pStyDoc->pDocBase,2*lI+1)); OT_DEL_T(pStyDoc->pDocBase); if( pStyDoc->pHPat != (HPat_T)NULL ) HP_drop(pStyDoc->pHPat); FreeMem(pStyDoc); } /* ------------------------- Main --------------------------------------- */ int main(int argc, c_string argv[]) { StyDoc_T pStyDoc; SD_init(argc,argv); if( SD_load(&pStyDoc) ) { // generate language documentation if( strlen(outfile) > 0 ) pStyDoc->pSysOut = OpnFile(outfile,"wt"); else pStyDoc->pSysOut = stdout; if( pStyDoc->pHPat != (HPat_T)NULL ) SD_gendoc_cfg(pStyDoc->pHPat); else SD_gendoc_raw(pStyDoc); fclose(pStyDoc->pSysOut); } SD_unload(pStyDoc); SD_quit(); BUG_CORE; return(0); }