/*------------- 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; } }
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; }
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"); }