예제 #1
0
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;
    }
}
예제 #2
0
/*------------- 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;
    }
}
예제 #3
0
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;
}
예제 #4
0
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;
}
예제 #5
0
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;
}
예제 #6
0
void
CcSyntax_Expected0(CcSyntax_t * self, CcBitArray_t * ret,
		   CcNode_t * p, const CcSymbol_t * curSy)
{
    CcSymbolTable_t * symtab = &self->globals->symtab;
    if (p->base.type == node_rslv) CcBitArray(ret, symtab->terminals.Count);
    else CcSyntax_Expected(self, ret, p, curSy);
}
예제 #7
0
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;
}
예제 #8
0
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);
}
예제 #9
0
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);
	}
    }
}
예제 #10
0
CcXmlSpec_t *
CcXmlSpec(CcGlobals_t * globals)
{
    CcXmlSpec_t * self = (CcXmlSpec_t *)CcObject(&XmlSpecType);
    self->globals = globals;
    self->caseSensitive = TRUE;
    CcBitArray(&self->options, XSO_SIZE);
    CcArrayList(&self->Tags);
    CcArrayList(&self->Attrs);
    CcArrayList(&self->PInstructions);
    return self;
}
예제 #11
0
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;
    }
}
예제 #12
0
static CcsBool_t
CcSyntax_AllNtReached(CcSyntax_t * self)
{
    int idx; CcSymbol_t * sym;
    CcsBool_t ok = TRUE;
    CcSymbolTable_t * symtab = &self->globals->symtab;

    self->visited = CcBitArray(&self->visitedSpace,
			       symtab->nonterminals.Count);
    CcBitArray_Set(self->visited, self->gramSy->kind, TRUE);
    CcSyntax_MarkReachedNts(self, ((CcSymbolNT_t *)self->gramSy)->graph);
    for (idx = 0; idx < symtab->nonterminals.Count; ++idx) {
	sym = (CcSymbol_t *)CcArrayList_Get(&symtab->nonterminals, idx);
	if (!CcBitArray_Get(self->visited, sym->kind)) {
	    ok = FALSE;
	    CcsErrorPool_Error(self->globals->errpool, NULL,
			       " '%s' cannot be reached", sym->name);
	}
    }
    return ok;
}
예제 #13
0
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;
    }
}
예제 #14
0
/* 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;
    }
}
예제 #15
0
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;
    }
}
예제 #16
0
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;
}
예제 #17
0
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);
}