static void CcSyntax_CompFollowSets(CcSyntax_t * self) { CcSymbolNT_t * sym; CcArrayListIter_t iter; CcSymbolTable_t * symtab = &self->globals->symtab; CcArrayList_t * tarr = &symtab->terminals; CcArrayList_t * ntarr = &symtab->nonterminals; for (sym = (CcSymbolNT_t *)CcArrayList_First(ntarr, &iter); sym; sym = (CcSymbolNT_t *)CcArrayList_Next(ntarr, &iter)) { sym->follow = CcBitArray(&sym->followSpace, tarr->Count); sym->nts = CcBitArray(&sym->ntsSpace, ntarr->Count); } CcBitArray_Set(((CcSymbolNT_t *)self->gramSy)->follow, self->eofSy->kind, TRUE); self->visited = CcBitArray(&self->visitedSpace, self->base.nodes.Count); for (sym =(CcSymbolNT_t *)CcArrayList_First(ntarr, &iter); sym; sym = (CcSymbolNT_t *)CcArrayList_Next(ntarr, &iter)) { self->curSy = (CcSymbol_t *)sym; CcSyntax_CompFollow(self, sym->graph); } CcBitArray_Destruct(self->visited); self->visited = NULL; for (sym =(CcSymbolNT_t *)CcArrayList_First(ntarr, &iter); sym; sym = (CcSymbolNT_t *)CcArrayList_Next(ntarr, &iter)) { self->visited = CcBitArray(&self->visitedSpace, ntarr->Count); self->curSy = (CcSymbol_t *)sym; CcSyntax_Complete(self, sym); CcBitArray_Destruct(self->visited); self->visited = NULL; } }
static CcsBool_t SCSOS_UseSwitch(CcCSharpBaseOutputScheme_t * self, CcNode_t * p) { CcBitArray_t s1, s2; int nAlts; CcSyntax_t * syntax = &self->base.globals->syntax; CcArrayList_t * terminals = &self->base.globals->symtab.terminals; if (p->base.type != node_alt) return FALSE; nAlts = 0; CcBitArray(&s1, terminals->Count); while (p != NULL) { CcSyntax_Expected0(syntax, &s2, p->sub, self->curSy); if (CcBitArray_Intersect(&s1, &s2)) goto falsequit2; CcBitArray_Or(&s1, &s2); CcBitArray_Destruct(&s2); ++nAlts; if (p->sub->base.type == node_rslv) goto falsequit1; p = p->down; } CcBitArray_Destruct(&s1); return nAlts > 5; falsequit2: CcBitArray_Destruct(&s2); falsequit1: CcBitArray_Destruct(&s1); return FALSE; }
/*------------- check if resolvers are legal --------------------*/ static void CcSyntax_CheckRes(CcSyntax_t * self, CcNode_t * p, CcsBool_t rslvAllowed) { CcNode_t * q; CcBitArray_t expected, soFar, fs, fsNext; CcSymbolTable_t * symtab = &self->globals->symtab; while (p != NULL) { if (p->base.type == node_alt) { CcBitArray(&expected, symtab->terminals.Count); for (q = p; q != NULL; q = q->down) { CcSyntax_Expected0(self, &fs, q->sub, self->curSy); CcBitArray_Or(&expected, &fs); CcBitArray_Destruct(&fs); } CcBitArray(&soFar, symtab->terminals.Count); for (q = p; q != NULL; q = q->down) { if (q->sub->base.type == node_rslv) { CcSyntax_Expected(self, &fs, q->sub->next, self->curSy); if (CcBitArray_Intersect(&fs, &soFar)) CcsErrorPool_Warning(self->globals->errpool, NULL, "Resolver will never be evaluated. " "Place it at previous conflicting alternative."); if (!CcBitArray_Intersect(&fs, &expected)) CcsErrorPool_Warning(self->globals->errpool, NULL, "Misplaced resolver: no LL(1) conflict."); CcBitArray_Destruct(&fs); } else { CcSyntax_Expected(self, &fs, q->sub, self->curSy); CcBitArray_Or(&soFar, &fs); CcBitArray_Destruct(&fs); } CcSyntax_CheckRes(self, q->sub, TRUE); } CcBitArray_Destruct(&expected); CcBitArray_Destruct(&soFar); } else if (p->base.type == node_iter || p->base.type == node_opt) { if (p->sub->base.type == node_rslv) { CcSyntax_First(self, &fs, p->sub->next); CcSyntax_Expected(self, &fsNext, p->next, self->curSy); if (!CcBitArray_Intersect(&fs, &fsNext)) CcsErrorPool_Warning(self->globals->errpool, NULL, "Misplaced resolver: no LL(1) conflict."); } CcSyntax_CheckRes(self, p->sub, TRUE); } else if (p->base.type == node_rslv) { if (!rslvAllowed) CcsErrorPool_Warning(self->globals->errpool, NULL, "Misplaced resolver: no alternative."); } if (p->up) break; p = p->next; rslvAllowed = FALSE; } }
void CcSyntax_Destruct(CcSyntax_t * self) { CcArrayList_Destruct(&self->errors); if (self->allSyncSets) CcBitArray_Destruct(self->allSyncSets); if (self->visited) CcBitArray_Destruct(self->visited); if (self->grammarPrefix) CcFree(self->grammarPrefix); if (self->schemeName) CcFree(self->schemeName); if (self->destructor) CcsPosition_Destruct(self->destructor); if (self->constructor) CcsPosition_Destruct(self->constructor); if (self->members) CcsPosition_Destruct(self->members); CcEBNF_Destruct(&self->base); }
static CcsBool_t CcSyntax_AllNtToTerm(CcSyntax_t * self) { CcBitArray_t mark; CcSymbolNT_t * sym; CcArrayListIter_t iter; CcsBool_t changed, ok = TRUE; CcSymbolTable_t * symtab = &self->globals->symtab; CcArrayList_t * ntarr = &symtab->nonterminals; CcBitArray(&mark, ntarr->Count); do { changed = FALSE; for (sym = (CcSymbolNT_t *)CcArrayList_First(ntarr, &iter); sym; sym = (CcSymbolNT_t *)CcArrayList_Next(ntarr, &iter)) { if (!CcBitArray_Get(&mark, sym->base.kind) && CcSyntax_IsTerm(self, sym->graph, &mark)) { CcBitArray_Set(&mark, sym->base.kind, TRUE); changed = TRUE; } } } while (changed); for (sym = (CcSymbolNT_t *)CcArrayList_First(ntarr, &iter); sym; sym = (CcSymbolNT_t *)CcArrayList_Next(ntarr, &iter)) { if (!CcBitArray_Get(&mark, sym->base.kind)) { ok = FALSE; CcsErrorPool_Error(self->globals->errpool, NULL, " %s cannot be derived to terminals", sym->base.name); } } CcBitArray_Destruct(&mark); return ok; }
static CcsBool_t CSOS_Productions(CcCSharpBaseOutputScheme_t * self, CcOutput_t * output) { CcBitArray_t isChecked; CcArrayListIter_t iter; const CcSymbolNT_t * sym; const CcArrayList_t * nonterminals = &self->base.globals->symtab.nonterminals; CcBitArray(&isChecked, self->base.globals->symtab.terminals.Count); for (sym = (const CcSymbolNT_t *)CcArrayList_FirstC(nonterminals, &iter); sym; sym = (const CcSymbolNT_t *)CcArrayList_NextC(nonterminals, &iter)) { self->curSy = (const CcSymbol_t *)sym; if (sym->attrPos == NULL) { CcPrintfIL(output, "private void %s()", sym->base.name); } else { CcPrintfIL(output, "private void %s(%s)", sym->base.name, sym->attrPos->text); } CcPrintfIL(output, "{"); output->indent += 4; if (sym->semPos) CcSource(output, sym->semPos); SCSOS_GenCode(self, output, sym->graph, &isChecked); output->indent -= 4; CcPrintfIL(output, "}"); CcPrintfL(output, ""); } CcBitArray_Destruct(&isChecked); return TRUE; }
void CcSyntaxSymSet_Destruct(CcSyntaxSymSet_t * self) { CcBitArray_t * cur; for (cur = self->start; cur < self->used; ++cur) CcBitArray_Destruct(cur); CcFree(self->start); }
static void ATest(FILE * fp, CcBitArray_t * ba0, CcBitArray_t * ba1) { CcBitArray_t ba2; int idx, cnt, numbits = CcBitArray_getCount(ba0); CcBitArray_Dump(ba0, fp, "BitArray 0: ", "\n"); CcBitArray_Dump(ba1, fp, "BitArray 1: ", "\n"); cnt = 0; for (idx = 0; idx < numbits; ++idx) if (CcBitArray_Get(ba0, idx) && CcBitArray_Get(ba1, idx)) cnt = 1; COCO_ASSERT((CcBitArray_Intersect(ba0, ba1) == cnt)); COCO_ASSERT((CcBitArray_Clone(&ba2, ba0))); COCO_ASSERT((CcBitArray_Equal(ba0, &ba2))); cnt = 0; for (idx = 0; idx < numbits; ++idx) { COCO_ASSERT(CcBitArray_Get(ba0, idx) == CcBitArray_Get(&ba2, idx)); if (CcBitArray_Get(ba0, idx)) ++cnt; } COCO_ASSERT((CcBitArray_Elements(ba0) == cnt)); COCO_ASSERT((CcBitArray_Or(&ba2, ba1) == 0)); CcBitArray_Dump(&ba2, fp, "Or: ", "\n"); for (idx = 0; idx < numbits; ++idx) COCO_ASSERT((CcBitArray_Get(ba0, idx) || CcBitArray_Get(ba1, idx)) == CcBitArray_Get(&ba2, idx)); CcBitArray_Destruct(&ba2); COCO_ASSERT((CcBitArray_Clone(&ba2, ba0))); COCO_ASSERT((CcBitArray_And(&ba2, ba1) == 0)); CcBitArray_Dump(&ba2, fp, "And: ", "\n"); for (idx = 0; idx < numbits; ++idx) COCO_ASSERT((CcBitArray_Get(ba0, idx) && CcBitArray_Get(ba1, idx)) == CcBitArray_Get(&ba2, idx)); CcBitArray_Destruct(&ba2); COCO_ASSERT((CcBitArray_Clone(&ba2, ba0))); CcBitArray_Subtract(&ba2, ba1); CcBitArray_Dump(&ba2, fp, "Subtract: ", "\n"); for (idx = 0; idx < numbits; ++idx) COCO_ASSERT((CcBitArray_Get(ba0, idx) && !CcBitArray_Get(ba1, idx)) == CcBitArray_Get(&ba2, idx)); COCO_ASSERT(!CcBitArray_Intersect(ba1, &ba2)); CcBitArray_Destruct(&ba2); fprintf(fp, "\n"); }
static void CcSyntax_First0(CcSyntax_t * self, CcBitArray_t * ret, CcNode_t * p, CcBitArray_t * mark) { CcBitArray_t fs0; CcSymbolTable_t * symtab = &self->globals->symtab; CcBitArray(ret, symtab->terminals.Count); while (p != NULL && !CcBitArray_Get(mark, p->base.index)) { CcBitArray_Set(mark, p->base.index, TRUE); if (p->base.type == node_nt) { CcNodeNT_t * p0 = (CcNodeNT_t *)p; CcSymbolNT_t * sym = (CcSymbolNT_t *)p0->sym; if (sym->firstReady) { CcBitArray_Or(ret, sym->first); } else { CcSyntax_First0(self, &fs0, sym->graph, mark); CcBitArray_Or(ret, &fs0); CcBitArray_Destruct(&fs0); } } else if (p->base.type == node_t) { CcNodeT_t * p0 = (CcNodeT_t *)p; CcBitArray_Set(ret, p0->sym->kind, TRUE); } else if (p->base.type == node_wt) { CcNodeWT_t * p0 = (CcNodeWT_t *)p; CcBitArray_Set(ret, p0->sym->kind, TRUE); } else if (p->base.type == node_any) { CcNodeANY_t * p0 = (CcNodeANY_t *)p; CcBitArray_Or(ret, p0->set); } else if (p->base.type == node_alt) { CcSyntax_First0(self, &fs0, p->sub, mark); CcBitArray_Or(ret, &fs0); CcBitArray_Destruct(&fs0); CcSyntax_First0(self, &fs0, p->down, mark); CcBitArray_Or(ret, &fs0); CcBitArray_Destruct(&fs0); } else if (p->base.type == node_iter || p->base.type == node_opt) { CcSyntax_First0(self, &fs0, p->sub, mark); CcBitArray_Or(ret, &fs0); CcBitArray_Destruct(&fs0); } if (!CcNode_DelNode(p)) break; p = p->next; } }
void CcSyntax_First(CcSyntax_t * self, CcBitArray_t * ret, CcNode_t * p) { CcBitArray_t fs0; CcBitArray(&fs0, self->base.nodes.Count); CcSyntax_First0(self, ret, p, &fs0); CcBitArray_Destruct(&fs0); }
static void CcXmlSpec_Destruct(CcObject_t * self) { CcXmlSpec_t * ccself = (CcXmlSpec_t *)self; CcArrayList_Destruct(&ccself->PInstructions); CcArrayList_Destruct(&ccself->Attrs); CcArrayList_Destruct(&ccself->Tags); CcBitArray_Destruct(&ccself->options); CcObject_Destruct(self); }
/* FIX ME */ static void CcSyntax_CheckAlts(CcSyntax_t * self, CcNode_t * p) { CcBitArray_t s1, s2; CcNode_t * q; CcSymbolTable_t * symtab = &self->globals->symtab; while (p != NULL) { if (p->base.type == node_alt) { q = p; CcBitArray(&s1, symtab->terminals.Count); while (q != NULL) { /* For all alternatives */ CcSyntax_Expected0(self, &s2, q->sub, self->curSy); CcSyntax_CheckOverlap(self, &s1, &s2, 1); CcBitArray_Or(&s1, &s2); CcSyntax_CheckAlts(self, q->sub); q = q->down; CcBitArray_Destruct(&s2); } CcBitArray_Destruct(&s1); } else if (p->base.type == node_opt || p->base.type == node_iter) { /* E.g. [[...]] */ if (CcNode_DelSubGraph(p->sub)) { CcSyntax_LL1Error(self, 4, NULL); } else { CcSyntax_Expected0(self, &s1, p->sub, self->curSy); CcSyntax_Expected(self, &s2, p->next, self->curSy); CcSyntax_CheckOverlap(self, &s1, &s2, 2); CcSyntax_CheckAlts(self, p->sub); CcBitArray_Destruct(&s1); CcBitArray_Destruct(&s2); } } else if (p->base.type == node_any) { /* E.g. {ANY} ANY or [ANY] ANY */ if (CcBitArray_Elements(((CcNodeANY_t *)p)->set) == 0) CcSyntax_LL1Error(self, 3, NULL); } if (p->up) break; p = p->next; } }
static void CcSyntax_FindAS(CcSyntax_t * self, CcNode_t * p) { CcNode_t * a, * q; CcBitArray_t s0, s1; CcSymbolTable_t * symtab = &self->globals->symtab; while (p != NULL) { if (p->base.type == node_opt || p->base.type == node_iter) { CcSyntax_FindAS(self, p->sub); a = CcSyntax_LeadingAny(self, p->sub); if (a != NULL) { CcSyntax_First(self, &s0, p->next); CcBitArray_Subtract(((CcNodeANY_t *)a)->set, &s0); CcBitArray_Destruct(&s0); } } else if (p->base.type == node_alt) { CcBitArray(&s1, symtab->terminals.Count); q = p; while (q != NULL) { CcSyntax_FindAS(self, q->sub); a = CcSyntax_LeadingAny(self, q->sub); if (a != NULL) { CcSyntax_First(self, &s0, q->down); CcBitArray_Or(&s0, &s1); CcBitArray_Subtract(((CcNodeANY_t *)a)->set, &s0); CcBitArray_Destruct(&s0); } else { CcSyntax_First(self, &s0, q->sub); CcBitArray_Or(&s1, &s0); CcBitArray_Destruct(&s0); } q = q->down; } CcBitArray_Destruct(&s1); } if (p->up) break; p = p->next; } }
static void CcSyntax_CompSyncSets(CcSyntax_t * self) { CcSymbolNT_t * sym; CcArrayListIter_t iter; CcSymbolTable_t * symtab = &self->globals->symtab; CcArrayList_t * ntarr = &symtab->nonterminals; self->allSyncSets = CcBitArray(&self->allSyncSetsSpace, symtab->terminals.Count); CcBitArray_Set(self->allSyncSets, self->eofSy->kind, TRUE); self->visited = CcBitArray(&self->visitedSpace, self->base.nodes.Count); for (sym = (CcSymbolNT_t *)CcArrayList_First(ntarr, &iter); sym; sym = (CcSymbolNT_t *)CcArrayList_Next(ntarr, &iter)) { self->curSy = (CcSymbol_t *)sym; CcSyntax_CompSync(self, sym->graph); } CcBitArray_Destruct(self->visited); self->visited = NULL; }
static void CcSyntax_CompFirstSets(CcSyntax_t * self) { CcBitArray_t fs; CcSymbolNT_t * sym; CcArrayListIter_t iter; CcSymbolTable_t * symtab = &self->globals->symtab; CcArrayList_t * ntarr = &symtab->nonterminals; for (sym = (CcSymbolNT_t *)CcArrayList_First(ntarr, &iter); sym; sym = (CcSymbolNT_t *)CcArrayList_Next(ntarr, &iter)) { sym->first = CcBitArray(&sym->firstSpace, symtab->terminals.Count); sym->firstReady = FALSE; } for (sym = (CcSymbolNT_t *)CcArrayList_First(ntarr, &iter); sym; sym = (CcSymbolNT_t *)CcArrayList_Next(ntarr, &iter)) { CcSyntax_First(self, &fs, sym->graph); CcBitArray_Destruct(sym->first); memcpy(sym->first, &fs, sizeof(fs)); sym->firstReady = TRUE; } }
static void CcSyntax_CompFollow(CcSyntax_t * self, CcNode_t * p) { CcBitArray_t s; CcSymbolNT_t * sym; while (p != NULL && !CcBitArray_Get(self->visited, p->base.index)) { CcBitArray_Set(self->visited, p->base.index, TRUE); if (p->base.type == node_nt) { CcSyntax_First(self, &s, p->next); sym = (CcSymbolNT_t *)((CcNodeNT_t *)p)->sym; CcBitArray_Or(sym->follow, &s); CcBitArray_Destruct(&s); if (CcNode_DelGraph(p->next)) CcBitArray_Set(sym->nts, self->curSy->kind, TRUE); } else if (p->base.type == node_opt || p->base.type == node_iter) { CcSyntax_CompFollow(self, p->sub); } else if (p->base.type == node_alt) { CcSyntax_CompFollow(self, p->sub); CcSyntax_CompFollow(self, p->down); } p = p->next; } }
void TestBitArray(FILE * fp) { int idx, numbits; CcBitArray_t ba0, ba1, ba2; for (numbits = 0; numbits < 32; ++numbits) { COCO_ASSERT((CcBitArray(&ba0, numbits))); COCO_ASSERT((CcBitArray(&ba1, numbits))); ATest(fp, &ba0, &ba1); CcBitArray_Destruct(&ba0); CcBitArray_Destruct(&ba1); COCO_ASSERT((CcBitArray(&ba0, numbits))); CcBitArray_SetAll(&ba0, 1); COCO_ASSERT((CcBitArray(&ba1, numbits))); ATest(fp, &ba0, &ba1); CcBitArray_Destruct(&ba0); CcBitArray_Destruct(&ba1); COCO_ASSERT((CcBitArray(&ba0, numbits))); COCO_ASSERT((CcBitArray(&ba1, numbits))); CcBitArray_SetAll(&ba1, 1); ATest(fp, &ba0, &ba1); CcBitArray_Destruct(&ba0); CcBitArray_Destruct(&ba1); COCO_ASSERT((CcBitArray(&ba0, numbits))); CcBitArray_SetAll(&ba0, 1); COCO_ASSERT((CcBitArray(&ba1, numbits))); CcBitArray_SetAll(&ba1, 1); ATest(fp, &ba0, &ba1); CcBitArray_Destruct(&ba0); CcBitArray_Destruct(&ba1); for (idx = 0; idx < 128; ++idx) { COCO_ASSERT((CcBitArray(&ba0, numbits))); CcBitArray_RandomSet(&ba0); COCO_ASSERT((CcBitArray(&ba1, numbits))); CcBitArray_RandomSet(&ba1); ATest(fp, &ba0, &ba1); COCO_ASSERT((CcBitArray_Clone(&ba2, &ba0))); CcBitArray_Subtract(&ba2, &ba1); ATest(fp, &ba0, &ba2); ATest(fp, &ba2, &ba0); ATest(fp, &ba1, &ba2); ATest(fp, &ba2, &ba1); CcBitArray_Destruct(&ba0); CcBitArray_Destruct(&ba1); CcBitArray_Destruct(&ba2); } } }
static void SCSOS_GenCode(CcCSharpBaseOutputScheme_t * self, CcOutput_t * output, CcNode_t * p, const CcBitArray_t * IsChecked) { int err; CcsBool_t equal, useSwitch; int index; CcNode_t * p2; CcBitArray_t s1, s2, isChecked; CcNodeNT_t * pnt; CcNodeT_t * pt; CcNodeWT_t * pwt; CcNodeSEM_t * psem; CcNodeSYNC_t * psync; CcSyntax_t * syntax = &self->base.globals->syntax; CcArrayList_t * terminals = &self->base.globals->symtab.terminals; CcBitArray_Clone(&isChecked, IsChecked); while (p != NULL) { if (p->base.type == node_nt) { pnt = (CcNodeNT_t *)p; if (pnt->pos) { CcPrintfIL(output, "%s(%s);", pnt->sym->name, pnt->pos->text); } else { CcPrintfIL(output, "%s();", pnt->sym->name); } } else if (p->base.type == node_t) { pt = (CcNodeT_t *)p; if (CcBitArray_Get(&isChecked, pt->sym->kind)) CcPrintfIL(output, "Get();"); else CcPrintfIL(output, "Expect(%d);", pt->sym->kind); } else if (p->base.type == node_wt) { pwt = (CcNodeWT_t *)p; CcSyntax_Expected(syntax, &s1, p->next, self->curSy); CcBitArray_Or(&s1, syntax->allSyncSets); CcPrintfIL(output, "ExpectWeak(%d, %d);", pwt->sym->kind, CcSyntaxSymSet_New(&self->symSet, &s1)); CcBitArray_Destruct(&s1); } else if (p->base.type == node_any) { CcPrintfIL(output, "Get();"); } else if (p->base.type == node_eps) { } else if (p->base.type == node_rslv) { } else if (p->base.type == node_sem) { psem = (CcNodeSEM_t *)p; CcSource(output, psem->pos); } else if (p->base.type == node_sync) { psync = (CcNodeSYNC_t *)p; err = CcSyntax_SyncError(syntax, self->curSy); CcBitArray_Clone(&s1, psync->set); SCSOS_GenCond(self, output, "while (!(", ")) {", &s1, p); output->indent += 4; CcPrintfIL(output, "SynErr(%d); Get();", err); output->indent -= 4; CcPrintfIL(output, "}"); CcBitArray_Destruct(&s1); } else if (p->base.type == node_alt) { CcSyntax_First(syntax, &s1, p); equal = CcBitArray_Equal(&s1, &isChecked); CcBitArray_Destruct(&s1); useSwitch = SCSOS_UseSwitch(self, p); if (useSwitch) CcPrintfIL(output, "switch (la.kind) {"); p2 = p; while (p2 != NULL) { CcSyntax_Expected(syntax, &s1, p2->sub, self->curSy); if (useSwitch) { CcPrintfI(output, ""); for (index = 0; index < terminals->Count; ++index) if (CcBitArray_Get(&s1, index)) CcPrintf(output, "case %d: ", index); CcPrintfL(output,"{"); } else if (p2 == p) { SCSOS_GenCond(self, output, "if (", ") {", &s1, p2->sub); } else if (p2->down == NULL && equal) { CcPrintfIL(output, "} else {"); } else { SCSOS_GenCond(self, output, "} else if (", ") {", &s1, p2->sub); } CcBitArray_Or(&s1, &isChecked); output->indent += 4; SCSOS_GenCode(self, output, p2->sub, &s1); if (useSwitch) CcPrintfIL(output, "break;"); output->indent -= 4; if (useSwitch) CcPrintfIL(output, "}"); p2 = p2->down; CcBitArray_Destruct(&s1); } if (equal) { CcPrintfIL(output, "}"); } else { err = CcSyntax_AltError(syntax, self->curSy); if (useSwitch) { CcPrintfIL(output, "default: SynErr(%d); break;", err); CcPrintfIL(output, "}"); } else { CcPrintfIL(output, "} else SynErr(%d);", err); } } } else if (p->base.type == node_iter) { p2 = p->sub; if (p2->base.type == node_wt) { CcSyntax_Expected(syntax, &s1, p2->next, self->curSy); CcSyntax_Expected(syntax, &s2, p->next, self->curSy); CcPrintfIL(output, "while (WeakSeparator(%d, %d, %d)) {", ((CcNodeWT_t *)p2)->sym->kind, CcSyntaxSymSet_New(&self->symSet, &s1), CcSyntaxSymSet_New(&self->symSet, &s2)); CcBitArray_Destruct(&s1); CcBitArray_Destruct(&s2); CcBitArray(&s1, terminals->Count); if (p2->up || p2->next == NULL) p2 = NULL; else p2 = p2->next; } else { CcSyntax_First(syntax, &s1, p2); SCSOS_GenCond(self, output, "while (", ") {", &s1, p2); } output->indent += 4; SCSOS_GenCode(self, output, p2, &s1); output->indent -= 4; CcPrintfIL(output, "}"); CcBitArray_Destruct(&s1); } else if (p->base.type == node_opt) { CcSyntax_First(syntax, &s1, p->sub); SCSOS_GenCond(self, output, "if (", ") {", &s1, p->sub); output->indent += 4; SCSOS_GenCode(self, output, p->sub, &s1); output->indent -= 4; CcPrintfIL(output, "}"); CcBitArray_Destruct(&s1); } if (p->base.type != node_eps && p->base.type != node_sem && p->base.type != node_sync) CcBitArray_SetAll(&isChecked, FALSE); if (p->up) break; p = p->next; } CcBitArray_Destruct(&isChecked); }
static CcsBool_t CcSyntax_NoCircularProductions(CcSyntax_t * self) { CcBitArray_t singles; SymbolPair_t * firstPair, * prevPair, * curPair, * curPair0; CcSymbolNT_t * sym; CcArrayListIter_t iter; int index; CcsBool_t ok, changed, onLeftSide, onRightSide; CcSymbol_t * leftsym, * rightsym; CcSymbolTable_t * symtab = &self->globals->symtab; CcArrayList_t * ntarr = &symtab->nonterminals; firstPair = NULL; CcBitArray(&singles, ntarr->Count); for (sym = (CcSymbolNT_t *)CcArrayList_First(ntarr, &iter); sym; sym = (CcSymbolNT_t *)CcArrayList_Next(ntarr, &iter)) { CcBitArray_SetAll(&singles, FALSE); /* Get nonterminals s such that sym-->s */ GetSingles(&singles, sym->graph); for (index = 0; index < ntarr->Count; ++index) { if (!CcBitArray_Get(&singles, index)) continue; curPair = CcMalloc(sizeof(SymbolPair_t)); curPair->left = sym->base.kind; curPair->right = index; curPair->next = firstPair; firstPair = curPair; } } CcBitArray_Destruct(&singles); do { changed = FALSE; prevPair = NULL; curPair = firstPair; while (curPair) { onLeftSide = FALSE; onRightSide = FALSE; for (curPair0 = curPair; curPair0; curPair0 = curPair0->next) { if (curPair->left == curPair0->right) onRightSide = TRUE; if (curPair->right == curPair0->left) onLeftSide = TRUE; } if (onLeftSide && onRightSide) { /* Circular Production found. */ prevPair = curPair; curPair = curPair->next; } else { /* Remove non-circular nonterminal symbol pair. */ curPair0 = curPair->next; if (prevPair == NULL) firstPair = curPair0; else prevPair->next = curPair0; CcFree(curPair); curPair = curPair0; changed = TRUE; } } } while (changed); ok = TRUE; for (curPair = firstPair; curPair; curPair = curPair0) { ok = FALSE; leftsym = (CcSymbol_t *)CcArrayList_Get(ntarr, curPair->left); rightsym = (CcSymbol_t *)CcArrayList_Get(ntarr, curPair->right); CcsErrorPool_Error(self->globals->errpool, NULL, " '%s' --> '%s'", leftsym->name, rightsym->name); curPair0 = curPair->next; CcFree(curPair); } return ok; }