LogVars ConstraintTree::expand (LogVar X) { moveToBottom ({X}); assert (isCountNormalized (X)); CTNodes nodes = getNodesAtLevel (logVars_.size() - 1); unsigned nrSymbols = getConditionalCount (X); for (CTNodes::const_iterator it = nodes.begin(); it != nodes.end(); ++ it) { Symbols symbols; const CTChilds& childs = (*it)->childs(); for (CTChilds::const_iterator chIt = childs.begin(); chIt != childs.end(); ++ chIt) { symbols.push_back ((*chIt)->symbol()); } (*it)->removeAndDeleteAllChilds(); CTNode* prev = *it; assert (symbols.size() == nrSymbols); for (size_t j = 0; j < nrSymbols; j++) { CTNode* newNode = new CTNode (symbols[j], (*it)->level() + j); prev->mergeSubtree (newNode); prev = newNode; } } LogVars newLvs; logVars_.pop_back(); for (size_t i = 0; i < nrSymbols; i++) { logVars_.push_back (LogVar (logVarSet_.back() + 1)); newLvs.push_back (LogVar (logVarSet_.back() + 1)); logVarSet_.insert (LogVar (logVarSet_.back() + 1)); } logVarSet_ -= X; return newLvs; }
// This builds a reduced version of a graph, where there // is only a new node if the number of non-array SYMBOLS // in the descendents changes. For example (EXTRACT 0 1 n) // will have the same "Symbols" node as n, because // no new symbols are introduced. Symbols* VariablesInExpression::getSymbol(const ASTNode& n) { if (symbol_graph.find(n.GetNodeNum()) != symbol_graph.end()) { return symbol_graph[n.GetNodeNum()]; } Symbols* node; // Note we skip array variables. We never solve for them so // can ignore them. if (n.GetKind() == SYMBOL && n.GetIndexWidth() == 0) { node = new Symbols(n); insert(n, node); return node; } vector<Symbols*> children; for (size_t i = 0; i < n.Degree(); i++) { Symbols* v = getSymbol(n[i]); if (!v->empty()) children.push_back(v); } if (children.size() == 1) { // If there is only a single child with a symbol. Then jump to it. node = children.back(); } else node = new Symbols(children); insert(n, node); return node; }
Symbols Preprocessor::preprocessed(const QByteArray &filename, QIODevice *file) { QByteArray input = file->readAll(); if (input.isEmpty()) return symbols; // phase 1: get rid of backslash-newlines input = cleaned(input); // phase 2: tokenize for the preprocessor symbols = tokenize(input); #if 0 for (int j = 0; j < symbols.size(); ++j) fprintf(stderr, "line %d: %s(%s)\n", symbols[j].lineNum, symbols[j].lexem().constData(), tokenTypeName(symbols[j].token)); #endif // phase 3: preprocess conditions and substitute macros Symbols result; preprocess(filename, result); #if 0 for (int j = 0; j < result.size(); ++j) fprintf(stderr, "line %d: %s(%s)\n", result[j].lineNum, result[j].lexem().constData(), tokenTypeName(result[j].token)); #endif return result; }
void xl_enter_block(Context *context, text name, native_fn fn, Tree *rtype, text open, text type, text close, text doc) // ---------------------------------------------------------------------------- // Enter a block into the context (called from .tbl files) // ---------------------------------------------------------------------------- { Tree *parms = xl_parameter("c", type); Block *from = new Block(parms, open, close); Name *to = new Name(open + close); from = new Block(from, open, close); // Extra block removed by Define Rewrite *rw = context->Define(from, to); rw->native = (native_fn) fn; rw->type = rtype; Symbols *s = MAIN->globals; Rewrite *rw2 = s->EnterRewrite(from, to); rw2->type = rtype; to->code = fn; to->SetSymbols(s); xl_enter_builtin(MAIN, name, to, rw2->parameters, fn); xl_set_documentation(from, doc); }
BOOL CALLBACK Symbols::SymEnumCallback(PSYMBOL_INFO pSymInfo, ULONG ulSymbolSize, PVOID pUserContext) { UserContext *pContext = (UserContext *)pUserContext; Symbols *pThisPtr = (Symbols *)pContext->pThis; DWORD_PTR dwAddress = (DWORD_PTR)pSymInfo->Address; DWORD_PTR dwModBase = (DWORD_PTR)pSymInfo->ModBase; //fprintf(stderr, "Symbol found at %p. Name: %.*s. Base address of module: %p\n", // dwAddress, pSymInfo->NameLen, pSymInfo->Name, dwModBase); bool bSuccess = false; SymbolInfo symbolInfo; symbolInfo.dwAddress = dwAddress; symbolInfo.strName = std::move(std::vector<char>(pSymInfo->Name, pSymInfo->Name + strlen(pSymInfo->Name))); symbolInfo.strName.emplace_back(0); IMAGEHLP_LINE64 lineInfo = pThisPtr->GetSymbolLineInfo(dwAddress, symbolInfo.dwDisplacement, bSuccess); if (bSuccess) { symbolInfo.dwLineNumber = lineInfo.LineNumber; symbolInfo.strSourceFile = std::move(std::vector<char>(lineInfo.FileName, lineInfo.FileName + strlen(lineInfo.FileName))); symbolInfo.strSourceFile.emplace_back(0); } ModuleSymbolInfo moduleSymbol; moduleSymbol.dwModuleBaseAddress = dwModBase; moduleSymbol.strName = std::move(std::vector<char>(pContext->pName, pContext->pName + strlen(pContext->pName))); moduleSymbol.strName.emplace_back(0); moduleSymbol.symbolInfo = std::move(symbolInfo); pThisPtr->m_mapSymbols.insert(std::make_pair(dwModBase, std::move(moduleSymbol))); return TRUE; }
void PdbEngine::refreshSymbols(const GdbMi &symbols) { QString moduleName = symbols["module"].toUtf8(); Symbols syms; foreach (const GdbMi &item, symbols["symbols"].children()) { Symbol symbol; symbol.name = item["name"].toUtf8(); syms.append(symbol); } Internal::showModuleSymbols(moduleName, syms); }
void PdbEngine::handleListSymbols(const PdbResponse &response) { GdbMi out; out.fromString(response.data.trimmed()); Symbols symbols; QString moduleName = response.cookie.toString(); foreach (const GdbMi &item, out.children()) { Symbol symbol; symbol.name = _(item.findChild("name").data()); symbols.append(symbol); } debuggerCore()->showModuleSymbols(moduleName, symbols); }
bool Wll1Loader::EncountRemark(Symbols& remark) { if(this->input_pos >= this->input_symbols.size()) return false; Symbols symbol = this->GetSymbol(); if(symbol.IsRemark()) { remark = symbol; return true; } else { return false; } }
void Preprocessor::parseDefineArguments(Macro *m) { Symbols arguments; while (hasNext()) { while (test(PP_WHITESPACE)) {} Token t = next(); if (t == PP_RPAREN) break; if (t != PP_IDENTIFIER) { QByteArray l = lexem(); if (l == "...") { m->isVariadic = true; arguments += Symbol(symbol().lineNum, PP_IDENTIFIER, "__VA_ARGS__"); while (test(PP_WHITESPACE)) {} if (!test(PP_RPAREN)) error("missing ')' in macro argument list"); break; } else if (!is_identifier(l.constData(), l.length())) { qDebug() << l; error("Unexpected character in macro argument list."); } } Symbol arg = symbol(); if (arguments.contains(arg)) error("Duplicate macro parameter."); arguments += symbol(); while (test(PP_WHITESPACE)) {} t = next(); if (t == PP_RPAREN) break; if (t == PP_COMMA) continue; if (lexem() == "...") { //GCC extension: #define FOO(x, y...) x(y) // The last argument was already parsed. Just mark the macro as variadic. m->isVariadic = true; while (test(PP_WHITESPACE)) {} if (!test(PP_RPAREN)) error("missing ')' in macro argument list"); break; } error("Unexpected character in macro argument list."); } m->arguments = arguments; while (test(PP_WHITESPACE)) {} }
/// no benefit to using string_span to query; will create string anyway Sym addSymbolMustBeNew(std::string const& word) { SymInt const oldsz = size(); SymInt const i = symbols_.index(word); if (size() == oldsz || i >= maxLstSize_) throw std::out_of_range("BasicVocab::addSymbolMustBeNew-string was not new"); return symForIndex(i); }
void FloatArityFunction::checkArity(const Symbols &args) const { unsigned argsNum = args.size(); if (arity() > argsNum) { throw MinArityError(arity(), argsNum); } }
bool symbol_exist(std::string name) { if (symbols.count(name) == 0) { cout << "ERROR: no such symbol " << name << endl; return false; } return true; }
void xl_enter_prefix(Context *context, text name, native_fn fn, Tree *rtype, TreeList ¶meters, text symbol, text doc) // ---------------------------------------------------------------------------- // Enter a prefix into the context (called from .tbl files) // ---------------------------------------------------------------------------- { if (parameters.size()) { Tree *parmtree = xl_parameters_tree(parameters); Prefix *from = new Prefix(new Name(symbol), parmtree); Name *to = new Name(symbol); Rewrite *rw = context->Define(from, to); rw->native = fn; rw->type = rtype; Symbols *s = MAIN->globals; Rewrite *rw2 = s->EnterRewrite(from, to); rw2->type = rtype; to->code = fn; to->SetSymbols(s); xl_enter_builtin(MAIN, name, to, rw2->parameters, fn); xl_set_documentation(from, doc); } else { Name *n = new Name(symbol); n->SetInfo<PrefixDefinitionsInfo>(new PrefixDefinitionsInfo()); Rewrite *rw = context->Define(n, n); rw->native = fn; rw->type = rtype; Symbols *s = MAIN->globals; Rewrite *rw2 = s->EnterName(symbol, n, Rewrite::GLOBAL); rw2->type = rtype; n->code = fn; n->SetSymbols(s); TreeList noparms; xl_enter_builtin(MAIN, name, n, noparms, fn); xl_set_documentation(n, doc); } }
TEST(Symbol, Test){ Symbols symbols; Scanner::Plugins::Symbol sym(symbols); symbols.init(); Scanner::StringCharacterWell mcw_1("string"), mcw_2("$4518"), mcw_3("+"), mcw_4("++"), mcw_5("+++"), mcw_6("==="), mcw_7("[]ll"); CHECK(sym.type() == Scanner::TokenType::TOKEN_TYPE_SYMBOL); CHECK(!sym.matches(mcw_1)); CHECK(sym.get(mcw_1) == Scanner::Token(Scanner::TokenType::TOKEN_TYPE_NONE, "")); mcw_1.commit(); CHECK(mcw_1.dump() == "string"); CHECK(!sym.matches(mcw_2)); CHECK(sym.get(mcw_2) == Scanner::Token(Scanner::TokenType::TOKEN_TYPE_NONE, "")); mcw_2.commit(); CHECK(mcw_2.dump() == "$4518"); CHECK(sym.matches(mcw_3)); CHECK(sym.get(mcw_3) == Scanner::Token(Scanner::TokenType::TOKEN_TYPE_SYMBOL, "+")); mcw_3.commit(); CHECK(mcw_3.dump() == ""); CHECK(sym.matches(mcw_4)); CHECK(sym.get(mcw_4) == Scanner::Token(Scanner::TokenType::TOKEN_TYPE_SYMBOL, "++")); mcw_4.commit(); CHECK(mcw_4.dump() == ""); CHECK(sym.matches(mcw_5)); CHECK(sym.get(mcw_5) == Scanner::Token(Scanner::TokenType::TOKEN_TYPE_SYMBOL, "++")); mcw_5.commit(); CHECK(mcw_5.dump() == "+"); CHECK(sym.matches(mcw_6)); CHECK(sym.get(mcw_6) == Scanner::Token(Scanner::TokenType::TOKEN_TYPE_SYMBOL, "===")); mcw_6.commit(); CHECK(mcw_6.dump() == ""); CHECK(sym.matches(mcw_7)); CHECK(sym.get(mcw_7) == Scanner::Token(Scanner::TokenType::TOKEN_TYPE_SYMBOL, "[]")); mcw_7.commit(); CHECK(mcw_7.dump() == "ll"); }
void readLiftedEvidence ( YAP_Term observedList, ObservedFormulas& obsFormulas) { while (observedList != YAP_TermNil()) { YAP_Term pair = YAP_HeadOfTerm (observedList); YAP_Term ground = YAP_ArgOfTerm (1, pair); Symbol functor; Symbols args; if (YAP_IsAtomTerm (ground)) { string name ((char*) YAP_AtomName (YAP_AtomOfTerm (ground))); functor = LiftedUtils::getSymbol (name); } else { assert (YAP_IsApplTerm (ground)); YAP_Functor yapFunctor = YAP_FunctorOfTerm (ground); string name ((char*) (YAP_AtomName (YAP_NameOfFunctor (yapFunctor)))); functor = LiftedUtils::getSymbol (name); unsigned arity = (unsigned) YAP_ArityOfFunctor (yapFunctor); for (unsigned i = 1; i <= arity; i++) { YAP_Term ti = YAP_ArgOfTerm (i, ground); assert (YAP_IsAtomTerm (ti)); string arg ((char *) YAP_AtomName (YAP_AtomOfTerm (ti))); args.push_back (LiftedUtils::getSymbol (arg)); } } unsigned evidence = (unsigned) YAP_IntOfTerm (YAP_ArgOfTerm (2, pair)); bool found = false; for (size_t i = 0; i < obsFormulas.size(); i++) { if (obsFormulas[i].functor() == functor && obsFormulas[i].arity() == args.size() && obsFormulas[i].evidence() == evidence) { obsFormulas[i].addTuple (args); found = true; } } if (found == false) { obsFormulas.push_back (ObservedFormula (functor, evidence, args)); } observedList = YAP_TailOfTerm (observedList); } }
void xl_enter_form(Context *context, text name, native_fn fn, Tree *rtype, text form, TreeList ¶meters, text doc) // ---------------------------------------------------------------------------- // Enter an arbitrary form in the symbol table // ---------------------------------------------------------------------------- { Tree *from = xl_parse_text(form); Name *to = new Name(name); Rewrite *rw = context->Define(from, to); rw->native = fn; rw->type = rtype; Symbols *s = MAIN->globals; Rewrite *rw2 = s->EnterRewrite(from, to); rw2->type = rtype; to->code = fn; to->SetSymbols(s); xl_enter_builtin(MAIN, name, to, rw2->parameters, fn); ulong sz = parameters.size(); if (sz != rw2->parameters.size()) { std::cerr << "WARNING: Internal error on parameter count for " << name << "\n" << " " << form << "\n"; ulong sz2 = rw2->parameters.size(); for (ulong i = 0; i < sz || i < sz2; i++) { std::cerr << " #" << i << ": "; if (i < sz) std::cerr << "spec(" << parameters[i] << ") "; if (i < sz2) std::cerr << "form(" << rw2->parameters[i] << ") "; std::cerr << "\n"; } } xl_set_documentation(from, doc); }
bool load_symbol_or_int(std::string arg, Int& num) { if (symbols.count(arg)) { num = symbols[arg]; } else { if (!num.parse(arg)) { cout << "ERROR: parse failed " << arg << endl; return false; } } return true; }
void xl_enter_postfix(Context *context, text name, native_fn fn, Tree *rtype, TreeList ¶meters, text symbol, text doc) // ---------------------------------------------------------------------------- // Enter a postfdix into the context (called from .tbl files) // ---------------------------------------------------------------------------- { Tree *parmtree = xl_parameters_tree(parameters); Postfix *from = new Postfix(parmtree, new Name(symbol)); Name *to = new Name(symbol); Rewrite *rw = context->Define(from, to); rw->native = (native_fn) fn; rw->type = rtype; Symbols *s = MAIN->globals; Rewrite *rw2 = s->EnterRewrite(from, to); rw2->type = rtype; to->code = fn; to->SetSymbols(s); xl_enter_builtin(MAIN, name, to, rw2->parameters, fn); xl_set_documentation(from, doc); }
Symbols Preprocessor::macroExpand(Preprocessor *that, Symbols &toExpand, int &index, int lineNum, bool one) { SymbolStack symbols; SafeSymbols sf; sf.symbols = toExpand; sf.index = index; symbols.push(sf); Symbols result; if (toExpand.isEmpty()) return result; for (;;) { QByteArray macro; Symbols newSyms = macroExpandIdentifier(that, symbols, lineNum, ¯o); if (macro.isEmpty()) { result += newSyms; } else { SafeSymbols sf; sf.symbols = newSyms; sf.index = 0; sf.expandedMacro = macro; symbols.push(sf); } if (!symbols.hasNext() || (one && symbols.size() == 1)) break; symbols.next(); } if (symbols.size()) index = symbols.top().index; else index = toExpand.size(); return result; }
void xl_enter_infix(Context *context, text name, native_fn fn, Tree *rtype, text t1, text symbol, text t2, text doc) // ---------------------------------------------------------------------------- // Enter an infix into the context (called from .tbl files) // ---------------------------------------------------------------------------- { Tree *ldecl = xl_parameter("l", t1); Tree *rdecl = xl_parameter("r", t2); Infix *from = new Infix(symbol, ldecl, rdecl); Name *to = new Name(symbol); Rewrite *rw = context->Define(from, to); rw->native = fn; rw->type = rtype; Symbols *s = MAIN->globals; Rewrite *rw2 = s->EnterRewrite(from, to); rw2->type = rtype; to->code = fn; to->SetSymbols(s); xl_enter_builtin(MAIN, name, to, rw2->parameters, fn); xl_set_documentation(from, doc); }
void Preprocessor::preprocess(const QByteArray &filename, Symbols &preprocessed) { currentFilenames.push(filename); preprocessed.reserve(preprocessed.size() + symbols.size()); while (hasNext()) { Token token = next(); switch (token) { case PP_INCLUDE: { int lineNum = symbol().lineNum; QByteArray include; bool local = false; if (test(PP_STRING_LITERAL)) { local = lexem().startsWith('\"'); include = unquotedLexem(); } else continue; until(PP_NEWLINE); // #### stringery QFileInfo fi; if (local) fi.setFile(QFileInfo(QString::fromLocal8Bit(filename)).dir(), QString::fromLocal8Bit(include)); for (int j = 0; j < Preprocessor::includes.size() && !fi.exists(); ++j) { const IncludePath &p = Preprocessor::includes.at(j); if (p.isFrameworkPath) { const int slashPos = include.indexOf('/'); if (slashPos == -1) continue; QByteArray frameworkCandidate = include.left(slashPos); frameworkCandidate.append(".framework/Headers/"); fi.setFile(QString::fromLocal8Bit(QByteArray(p.path + '/' + frameworkCandidate)), QString::fromLocal8Bit(include.mid(slashPos + 1))); } else { fi.setFile(QString::fromLocal8Bit(p.path), QString::fromLocal8Bit(include)); } // try again, maybe there's a file later in the include paths with the same name // (186067) if (fi.isDir()) { fi = QFileInfo(); continue; } } if (!fi.exists() || fi.isDir()) continue; include = fi.canonicalFilePath().toLocal8Bit(); if (Preprocessor::preprocessedIncludes.contains(include)) continue; Preprocessor::preprocessedIncludes.insert(include); QFile file(QString::fromLocal8Bit(include)); if (!file.open(QFile::ReadOnly)) continue; QByteArray input = file.readAll(); file.close(); if (input.isEmpty()) continue; Symbols saveSymbols = symbols; int saveIndex = index; // phase 1: get rid of backslash-newlines input = cleaned(input); // phase 2: tokenize for the preprocessor symbols = tokenize(input); input.clear(); index = 0; // phase 3: preprocess conditions and substitute macros preprocessed += Symbol(0, MOC_INCLUDE_BEGIN, include); preprocess(include, preprocessed); preprocessed += Symbol(lineNum, MOC_INCLUDE_END, include); symbols = saveSymbols; index = saveIndex; continue; } case PP_DEFINE: { next(IDENTIFIER); QByteArray name = lexem(); int start = index; until(PP_NEWLINE); Macro macro; macro.symbols.reserve(index - start - 1); for (int i = start; i < index - 1; ++i) macro.symbols += symbols.at(i); macros.insert(name, macro); continue; } case PP_UNDEF: { next(IDENTIFIER); QByteArray name = lexem(); until(PP_NEWLINE); macros.remove(name); continue; } case PP_IDENTIFIER: { // if (macros.contains(symbol())) // ; } // we _could_ easily substitute macros by the following // four lines, but we choose not to. /* if (macros.contains(sym.lexem())) { preprocessed += substitute(macros, symbols, i); continue; } */ break; case PP_HASH: until(PP_NEWLINE); continue; // skip unknown preprocessor statement case PP_IFDEF: case PP_IFNDEF: case PP_IF: while (!evaluateCondition()) { if (!skipBranch()) break; if (test(PP_ELIF)) { } else { until(PP_NEWLINE); break; } } continue; case PP_ELIF: case PP_ELSE: skipUntilEndif(); // fall through case PP_ENDIF: until(PP_NEWLINE); continue; case SIGNALS: case SLOTS: { Symbol sym = symbol(); if (macros.contains("QT_NO_KEYWORDS")) sym.token = IDENTIFIER; else sym.token = (token == SIGNALS ? Q_SIGNALS_TOKEN : Q_SLOTS_TOKEN); preprocessed += sym; } continue; default: break; } preprocessed += symbol(); } currentFilenames.pop(); }
static Symbols tokenize(const QByteArray &input, int lineNum = 1, TokenizeMode mode = TokenizeCpp) { Symbols symbols; const char *begin = input; const char *data = begin; while (*data) { if (mode == TokenizeCpp) { int column = 0; const char *lexem = data; int state = 0; Token token = NOTOKEN; for (;;) { if (static_cast<signed char>(*data) < 0) { ++data; continue; } int nextindex = keywords[state].next; int next = 0; if (*data == keywords[state].defchar) next = keywords[state].defnext; else if (!state || nextindex) next = keyword_trans[nextindex][(int)*data]; if (!next) break; state = next; token = keywords[state].token; ++data; } // suboptimal, is_ident_char should use a table if (keywords[state].ident && is_ident_char(*data)) token = keywords[state].ident; if (token == NOTOKEN) { // an error really ++data; continue; } ++column; if (token > SPECIAL_TREATMENT_MARK) { switch (token) { case QUOTE: data = skipQuote(data); token = STRING_LITERAL; // concatenate multi-line strings for easier // STRING_LITERAAL handling in moc if (!Preprocessor::preprocessOnly && !symbols.isEmpty() && symbols.last().token == STRING_LITERAL) { QByteArray newString = symbols.last().unquotedLexem(); newString += input.mid(lexem - begin + 1, data - lexem - 2); newString.prepend('\"'); newString.append('\"'); symbols.last() = Symbol(symbols.last().lineNum, STRING_LITERAL, newString); continue; } break; case SINGLEQUOTE: while (*data && (*data != '\'' || (*(data-1)=='\\' && *(data-2)!='\\'))) ++data; if (*data) ++data; token = CHARACTER_LITERAL; break; case LANGLE_SCOPE: // split <:: into two tokens, < and :: token = LANGLE; data -= 2; break; case DIGIT: while (is_digit_char(*data)) ++data; if (!*data || *data != '.') { token = INTEGER_LITERAL; if (data - lexem == 1 && (*data == 'x' || *data == 'X') && *lexem == '0') { ++data; while (is_hex_char(*data)) ++data; } break; } token = FLOATING_LITERAL; ++data; // fall through case FLOATING_LITERAL: while (is_digit_char(*data)) ++data; if (*data == '+' || *data == '-') ++data; if (*data == 'e' || *data == 'E') { ++data; while (is_digit_char(*data)) ++data; } if (*data == 'f' || *data == 'F' || *data == 'l' || *data == 'L') ++data; break; case HASH: if (column == 1) { mode = PreparePreprocessorStatement; while (*data && (*data == ' ' || *data == '\t')) ++data; if (is_ident_char(*data)) mode = TokenizePreprocessorStatement; continue; } break; case NEWLINE: ++lineNum; continue; case BACKSLASH: { const char *rewind = data; while (*data && (*data == ' ' || *data == '\t')) ++data; if (*data && *data == '\n') { ++data; continue; } data = rewind; } break; case CHARACTER: while (is_ident_char(*data)) ++data; token = IDENTIFIER; break; case C_COMMENT: if (*data) { if (*data == '\n') ++lineNum; ++data; if (*data) { if (*data == '\n') ++lineNum; ++data; } } while (*data && (*(data-1) != '/' || *(data-2) != '*')) { if (*data == '\n') ++lineNum; ++data; } token = WHITESPACE; // one comment, one whitespace // fall through; case WHITESPACE: if (column == 1) column = 0; while (*data && (*data == ' ' || *data == '\t')) ++data; if (Preprocessor::preprocessOnly) // tokenize whitespace break; continue; case CPP_COMMENT: while (*data && *data != '\n') ++data; continue; // ignore safely, the newline is a separator default: continue; //ignore } } #ifdef USE_LEXEM_STORE if (!Preprocessor::preprocessOnly && token != IDENTIFIER && token != STRING_LITERAL && token != FLOATING_LITERAL && token != INTEGER_LITERAL) symbols += Symbol(lineNum, token); else #endif symbols += Symbol(lineNum, token, input, lexem-begin, data-lexem); } else { // Preprocessor const char *lexem = data; int state = 0; Token token = NOTOKEN; if (mode == TokenizePreprocessorStatement) { state = pp_keyword_trans[0][(int)'#']; mode = TokenizePreprocessor; } for (;;) { if (static_cast<signed char>(*data) < 0) { ++data; continue; } int nextindex = pp_keywords[state].next; int next = 0; if (*data == pp_keywords[state].defchar) next = pp_keywords[state].defnext; else if (!state || nextindex) next = pp_keyword_trans[nextindex][(int)*data]; if (!next) break; state = next; token = pp_keywords[state].token; ++data; } // suboptimal, is_ident_char should use a table if (pp_keywords[state].ident && is_ident_char(*data)) token = pp_keywords[state].ident; switch (token) { case NOTOKEN: ++data; break; case PP_IFDEF: symbols += Symbol(lineNum, PP_IF); symbols += Symbol(lineNum, PP_DEFINED); continue; case PP_IFNDEF: symbols += Symbol(lineNum, PP_IF); symbols += Symbol(lineNum, PP_NOT); symbols += Symbol(lineNum, PP_DEFINED); continue; case PP_INCLUDE: mode = TokenizeInclude; break; case PP_QUOTE: data = skipQuote(data); token = PP_STRING_LITERAL; break; case PP_SINGLEQUOTE: while (*data && (*data != '\'' || (*(data-1)=='\\' && *(data-2)!='\\'))) ++data; if (*data) ++data; token = PP_CHARACTER_LITERAL; break; case PP_DIGIT: while (is_digit_char(*data)) ++data; if (!*data || *data != '.') { token = PP_INTEGER_LITERAL; if (data - lexem == 1 && (*data == 'x' || *data == 'X') && *lexem == '0') { ++data; while (is_hex_char(*data)) ++data; } break; } token = PP_FLOATING_LITERAL; ++data; // fall through case PP_FLOATING_LITERAL: while (is_digit_char(*data)) ++data; if (*data == '+' || *data == '-') ++data; if (*data == 'e' || *data == 'E') { ++data; while (is_digit_char(*data)) ++data; } if (*data == 'f' || *data == 'F' || *data == 'l' || *data == 'L') ++data; break; case PP_CHARACTER: if (mode == PreparePreprocessorStatement) { // rewind entire token to begin data = lexem; mode = TokenizePreprocessorStatement; continue; } while (is_ident_char(*data)) ++data; token = PP_IDENTIFIER; break; case PP_C_COMMENT: if (*data) { if (*data == '\n') ++lineNum; ++data; if (*data) { if (*data == '\n') ++lineNum; ++data; } } while (*data && (*(data-1) != '/' || *(data-2) != '*')) { if (*data == '\n') ++lineNum; ++data; } token = PP_WHITESPACE; // one comment, one whitespace // fall through; case PP_WHITESPACE: while (*data && (*data == ' ' || *data == '\t')) ++data; continue; // the preprocessor needs no whitespace case PP_CPP_COMMENT: while (*data && *data != '\n') ++data; continue; // ignore safely, the newline is a separator case PP_NEWLINE: ++lineNum; mode = TokenizeCpp; break; case PP_BACKSLASH: { const char *rewind = data; while (*data && (*data == ' ' || *data == '\t')) ++data; if (*data && *data == '\n') { ++data; continue; } data = rewind; } break; case PP_LANGLE: if (mode != TokenizeInclude) break; token = PP_STRING_LITERAL; while (*data && *data != '\n' && *(data-1) != '>') ++data; break; default: break; } if (mode == PreparePreprocessorStatement) continue; #ifdef USE_LEXEM_STORE if (token != PP_IDENTIFIER && token != PP_STRING_LITERAL && token != PP_FLOATING_LITERAL && token != PP_INTEGER_LITERAL) symbols += Symbol(lineNum, token); else #endif symbols += Symbol(lineNum, token, input, lexem-begin, data-lexem); } } symbols += Symbol(); // eof symbol return symbols; }
static inline bool hasNext(const Symbols &symbols, int i) { return (i < symbols.size()); }
bool containsIndex(SymInt i) const { return i - offset_ < symbols_.size(); }
void Preprocessor::preprocess(const QByteArray &filename, Symbols &preprocessed) { currentFilenames.push(filename); preprocessed.reserve(preprocessed.size() + symbols.size()); while (hasNext()) { Token token = next(); switch (token) { case PP_INCLUDE: { int lineNum = symbol().lineNum; QByteArray include; bool local = false; if (test(PP_STRING_LITERAL)) { local = lexem().startsWith('\"'); include = unquotedLexem(); } else continue; until(PP_NEWLINE); // #### stringery QFileInfo fi; if (local) fi.setFile(QFileInfo(QString::fromLocal8Bit(filename.constData())).dir(), QString::fromLocal8Bit(include.constData())); for (int j = 0; j < Preprocessor::includes.size() && !fi.exists(); ++j) { const IncludePath &p = Preprocessor::includes.at(j); if (p.isFrameworkPath) { const int slashPos = include.indexOf('/'); if (slashPos == -1) continue; QByteArray frameworkCandidate = include.left(slashPos); frameworkCandidate.append(".framework/Headers/"); fi.setFile(QString::fromLocal8Bit(QByteArray(p.path + '/' + frameworkCandidate).constData()), QString::fromLocal8Bit(include.mid(slashPos + 1).constData())); } else { fi.setFile(QString::fromLocal8Bit(p.path.constData()), QString::fromLocal8Bit(include.constData())); } // try again, maybe there's a file later in the include paths with the same name // (186067) if (fi.isDir()) { fi = QFileInfo(); continue; } } if (!fi.exists() || fi.isDir()) continue; include = fi.canonicalFilePath().toLocal8Bit(); if (Preprocessor::preprocessedIncludes.contains(include)) continue; Preprocessor::preprocessedIncludes.insert(include); QFile file(QString::fromLocal8Bit(include.constData())); if (!file.open(QFile::ReadOnly)) continue; QByteArray input = file.readAll(); file.close(); if (input.isEmpty()) continue; Symbols saveSymbols = symbols; int saveIndex = index; // phase 1: get rid of backslash-newlines input = cleaned(input); // phase 2: tokenize for the preprocessor symbols = tokenize(input); input.clear(); index = 0; // phase 3: preprocess conditions and substitute macros preprocessed += Symbol(0, MOC_INCLUDE_BEGIN, include); preprocess(include, preprocessed); preprocessed += Symbol(lineNum, MOC_INCLUDE_END, include); symbols = saveSymbols; index = saveIndex; continue; } case PP_DEFINE: { next(IDENTIFIER); QByteArray name = lexem(); Macro macro; macro.isVariadic = false; Token t = next(); if (t == LPAREN) { // we have a function macro macro.isFunction = true; parseDefineArguments(¯o); } else if (t == PP_WHITESPACE) { macro.isFunction = false; } else { error("Moc: internal error"); } int start = index; until(PP_NEWLINE); macro.symbols.reserve(index - start - 1); // remove whitespace where there shouldn't be any: // Before and after the macro, after a # and around ## Token lastToken = HASH; // skip shitespace at the beginning for (int i = start; i < index - 1; ++i) { Token token = symbols.at(i).token; if (token == PP_WHITESPACE || token == WHITESPACE) { if (lastToken == PP_HASH || lastToken == HASH || lastToken == PP_HASHHASH || lastToken == PP_WHITESPACE || lastToken == WHITESPACE) continue; } else if (token == PP_HASHHASH) { if (!macro.symbols.isEmpty() && (lastToken == PP_WHITESPACE || lastToken == WHITESPACE)) macro.symbols.pop_back(); } macro.symbols.append(symbols.at(i)); lastToken = token; } // remove trailing whitespace while (!macro.symbols.isEmpty() && (macro.symbols.last().token == PP_WHITESPACE || macro.symbols.last().token == WHITESPACE)) macro.symbols.pop_back(); if (!macro.symbols.isEmpty()) { if (macro.symbols.first().token == PP_HASHHASH || macro.symbols.last().token == PP_HASHHASH) { error("'##' cannot appear at either end of a macro expansion"); } if (macro.symbols.last().token == HASH || macro.symbols.last().token == PP_HASH) { error("'#' is not followed by a macro parameter"); } } macros.insert(name, macro); continue; } case PP_UNDEF: { next(IDENTIFIER); QByteArray name = lexem(); until(PP_NEWLINE); macros.remove(name); continue; } case PP_IDENTIFIER: { // substitute macros preprocessed += macroExpand(this, symbols, index, symbol().lineNum, true); continue; } case PP_HASH: until(PP_NEWLINE); continue; // skip unknown preprocessor statement case PP_IFDEF: case PP_IFNDEF: case PP_IF: while (!evaluateCondition()) { if (!skipBranch()) break; if (test(PP_ELIF)) { } else { until(PP_NEWLINE); break; } } continue; case PP_ELIF: case PP_ELSE: skipUntilEndif(); // fall through case PP_ENDIF: until(PP_NEWLINE); continue; case PP_NEWLINE: continue; case SIGNALS: case SLOTS: { Symbol sym = symbol(); if (macros.contains("QT_NO_KEYWORDS")) sym.token = IDENTIFIER; else sym.token = (token == SIGNALS ? Q_SIGNALS_TOKEN : Q_SLOTS_TOKEN); preprocessed += sym; } continue; default: break; } preprocessed += symbol(); } currentFilenames.pop(); }
Symbols Preprocessor::macroExpandIdentifier(Preprocessor *that, SymbolStack &symbols, int lineNum, QByteArray *macroName) { Symbol s = symbols.symbol(); // not a macro if (s.token != PP_IDENTIFIER || !that->macros.contains(s) || symbols.dontReplaceSymbol(s.lexem())) { Symbols syms; syms += s; syms.last().lineNum = lineNum; return syms; } const Macro ¯o = that->macros.value(s); *macroName = s.lexem(); Symbols expansion; if (!macro.isFunction) { expansion = macro.symbols; } else { bool haveSpace = false; while (symbols.test(PP_WHITESPACE)) { haveSpace = true; } if (!symbols.test(PP_LPAREN)) { *macroName = QByteArray(); Symbols syms; if (haveSpace) syms += Symbol(lineNum, PP_WHITESPACE); syms += s; syms.last().lineNum = lineNum; return syms; } QList<Symbols> arguments; while (symbols.hasNext()) { Symbols argument; // strip leading space while (symbols.test(PP_WHITESPACE)) {} int nesting = 0; bool vararg = macro.isVariadic && (arguments.size() == macro.arguments.size() - 1); while (symbols.hasNext()) { Token t = symbols.next(); if (t == PP_LPAREN) { ++nesting; } else if (t == PP_RPAREN) { --nesting; if (nesting < 0) break; } else if (t == PP_COMMA && nesting == 0) { if (!vararg) break; } argument += symbols.symbol(); } arguments += argument; if (nesting < 0) break; } // empty VA_ARGS if (macro.isVariadic && arguments.size() == macro.arguments.size() - 1) arguments += Symbols(); if (arguments.size() != macro.arguments.size() && // 0 argument macros are a bit special. They are ok if the // argument is pure whitespace or empty (macro.arguments.size() != 0 || arguments.size() != 1 || !arguments.at(0).isEmpty())) that->error("Macro argument mismatch."); // now replace the macro arguments with the expanded arguments enum Mode { Normal, Hash, HashHash } mode = Normal; for (int i = 0; i < macro.symbols.size(); ++i) { const Symbol &s = macro.symbols.at(i); if (s.token == HASH || s.token == PP_HASHHASH) { mode = (s.token == HASH ? Hash : HashHash); continue; } int index = macro.arguments.indexOf(s); if (mode == Normal) { if (index >= 0) { // each argument undoergoes macro expansion if it's not used as part of a # or ## if (i == macro.symbols.size() - 1 || macro.symbols.at(i + 1).token != PP_HASHHASH) { Symbols arg = arguments.at(index); int idx = 1; expansion += macroExpand(that, arg, idx, lineNum, false); } else { expansion += arguments.at(index); } } else { expansion += s; } } else if (mode == Hash) { if (index < 0) that->error("'#' is not followed by a macro parameter"); const Symbols &arg = arguments.at(index); QByteArray stringified; for (int i = 0; i < arg.size(); ++i) { stringified += arg.at(i).lexem(); } stringified.replace('"', "\\\""); stringified.prepend('"'); stringified.append('"'); expansion += Symbol(lineNum, STRING_LITERAL, stringified); } else if (mode == HashHash) { if (s.token == WHITESPACE) continue; while (expansion.size() && expansion.last().token == PP_WHITESPACE) expansion.pop_back(); Symbol next = s; if (index >= 0) { const Symbols &arg = arguments.at(index); if (arg.size() == 0) { mode = Normal; continue; } next = arg.at(0); } if (!expansion.isEmpty() && expansion.last().token == s.token) { Symbol last = expansion.last(); expansion.pop_back(); if (last.token == STRING_LITERAL || s.token == STRING_LITERAL) that->error("Can't concatenate non identifier tokens"); QByteArray lexem = last.lexem() + next.lexem(); expansion += Symbol(lineNum, last.token, lexem); } else { expansion += next; } if (index >= 0) { const Symbols &arg = arguments.at(index); for (int i = 1; i < arg.size(); ++i) expansion += arg.at(i); } } mode = Normal; } if (mode != Normal) that->error("'#' or '##' found at the end of a macro argument"); } return expansion; }
bool contains(std::string const& word) const { return symbols_.find(word) != kNullIndex; }
bool contains(cstring_span<> word) const { return symbols_.find(word) != kNullIndex; }
void reset() { symbols_.clear(); freezeEndIndex_ = 0; }
int runLiftedSolver (void) { LiftedNetwork* network = (LiftedNetwork*) YAP_IntOfTerm (YAP_ARG1); YAP_Term taskList = YAP_ARG2; vector<Params> results; ParfactorList pfListCopy (*network->first); LiftedVe::absorveEvidence (pfListCopy, *network->second); while (taskList != YAP_TermNil()) { Grounds queryVars; YAP_Term jointList = YAP_HeadOfTerm (taskList); while (jointList != YAP_TermNil()) { YAP_Term ground = YAP_HeadOfTerm (jointList); if (YAP_IsAtomTerm (ground)) { string name ((char*) YAP_AtomName (YAP_AtomOfTerm (ground))); queryVars.push_back (Ground (LiftedUtils::getSymbol (name))); } else { assert (YAP_IsApplTerm (ground)); YAP_Functor yapFunctor = YAP_FunctorOfTerm (ground); string name ((char*) (YAP_AtomName (YAP_NameOfFunctor (yapFunctor)))); unsigned arity = (unsigned) YAP_ArityOfFunctor (yapFunctor); Symbol functor = LiftedUtils::getSymbol (name); Symbols args; for (unsigned i = 1; i <= arity; i++) { YAP_Term ti = YAP_ArgOfTerm (i, ground); assert (YAP_IsAtomTerm (ti)); string arg ((char *) YAP_AtomName (YAP_AtomOfTerm (ti))); args.push_back (LiftedUtils::getSymbol (arg)); } queryVars.push_back (Ground (functor, args)); } jointList = YAP_TailOfTerm (jointList); } if (Globals::liftedSolver == LiftedSolver::FOVE) { LiftedVe solver (pfListCopy); if (Globals::verbosity > 0 && taskList == YAP_ARG2) { solver.printSolverFlags(); cout << endl; } results.push_back (solver.solveQuery (queryVars)); } else if (Globals::liftedSolver == LiftedSolver::LBP) { LiftedBp solver (pfListCopy); if (Globals::verbosity > 0 && taskList == YAP_ARG2) { solver.printSolverFlags(); cout << endl; } results.push_back (solver.solveQuery (queryVars)); } else { assert (false); } taskList = YAP_TailOfTerm (taskList); } YAP_Term list = YAP_TermNil(); for (size_t i = results.size(); i-- > 0; ) { const Params& beliefs = results[i]; YAP_Term queryBeliefsL = YAP_TermNil(); for (size_t j = beliefs.size(); j-- > 0; ) { YAP_Int sl1 = YAP_InitSlot (list); YAP_Term belief = YAP_MkFloatTerm (beliefs[j]); queryBeliefsL = YAP_MkPairTerm (belief, queryBeliefsL); list = YAP_GetFromSlot (sl1); YAP_RecoverSlots (1); } list = YAP_MkPairTerm (queryBeliefsL, list); } return YAP_Unify (list, YAP_ARG3); }