TravelTime LibTau::computeFirst(double lat1, double lon1, double dep1, double lat2, double lon2, double alt2, int ellc) { if ( !_initialized ) setModel("iasp91"); double delta, azi1, azi2; Math::Geo::delazi(lat1, lon1, lat2, lon2, &delta, &azi1, &azi2); /* TODO apply ellipticity correction */ return computeFirst(delta, dep1); }
//******************************************************* // GrammarAnalyzer::fillFirstSets //******************************************************* void GrammarAnalyzer::fillFirstSets() noexcept { // This loop assumes the first sets haven't been changed from the empty // set yet. (Code provided in class has an else case to set the first // set to the empty list.) for (auto nonTerminal : myNonTerminalSymbols) { if (nonTerminal->getDerivesLambda()) { nonTerminal->addToFirstSet(Lambda::getInstance()); } } for (auto terminal : myTerminalSymbols) { terminal->addToFirstSet(terminal); } for (auto production : myProductions) { auto rhs = production->getRHS(); uint32_t index = 0; for (; index < rhs.size() && false == isGrammarSymbol(rhs[index]); ++index); if (typeid(*rhs[index]) == typeid(TerminalSymbol)) { production->getLHS()->addToFirstSet(rhs[index]); } } bool anyChanges = true; while (anyChanges) { anyChanges = false; for (auto production : myProductions) { auto previousSize = production->getLHS()->getFirstSet().size(); Symbol::SymbolSet rhsFirstSet{computeFirst(production->getRHS())}; for (auto symbol : rhsFirstSet) { production->getLHS()->addToFirstSet(symbol); } auto afterSize = production->getLHS()->getFirstSet().size(); if (! anyChanges) { anyChanges = (previousSize != afterSize); } } } }
void predict (const std::vector<std::string>& LHS, const std::vector<std::string>& RHS, const std::vector<std::vector<std::string>>& RHSStringList) { predictSet.resize (LHS.size()); for (unsigned i = 0; i < LHS.size(); ++i) { if (RHS[i].compare("") == 0) { predictSet[i] = followSet[LHS[i]]; predictSet[i].erase (""); } else { predictSet[i] = computeFirst(RHSStringList[i]); } } }
void fillFirstSet (const std::set<std::string> nonterminals, const std::set<std::string> terminals, const std::vector<std::string> LHS, const std::vector<std::string> RHS, const std::vector<std::vector<std::string>>& RHSStringList) { auto ntItr = nonterminals.begin(); auto tItr = terminals.begin(); for (; ntItr != nonterminals.end(); ++ntItr) { if (derivesLambda [*ntItr]) { firstSet[*ntItr].insert (""); } else { firstSet[*ntItr].clear (); } } for (; tItr != terminals.end(); ++tItr) { if (tItr->compare("") != 0){ firstSet[*tItr].insert (*tItr); } for (ntItr = nonterminals.begin(); ntItr != nonterminals.end(); ++ntItr) { if (yields(*ntItr, *tItr, LHS, RHS)) { firstSet[*ntItr].insert (*tItr); } } } bool changes = true; while (changes) { auto prevFirstSet = firstSet; for (unsigned i = 0; i < LHS.size(); ++i) { auto rhsFirst = computeFirst (RHSStringList[i]); firstSet[LHS[i]].insert(rhsFirst.begin(), rhsFirst.end()); } if (prevFirstSet == firstSet) { changes = false; } } }
//******************************************************* // GrammarAnalyzer::generatePredictSets //******************************************************* void GrammarAnalyzer::generatePredictSets() noexcept { for (auto production : myProductions) { Symbol::SymbolSet predictSet{computeFirst(production->getRHS())}; if (containsLambda(predictSet)) { auto lhsPtr = production->getLHS(); NonTerminalSymbol *lhs = dynamic_cast<NonTerminalSymbol*>(lhsPtr.get()); Symbol::SymbolSet followSet{lhs->getFollowSet()}; predictSet.insert(followSet.begin(), followSet.end()); } predictSet.erase(Lambda::getInstance()); for (auto symbol : predictSet) { production->addToPredictSet(symbol); } } }
void CFG::computeFollow() // elements are terminals // for all nonterminals { computeFirst(); follow.clear(); for(size_t i = 0; i < v.size(); ++i) { follow.push_back(make_pair(v[i], vector<string>())); // $ represents the end of input } follow[getFollowIndex(s)].second.push_back("$"); bool updated = false; do { updated = false; for(size_t j = 0; j < p.size(); ++j) { // A -> alpha B beta // case1: A -> alpha B ==>==> follow(A) subset follow(B) // case2: A -> alpha B beta ==> (first(beta) except {epsilon}) subset follow(B) // epsilon in first(beta) ==> follow(A) subset follow(B) for(size_t k = 0; k < p[j].right.size(); ++k) { if(in(p[j].right[k], v)) { int aFollowIndex = getFollowIndex(p[j].left); vector<string> followA = follow[aFollowIndex].second; int bFollowIndex = getFollowIndex(p[j].right[k]); vector<string> followB = follow[bFollowIndex].second; vector<string> beta; vector<string> firstBeta; if(k < p[j].right.size() - 1) { for(size_t l = k + 1; l < p[j].right.size(); ++l) { beta.push_back(p[j].right[l]); } firstBeta = computeFirst(beta); bool epsilon = del(firstBeta, string("")); bool added = add(followB, firstBeta); if(added) { updated = true; } if(epsilon) { bool added = add(followB, followA); if(added) { updated = true; } } } else { bool added = add(followB, followA); if(added) { updated = true; } } follow[bFollowIndex].second = followB; } } } }while(updated); }
vector<LR1Item> CFG::closure(const vector<LR1Item>& is) { vector<LR1Item> js = is; bool updated = false; do { updated = false; for(size_t i = 0; i < js.size(); ++i) { // (A -> alpha . B beta, a) Production pr = p[js[i].productionIndex]; if(js[i].dotPosition < pr.right.size()) { string B = pr.right[js[i].dotPosition]; if(in(B, v)) { vector<string> betaa; for(size_t k = js[i].dotPosition + 1; k < pr.right.size(); ++k) { betaa.push_back(pr.right[k]); } betaa.push_back(js[i].lookahead); vector<string> firstBetaa = computeFirst(betaa); for(size_t j = 0; j < p.size(); ++j) { if(p[j].left == B) { for(size_t k = 0; k < firstBetaa.size(); ++k) { string b = firstBetaa[k]; if(b != "") { bool exist = false; for(size_t l = 0; l < js.size(); ++l) { if(js[l].productionIndex == j && js[l].dotPosition == 0 && js[l].lookahead == b) { exist = true; break; } } if(!exist) { js.push_back(LR1Item(j, 0, b)); updated = true; } } } } } } } } }while(updated); return js; }
//******************************************************* // GrammarAnalyzer::fillFollowSets //******************************************************* void GrammarAnalyzer::fillFollowSets() noexcept { // Quite the hack, but really no other way to do it. auto s = dynamic_cast<NonTerminalSymbol*>(myGrammar.getStartSymbol().get()); s->addToFollowSet(Lambda::getInstance()); bool anyChanges = true; while (anyChanges) { anyChanges = false; for (auto production : myProductions) { auto rhs = production->getRHS(); for (uint32_t rhsIndex = 0; rhsIndex < rhs.size(); ++rhsIndex) { std::shared_ptr<Symbol> rhsSymbol = rhs[rhsIndex]; if (typeid(*rhsSymbol) == typeid(NonTerminalSymbol)) { NonTerminalSymbol *nonTerminal = dynamic_cast<NonTerminalSymbol*>(rhsSymbol.get()); auto previousSize = nonTerminal->getFollowSet().size(); Symbol::SymbolList remainingRhs; for (auto jj = rhsIndex + 1; jj < rhs.size(); ++jj) { if (isGrammarSymbol(rhs[jj])) { remainingRhs.push_back(rhs[jj]); } } Symbol::SymbolSet firstSetOfRemaining{computeFirst(remainingRhs)}; auto lambdaIter = firstSetOfRemaining.find(Lambda::getInstance()); bool hasLambda = lambdaIter != firstSetOfRemaining.end(); if (hasLambda) { firstSetOfRemaining.erase(lambdaIter); } for (auto s : firstSetOfRemaining) { nonTerminal->addToFollowSet(s); } if (hasLambda) { NonTerminalSymbol *lhs = dynamic_cast<NonTerminalSymbol*>(production->getLHS().get()); for (auto symbol : lhs->getFollowSet()) { nonTerminal->addToFollowSet(symbol); } } auto afterSize = nonTerminal->getFollowSet().size(); if (! anyChanges) { anyChanges = (previousSize != afterSize); } } } } } }