void CcXmlSpec_MakeTerminals(const CcXmlSpec_t * self, CcGlobals_t * globals) { char EndTag[128]; CcArrayListIter_t iter; const CcXmlData_t * data; CcSymbolTable_t * symtab = &globals->symtab; for (data = (const CcXmlData_t *)CcArrayList_FirstC(&self->Tags, &iter); data; data = (const CcXmlData_t *)CcArrayList_NextC(&self->Tags, &iter)) { if (!CcSymbolTable_NewTerminalWithCheck(symtab, data->tokenName, data->loc.line)) CcsErrorPool_Error(globals->errpool, &data->loc, "Symbol %s is defined twice.\n", data->tokenName); snprintf(EndTag, sizeof(EndTag), "END_%s", data->tokenName); if (!CcSymbolTable_NewTerminalWithCheck(symtab, EndTag, data->loc.line)) CcsErrorPool_Error(globals->errpool, &data->loc, "Symbol %s is defined twice.\n", EndTag); } for (data = (const CcXmlData_t *)CcArrayList_FirstC(&self->Attrs, &iter); data; data = (const CcXmlData_t *)CcArrayList_NextC(&self->Attrs, &iter)) if (!CcSymbolTable_NewTerminalWithCheck(symtab, data->tokenName, data->loc.line)) CcsErrorPool_Error(globals->errpool, &data->loc, "Symbol %s is defined twice.\n", data->tokenName); for (data = (const CcXmlData_t *)CcArrayList_FirstC(&self->PInstructions, &iter); data; data = (const CcXmlData_t *)CcArrayList_NextC(&self->PInstructions, &iter)) if (!CcSymbolTable_NewTerminalWithCheck(symtab, data->tokenName, data->loc.line)) CcsErrorPool_Error(globals->errpool, &data->loc, "Symbol %s is defined twice.\n", data->tokenName); }
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; }
void CcXmlSpec_SetOption(CcXmlSpec_t * self, const CcsToken_t * token) { CcsXmlSpecOption_t option; for (option = XSO_UnknownTag; option < XSO_SIZE; ++option) if (!strcmp(token->val, CcsXmlSpecOptionNames[option])) { CcBitArray_Set(&self->options, option, TRUE); return; } CcsErrorPool_Error(self->globals->errpool, &token->loc, "Unrecognized option '%s' encountered.", token->val); }
/*------------- check if every nts has a production --------------------*/ static CcsBool_t CcSyntax_NtsComplete(CcSyntax_t * self) { int idx; CcSymbolNT_t * sym; CcsBool_t complete = TRUE; CcSymbolTable_t * symtab = &self->globals->symtab; for (idx = 0; idx < symtab->nonterminals.Count; ++idx) { sym = (CcSymbolNT_t *)CcArrayList_Get(&symtab->nonterminals, idx); if (sym->graph == NULL) { complete = FALSE; CcsErrorPool_Error(self->globals->errpool, NULL, "No production for %s", sym->base.name); } } return complete; }
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; }
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; }