void Grammar::dumpFirst1Sets(FILE *f) const { const int maxLength = getMaxNonTerminalNameLength() + 1; for(int i = getTerminalCount(); i < getSymbolCount(); i++) { const GrammarSymbol &nt = getSymbol(i); _ftprintf(f, _T("%-*.*s:%s\n"), maxLength, maxLength, nt.m_name.cstr(), symbolSetToString(nt.m_first1).cstr()); } }
//! Returns STN_UNDEF if it cannot find a symbol at the given \a symbolAddress. unsigned StELFFile::getIndexOfSymbolAtAddress(uint32_t symbolAddress, bool strict) { unsigned symbolCount = getSymbolCount(); unsigned symbolIndex = 0; for (; symbolIndex < symbolCount; ++symbolIndex) { const Elf32_Sym &symbol = getSymbolAtIndex(symbolIndex); // the GHS toolchain puts in STT_FUNC symbols marking the beginning and ending of each // file. if the entry point happens to be at the beginning of the file, the beginning- // of-file symbol will have the same value and type. fortunately, the size of these // symbols is 0 (or seems to be). we also ignore symbols that start with two dots just // in case. if (symbol.st_value == symbolAddress && (strict && ELF32_ST_TYPE(symbol.st_info) == STT_FUNC && symbol.st_size != 0)) { std::string symbolName = getSymbolName(symbol); // ignore symbols that start with two dots if (symbolName[0] == '.' && symbolName[1] == '.') continue; // found the symbol! return symbolIndex; } } return STN_UNDEF; }
bool SymbolGroup::getSymbolParameters(CIDebugSymbolGroup *symbolGroup, SymbolParameterVector *vec, std::string *errorMessage) { ULONG count; return getSymbolCount(symbolGroup, &count, errorMessage) && getSymbolParameters(symbolGroup, 0, count, vec, errorMessage); }
int Grammar::getMaxNonTerminalNameLength() const { const int n = getSymbolCount(); int m = 0; for(int i = getTerminalCount(); i < n; i++) { const int l = (int)getSymbol(i).m_name.length(); if(l > m) { m = l; } } return m; }
ARMSymbolType_t StELFFile::getTypeOfSymbolAtIndex(unsigned symbolIndex) { ARMSymbolType_t symType = eARMSymbol; const Elf32_Sym &symbol = getSymbolAtIndex(symbolIndex); if (m_elfVariant == eGHSVariant) { if (symbol.st_other & STO_THUMB) symType = eThumbSymbol; } else { unsigned mappingSymStart = 1; unsigned mappingSymCount = getSymbolCount() - 1; // don't include first undefined symbol bool mapSymsFirst = (m_header.e_flags & EF_ARM_MAPSYMSFIRST) != 0; if (mapSymsFirst) { // first symbol '$m' is number of mapping syms const Elf32_Sym &mappingSymCountSym = getSymbolAtIndex(1); if (getSymbolName(mappingSymCountSym) == MAPPING_SYMBOL_COUNT_TAGSYM) { mappingSymCount = mappingSymCountSym.st_value; mappingSymStart = 2; } } uint32_t lastMappingSymAddress = 0; unsigned mappingSymIndex = mappingSymStart; for (; mappingSymIndex < mappingSymCount + mappingSymStart; ++mappingSymIndex) { const Elf32_Sym &mappingSym = getSymbolAtIndex(mappingSymIndex); std::string mappingSymName = getSymbolName(mappingSym); ARMSymbolType_t nextSymType = eUnknownSymbol; if (mappingSymName == ARM_SEQUENCE_MAPSYM) symType = eARMSymbol; else if (mappingSymName == DATA_SEQUENCE_MAPSYM) symType = eDataSymbol; else if (mappingSymName == THUMB_SEQUENCE_MAPSYM) symType = eThumbSymbol; if (nextSymType != eUnknownSymbol) { if (symbol.st_value >= lastMappingSymAddress && symbol.st_value < mappingSym.st_value) break; symType = nextSymType; lastMappingSymAddress = mappingSym.st_value; } } } return symType; }
void Grammar::dump(MarginFile *f) const { for(int i = 0; i < getSymbolCount(); i++) { const GrammarSymbol &sym = getSymbol(i); f->printf(_T("Symbol:%-20s, %4d %-11s "), sym.m_name.cstr(), sym.m_precedence, sym.getTypeString()); if(sym.m_reachable ) f->printf(_T("reachable ")); if(sym.m_terminate ) f->printf(_T("terminate ")); if(sym.m_deriveEpsilon) f->printf(_T("derive e ")); if(isNonTerminal(i)) { dump(sym.m_first1); } f->printf(_T("\n")); } for(int i = 0; i < getProductionCount(); i++) { dump(m_productions[i], f); f->printf(_T("\n")); } }
void StELFFile::dumpSymbolTable() { const char *symbolTypes[5] = { "NOTYPE", "OBJECT", "FUNC", "SECTION", "FILE" }; const char *symbolBinding[3] = { "LOCAL", "GLOBAL", "WEAK" }; unsigned count = getSymbolCount(); unsigned i = 0; for (; i < count; ++i) { const Elf32_Sym &symbol = getSymbolAtIndex(i); std::string name = getSymbolName(symbol); printf("'%s': %s, %s, 0x%08x, 0x%08x, %d. 0x%08x\n", name.c_str(), symbolTypes[ELF32_ST_TYPE(symbol.st_info)], symbolBinding[ELF32_ST_BIND(symbol.st_info)], symbol.st_value, symbol.st_size, symbol.st_shndx, symbol.st_other); } }
void StELFFile::byteSwapSymbolTable(const Elf32_Shdr &header, SectionDataInfo &info) { unsigned symbolCount = getSymbolCount(); unsigned i = 0; unsigned symbolOffset = 0; for (; i < symbolCount; ++i, symbolOffset += header.sh_entsize) { Elf32_Sym *symbol = reinterpret_cast<Elf32_Sym *>(&info.m_data[symbolOffset]); symbol->st_name = ENDIAN_LITTLE_TO_HOST_U32(symbol->st_name); symbol->st_value = ENDIAN_LITTLE_TO_HOST_U32(symbol->st_value); symbol->st_size = ENDIAN_LITTLE_TO_HOST_U32(symbol->st_size); symbol->st_shndx = ENDIAN_LITTLE_TO_HOST_U16(symbol->st_shndx); } // remember that we've byte swapped the symbols info.m_swapped = true; }
bool SymbolGroup::getSymbolParameters(CIDebugSymbolGroup *symbolGroup, unsigned long start, unsigned long count, SymbolParameterVector *vec, std::string *errorMessage) { if (!count) { vec->clear(); return true; } // Trim the count to the maximum count available. When expanding elements // and passing SubElements as count, SubElements might be an estimate that // is too large and triggers errors. ULONG totalCount; if (!getSymbolCount(symbolGroup, &totalCount, errorMessage)) return false; if (start >= totalCount) { std::ostringstream str; str << "SymbolGroup::getSymbolParameters: Start parameter " << start << " beyond total " << totalCount << '.'; *errorMessage = str.str(); return false; } if (start + count > totalCount) count = totalCount - start; // Get parameters. vec->resize(count); const HRESULT hr = symbolGroup->GetSymbolParameters(start, count, &(*vec->begin())); if (FAILED(hr)) { std::ostringstream str; str << "SymbolGroup::getSymbolParameters failed for index=" << start << ", count=" << count << ": " << msgDebugEngineComFailed("GetSymbolParameters", hr); *errorMessage = str.str(); return false; } return true; }
void Grammar::checkStateIsConsistent(const LR1State &state, StateResult &result) { BitSet symbolsDone(getSymbolCount()); const int itemCount = (int)state.m_items.size(); for(int i = 0; i < itemCount; i++) { const LR1Item &item = state.m_items[i]; if(isShiftItem(item)) { const int t = getShiftSymbol(item); if(symbolsDone.contains(t)) { continue; } for(int j = 0; j < itemCount; j++) { if(j == i) { continue; } const LR1Item &item1 = state.m_items[j]; if(isReduceItem(item1) && item1.m_la.contains(t)) { const GrammarSymbol &terminal = getSymbol(t); switch(resolveShiftReduceConflict(terminal, item1)) { case CONFLICT_NOT_RESOLVED: m_SRconflicts++; result.m_errors.add(format(_T("Shift/reduce conflict. Shift or reduce by prod %-3d (prec=%d) on '%s' (prec=%d, %s).") ,item1.m_prod ,getProduction(item1).m_precedence ,terminal.m_name.cstr() ,terminal.m_precedence ,terminal.getTypeString())); break; case CHOOSE_SHIFT: result.m_actions.add(ParserAction(t, item.getSuccessor())); symbolsDone += t; result.m_warnings.add(format(_T("Shift/reduce conflict on %s (prec=%d, %s). Choose shift instead of reduce by prod %d (prec=%d).") ,terminal.m_name.cstr() ,terminal.m_precedence ,terminal.getTypeString() ,item1.m_prod ,getProduction(item1).m_precedence)); m_warningCount++; break; case CHOOSE_REDUCE: result.m_actions.add(ParserAction(t, -item1.m_prod)); symbolsDone += t; result.m_warnings.add(format(_T("Shift/reduce conflict on %s (prec=%d, %s). Choose reduce by prod %d (prec=%d).") ,terminal.m_name.cstr() ,terminal.m_precedence ,terminal.getTypeString() ,item1.m_prod ,getProduction(item1).m_precedence)); m_warningCount++; break; } } } if(!symbolsDone.contains(t)) { if(item.m_succ >= 0) { result.m_actions.add(ParserAction(t, item.getSuccessor())); } symbolsDone += t; continue; } } } for(int i = 0; i < itemCount; i++) { const LR1Item &itemi = state.m_items[i]; if(isReduceItem(itemi)) { BitSet tokensReducedByOtherItems(getTerminalCount()); if(isAcceptItem(itemi)) { // check if this is start -> S . [EOI] result.m_actions.add(ParserAction(0, 0)); if(symbolsDone.contains(0)) { throwException(_T("Token EOI already done in state %d while generating Acceptitem"), state.m_index); } symbolsDone += 0; continue; } for(int j = 0; j < itemCount; j++) { if(j == i) { continue; } const LR1Item &itemj = state.m_items[j]; if(isReduceItem(itemj)) { const BitSet intersection(itemi.m_la & itemj.m_la); if(!intersection.isEmpty()) { if(itemj.m_prod < itemi.m_prod) { tokensReducedByOtherItems += intersection; result.m_warnings.add(format(_T("Reduce/reduce conflict on %s between prod %d and prod %d. Choose prod %d.") ,symbolSetToString(intersection).cstr() ,itemj.m_prod ,itemi.m_prod ,itemj.m_prod)); m_warningCount++; } } } } BitSet itemTokens(itemi.m_la - tokensReducedByOtherItems); for(Iterator<size_t> it = itemTokens.getIterator(); it.hasNext(); ) { const unsigned short t = (unsigned short)it.next(); if(!symbolsDone.contains(t)) { result.m_actions.add(ParserAction(t, -itemi.m_prod)); symbolsDone += t; } } } } for(int i = 0; i < itemCount; i++) { const LR1Item &itemi = state.m_items[i]; if(!isShiftItem(itemi) && !isReduceItem(itemi)) { const int nt = getShiftSymbol(itemi); if(!symbolsDone.contains(nt)) { if(itemi.getSuccessor() >= 0) { result.m_succs.add(ParserAction(nt, itemi.getSuccessor())); } symbolsDone += nt; } } } // for result.m_actions.sort(parserActionCompareToken); // sort actions by symbolnumber (lookahead symbol) result.m_succs.sort( parserActionCompareToken); // sort result by symbolnumber (nonTerminal) }
int Grammar::addNonTerminal(const String &name, const SourcePosition &pos) { return addSymbol(GrammarSymbol(getSymbolCount(), name, NONTERMINAL, 0, pos, getTerminalCount())); }
int Grammar::addTerminal(const String &name, SymbolType type, int precedence, const SourcePosition &pos) { m_terminalCount++; return addSymbol(GrammarSymbol(getSymbolCount(), name, type, precedence, pos, 1)); }
int Grammar::addSymbol(const GrammarSymbol &symbol) { const int index = getSymbolCount(); m_symbolMap.put(symbol.m_name, index); m_symbols.add(symbol); return index; }
void* Database::getSymbolHandle(unsigned int index) { if( index >= getSymbolCount() ) return 0; return &(base->symbols[index]); }