int Wll0Intepreter::SplitParameters(const vector<Symbols>&symbols, vector< vector<Symbols> >& fields) { fields.clear(); if(symbols.empty()) return 0; vector<Symbols> field; int depth = 0; for(vector<Symbols>::const_iterator i = symbols.begin(); i != symbols.end(); ++i) { if(*i == Symbols(REMARK_SYMBOL, "$SEPERATOR") && depth == 0) { fields.push_back(field); field.clear(); } else { if(*i == Symbols(REMARK_SYMBOL, "$LEFT_QUOTE")) { depth++; } else if(*i == Symbols(REMARK_SYMBOL, "$RIGHT_QUOTE")) { depth--; } field.push_back(*i); } } fields.push_back(field); return fields.size(); }
bool Wll1Loader::LoadVariable(Symbols& variable) { // //<variable>-->"<"<identifier>">"==><variable>-->"$"<identifier>$VARIABLE; string ident; return this->Accept('<') && this->LoadIdent(ident) && this->Accept('>') && (variable = Symbols(("<"+ident+">").c_str()),true); }
bool Wll1Loader::LoadRemark(Symbols& remark) { //<remark>-->"WLL0"==><remark>-->$WLL0; //<remark>-->"TRANSLATION"==><remark>-->$TRANSLATION; //<remark>-->"SOURCE-RULE"==><remark>-->$SOURCE-RULE; //<remark>-->"DESTINATION-RULE"==><remark>-->$DESTINATION-RULE; //<remark>-->"RULE"==><remark>-->$RULE; //<remark>-->"ROOT-SYMBOL"==><remark>-->$ROOT-SYMBOL; //<remark>-->"EXPRESSION"==><remark>-->$EXPRESSION; //<remark>-->"SUB-SYMBOL"==><remark>-->$SUB-SYMBOL; //<remark>-->"VARIABLE"==><remark>-->$VARIABLE; //<remark>-->"CONSTANT"==><remark>-->$CONSTANT; //<remark>-->"REMARK"==><remark>-->$REMARK; //<remark>-->"*"==><remark>-->$*; // string ident; //<remark>-->$*==><remark>-->$*; //<remark>-->"$"<identifier>==><remark>-->"$"<identifier>; return this->ExpectRemark(remark) || this->Accept('$') && this->LoadIdent(ident) && (remark = Symbols(REMARK_SYMBOL,("$"+ident).c_str()),true); }
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; }
Error LLJIT::defineAbsolute(StringRef Name, JITEvaluatedSymbol Sym) { auto InternedName = ES->intern(Name); SymbolMap Symbols({{InternedName, Sym}}); return Main.define(absoluteSymbols(std::move(Symbols))); }