ProductionStub::ProductionStub(const Production& production) : headID_(production.getHeadID()) { const std::vector<GrammarSymbol*>& body = production.getBody(); for (size_t i = 0; i < body.size(); ++i) bodyIDs_.push_back(body[i]->getSymbolID()); }
_file_ast handle_file(string& input, Production& p, Chart& chart) { int64_t setIndex; size_t stateIndex; Production production; _production_ast p_ast; _file_ast out; switch (p.number()){ case 0: //production ws ";" ws file //production tie(setIndex, stateIndex) = p.symbolInfo(0); production = chart.getState(setIndex, stateIndex).first; p_ast = handle_production(input, production, chart); //We don't care about whitespace or the symbol in this case tie(setIndex, stateIndex) = p.symbolInfo(4); production = chart.getState(setIndex, stateIndex).first; out = handle_file(input, production, chart); out.push_back(p_ast); return out; case 1: // production ws ";" ws //This is the terminal file make a new //production tie(setIndex, stateIndex) = p.symbolInfo(0); production = chart.getState(setIndex, stateIndex).first; p_ast = handle_production(input, production, chart); out = _file_ast({p_ast}); return out; default: break; } return _file_ast{}; }
_sub_production_ast handle_sub_production(string& input, Production& p, Chart& chart) { int64_t setIndex; size_t stateIndex; Production production; _sub_production_ast out; _symbol_ast symbol; switch(p.number()){ case 0: //symbol ws sub_production tie(setIndex, stateIndex) = p.symbolInfo(0); production = chart.getState(setIndex, stateIndex).first; symbol = handle_symbol(input, production, chart); //Skip ws tie(setIndex, stateIndex) = p.symbolInfo(2); production = chart.getState(setIndex, stateIndex).first; out = handle_sub_production(input, production, chart); out.insert(out.begin(), symbol); return out; case 1: //symbol tie(setIndex, stateIndex) = p.symbolInfo(0); production = chart.getState(setIndex, stateIndex).first; symbol = handle_symbol(input, production, chart); out.push_back(symbol); return out; default:; } return out; }
/// Perform an action. /// Given an action, update the state by replacing the children /// items in the action by the yielded item. /// \todo Should add to ::_path /// \todo Where is this called from? void State::perform(const Production& p) { boost::shared_ptr<const State> initial = _initial_state; if (this->is_initial()) { assert(!initial); initial = boost::shared_ptr<const State>(new const State(*this)); } ItemTokens newfrontier; ItemTokens::const_iterator i; ItemTokens::const_iterator childi = this->locate(p.action().children()); for(i = _frontier.begin(); i != childi; i++) { newfrontier.push_back(*i); } newfrontier.push_back(p.itemtoken()); i += p.action().children().size(); for(; i != _frontier.end(); i++) { newfrontier.push_back(*i); } assert(_frontier.size() == newfrontier.size() + p.action().children().size() - 1); Debug::log(5) << "Old state: " << _frontier.to_string() << "\n"; Debug::log(5) << "New state: " << newfrontier.to_string() << "\n"; _frontier = newfrontier; _path.add(p); _initial_state = initial; assert(this->initial_state().is_initial()); }
_rhs_ast handle_rhs(string& input, Production& p, Chart& chart) { int64_t setIndex; size_t stateIndex; Production production; _rhs_ast out; _sub_production_ast subProd; switch(p.number()){ case 0: //sub_production ws "|" ws rhs | sub_production tie(setIndex, stateIndex) = p.symbolInfo(0); production = chart.getState(setIndex, stateIndex).first; subProd = handle_sub_production(input, production, chart); tie(setIndex, stateIndex) = p.symbolInfo(4); production = chart.getState(setIndex, stateIndex).first; out = handle_rhs(input, production, chart); out.push_back(subProd); return out; case 1: tie(setIndex, stateIndex) = p.symbolInfo(0); production = chart.getState(setIndex, stateIndex).first; subProd = handle_sub_production(input, production, chart); out.push_back(subProd); return out; default:; } return out; }
_production_ast handle_production(string& input, Production& p, Chart& chart) { int64_t setIndex; size_t stateIndex; Production production; _production_ast out = _production_ast(); //No cases so no switch //non_terminal option ws ":=" ws rhs tie(setIndex, stateIndex) = p.symbolInfo(0); production = chart.getState(setIndex, stateIndex).first; _non_terminal_ast name = handle_non_terminal(input, production, chart); out.name_ = name; tie(setIndex, stateIndex) = p.symbolInfo(1); if(setIndex > 0) { //If it has a negative setIndex it was skipped production = chart.getState(setIndex, stateIndex).first; _option_ast option = handle_option(input, production, chart); if (option == "nullable") { out.nullable_ = true; } else { out.nullable_ = false; } } tie(setIndex, stateIndex) = p.symbolInfo(5); production = chart.getState(setIndex, stateIndex).first; _rhs_ast rhs = handle_rhs(input, production, chart); out.sub_productions_ = rhs; return out; }
Nonterminal::~Nonterminal(void) { if (this->m_pwzName) free(this->m_pwzName); // Delete the associated productions Production* p = this->m_pProd; while (p) { Production* pNext = p->getNext(); delete p; p = pNext; } Nonterminal::ac--; }
static void expandOn(const map<string, Definition>& grammar, int aNonTerminalPos, vector<string>& aResult) { if(aNonTerminalPos == -1) { // Base case // return; } else { // Recursive case // auto iterator = grammar.find(aResult[aNonTerminalPos]); // If non-terminal is not defined then display error msg and exit. if(iterator == grammar.end()) { cout << "Could not find \"" << aResult[aNonTerminalPos] << "\" in the grammar file." << endl; exit (EXIT_FAILURE); } Definition myDefinition = iterator->second; Production myRandProduction = myDefinition.getRandomProduction(); // Get iterator 1 passed pos to insert. auto resultIterator = aResult.begin()+aNonTerminalPos+1; aResult.insert(resultIterator, myRandProduction.begin(), myRandProduction.end()); // Get new valid iterator and delete expanded non-terminal. resultIterator = aResult.begin()+aNonTerminalPos; aResult.erase(resultIterator); // Iterate through result vector to expand on non-terminals. // Start from previously expanded position. int newNonTerminalPos = -1; int pos = aNonTerminalPos; for(auto start = aResult.begin()+aNonTerminalPos; start != aResult.end(); start++) { // Check if non-terminal. if( (*start)[0] == '<') { newNonTerminalPos = pos; break; } pos++; } // Recurse. expandOn(grammar, newNonTerminalPos, aResult); } }
static void expendProduction(Production& production, const map<string, Definition>& grammar) { for (auto iter = production.begin(); iter < production.end(); ++iter) { string str = *iter; if (str.find('<') == std::string::npos) { cout << str << " "; } else { Definition def = grammar.at(str); Production prod = def.getRandomProduction(); expendProduction(prod, grammar); } } }
/// Make a consistent parse decision from a parse path. /// \param state The state in which the parse decision should be made. /// \param path The parse path that gives us the order of the actions. /// \sideeffect The action performed is popped from path. void Parser::make_consistent_decision(ParseState& state, Path& path) { assert(parameter::treebank_has_parse_paths()); // Just use the first production from the parse path. Production p = path.pop(); Action a = p.action(); // assert(m_parser->ItemToken_from_action(a) == p.itemtoken()); Debug::log(5) << "Performing: " << a.to_string() << "\n"; state.perform(a); stats::total_actions_add(1); // FIXME: Don't necessarily use _parse_span_chart. _parse_span_chart.subtract(SpanItem(a), _parse_prc, _parse_rcl, _parse_cbs); }
Production newprod(string a) { cout<<"\tCreating new production for string "<<a; Production p; if(index < production.size() && production[index].compare(a) == 0) { cout<<"\n\t\tNew production ...."; Production p; p.addForProd(index+1,lprod,production); p.viewproduction(); return p; } return p; }
//------------------------------ProductionState-------------------------------- void ProductionState::initialize() { _constraint = noConstraint; // reset each Production currently in the dictionary DictI iter( &_production ); const void *x, *y = NULL; for( ; iter.test(); ++iter) { x = iter._key; y = iter._value; Production *p = (Production*)y; if( p != NULL ) { p->initialize(); } } }
bool Predict::DerivesLambda( Production production ){ // Test for empty production RHS if( production.getRHS().size() == 0 ){ return true; } else { // Iterate through nonterminal/terminal symbols for( int j = 0; j < production.getRHS().size(); j++ ){ if( production.getRHS().get(j) == _LAMBDA ) return true; } } return false; }
void Grammar::dump(const Production &prod, MarginFile *f) const { fprintf(f, _T("%s -> "), getSymbol(prod.m_leftSide).m_name.cstr()); for(int i = 0; i < prod.getLength(); i++) { fprintf(f, _T("%s "), getSymbol(prod.m_rightSide[i]).m_name.cstr()); } fprintf(f, _T("prec %d"), prod.m_precedence); }
void Predict::MarkLambda(){ // Initializiation // for V in Vocabulary . DerivesLambda(V) := False for( int i = 0; i < grammar.nonterminalSet.size(); i ++ ){ grammar.derivesLambda.insertOverwrite( grammar.nonterminalSet[i], false ); } // for P in G.Productions for( int i = 0; i < grammar.productions.size(); i++ ){ Production production = grammar.productions.get(i); if( DerivesLambda( production ) ) grammar.derivesLambda.insertOverwrite( production.getLHS(), true ); } }
bool checkprod(Production p) { if(index == p.getindex()) { if(lprod.compare(p.getlprod()) == 0) { for(int i=0;i<production.size();i++) if(production[i].compare(p.getprod(i))!=0) return false; return true; } else return false; } else return false; }
_non_terminal_ast handle_non_terminal(string& input, Production& p, Chart& chart) { int64_t stringStart; size_t stringLen; tie(stringStart, stringLen) = p.symbolInfo(0); return input.substr(stringStart, stringLen); }
bool Grammar::deriveEpsilon(const Production &prod) const { const int length = prod.getLength(); for(int s = 0; s < length; s++) { if(!getSymbol(prod.m_rightSide[s]).m_deriveEpsilon) { return false; } } return true; }
bool Grammar::canTerminate(const Production &prod) const { const int length = prod.getLength(); for(int s = 0; s < length; s++) { if(!getSymbol(prod.m_rightSide[s]).m_terminate) { return false; } } return true; }
static void generateRandomSentences(const map<string, Definition>& grammar, int numSentencesNeeded) { for (int i = 0; i < numSentencesNeeded; i++) { map<string,Definition>::const_iterator it; it = grammar.find("<start>"); const Production startProduction = it->second.getRandomProduction(); vector<string> sentence; // Copy startProduction into a vector for (auto pi = startProduction.begin(); pi != startProduction.end(); ++pi) { string word = *pi; sentence.push_back(word); } printProduction (grammar, sentence); } cout << endl; }
Node* Parser::makeNode(State* pState, UINT nEnd, Node* pV, NodeDict& ndV) { UINT nDot = pState->getDot() + 1; Production* pProd = pState->getProd(); UINT nLen = pProd->getLength(); if (nDot == 1 && nLen >= 2) return pV; INT iNtB = pState->getNt(); UINT nStart = pState->getStart(); Node* pW = pState->getNode(); Production* pProdLabel = pProd; if (nDot >= nLen) { // Completed production: label by nonterminal only nDot = 0; pProdLabel = NULL; } Label label(iNtB, nDot, pProdLabel, nStart, nEnd); Node* pY = ndV.lookupOrAdd(label); pY->addFamily(pProd, pW, pV); // pW may be NULL return pY; }
//Handle symbols _symbol_ast handle_symbol(string& input, Production& p, Chart& chart) { int64_t setIndex; size_t stateIndex; Production production; _symbol_ast out; tie(setIndex, stateIndex) = p.symbolInfo(0); production = chart.getState(setIndex, stateIndex).first; out.value_ = handle_non_terminal(input, production, chart); switch(p.number()){ case 0: out.type_ = _symbol_ast::type::NON_TERMINAL; break; case 1: out.type_ = _symbol_ast::type::TERMINAL; break; case 2: out.type_ = _symbol_ast::type::REGEX; break; default:; } return out; }
bool LL1Parser::parse(const vector<string>& str) { fstream f("../src/LogLL1"); f.clear(); bool accept = true; vector<string> w = str; w.push_back("$"); vector<string> stk = {g.s, "$"}; // stk.front(): top, stk.back(): bottom int ip = 0; string x = stk.front(); while(x != "$") { f << "stk: "; display(stk, f); f << endl; cout << "stk: "; display(stk); cout << endl; string a = w[ip]; int xIndex = g.getVariableIndex(x); int aIndex = g.getTerminalIndex(a); if(aIndex == -1) { aIndex = g.t.size(); } f << "x: " << x << endl << "a: " << a << endl; cout << "x: " << x << endl << "a: " << a << endl; if(x == a) { f << "match " << a << endl; cout << "match " << a << endl; stk.erase(stk.begin()); ++ip; } else if(in(x, g.t)) { f << "error" << endl; cout << "error" << endl; accept = false; break; } else if(m[xIndex][aIndex] == -1) { f << "error" << endl; cout << "error" << endl; accept = false; break; } else { Production pr = g.p[m[xIndex][aIndex]]; pr.display(f); f << endl; pr.display(); cout << endl; stk.erase(stk.begin()); if(!(pr.right.size() == 1 && pr.right[0] == "")) { for(auto it = pr.right.rbegin(); it != pr.right.rend(); ++it) { stk.insert(stk.begin(), *it); } } } f << endl; cout << endl; x = stk.front(); } f.close(); return accept; }
//Dado uma producao A -> x1 x2 ..xn //retorna o first da sequencia da producao comecando em startindex // por ex A - > x0 x1 x2 // se passar start = 1, vai retornar o first de FIRST(x1 x2) std::set<const GrammarSymbol*> GetFirstSet(const FirstSets& first, const Grammar& g, const Production& prod, int startIndex = 0) { std::set<const GrammarSymbol*> r; int epsilonCount = 0; for (int k = startIndex ; k < prod.GetNumOfRightSymbols(); k++) { const GrammarSymbol* pgs = prod.GetRightSymbol(k); // Put FIRST (Y1) - {epsilon} into FIRST (X) if (k == startIndex) { //Copia todos (-epsilon) de Y1first para Y1first(X) auto Y1first = first.Get(prod.GetRightSymbol(k)); if (Y1first.find(g.epsilon()) != Y1first.end()) { epsilonCount = 1; } for (auto it = Y1first.begin(); it != Y1first.end(); it++) { if (*it != g.epsilon()) { r.insert(*it); } } continue; } // O anterior tinha epsilon? auto YKfirst = first.Get(prod.GetRightSymbol(k - 1)); if (YKfirst.find(g.epsilon()) != YKfirst.end()) { epsilonCount++; //Copia todos (-epsilon) para first(X) auto Y1first = first.Get(prod.GetRightSymbol(k)); for (auto it = Y1first.begin(); it != Y1first.end(); it++) { if (*it != g.epsilon()) { r.insert(*it); } } } else { //se o anterior nao tinha epsilon ja para break; } } // se todos eram epsilon entao adicionar epsilon TODO -1 if (epsilonCount != 0 && epsilonCount == (prod.GetNumOfRightSymbols() - startIndex)) { r.insert(g.epsilon()); } return r; }
void store(Count clock, const Packet &p) { Production *prod = productions[p.parent]; assert(prod && "Store without a parent"); prod->store(clock, p); }
void load(Count clock, const Packet &p) { Production *prod = productions[p.parent]; assert(prod && "Load without a parent"); prod->load(clock, p); }
void GrammarParser::parseActionBody(const SourcePosition &sourcePos, CompactShortArray &usedDollar, const Production &prod) { for(;;) { switch(m_token) { case LCURL: next(); parseActionBody(sourcePos, usedDollar, prod); if(m_token != RCURL) { m_lex.error(_T("Expected '}'.")); } else { next(); } break; case RCURL: return; case EOI: m_lex.error(sourcePos, _T("This codeblock has no end.")); return; case DOLLARDOLLAR: { SourceText tmp; m_lex.getCollected(tmp); m_lex.collectEnd(); next(); m_actionBody += tmp.m_sourceText + _T("m_leftSide "); m_lex.collectBegin(); } break; case DOLLAR: { SourceText tmp; m_lex.getCollected(tmp); m_lex.collectEnd(); next(); if(m_token != NUMBER) { m_lex.error(_T("Expected number.")); m_actionBody += _T("$ "); } else { const int prodLength = prod.getLength(); const int symbolIndex = (int)m_lex.getNumber(); const int fromTop = prodLength - symbolIndex; if(symbolIndex < 1 || symbolIndex > prodLength) { m_lex.warning(m_lex.getSourcePos(), _T("$%d is not in range [1..%d]."), symbolIndex, prodLength); m_grammar.m_warningCount++; } else { if(m_grammar.isTerminal(prod.m_rightSide[symbolIndex-1])) { m_lex.warning(m_lex.getSourcePos(), _T("$%d is a terminal."), symbolIndex); m_grammar.m_warningCount++; } } next(); m_actionBody += tmp.m_sourceText + format(_T("getStackTop(%d)"), fromTop); } m_lex.collectBegin(); } break; default: next(); break; } } }
/** * Loads the base from a YAML file. * @param node YAML node. * @param save Pointer to saved game. */ void Base::load(const YAML::Node &node, SavedGame *save, bool newGame, bool newBattleGame) { Target::load(node); _name = Language::utf8ToWstr(node["name"].as<std::string>("")); if (!newGame || !Options::getBool("customInitialBase") || newBattleGame) { for (YAML::const_iterator i = node["facilities"].begin(); i != node["facilities"].end(); ++i) { std::string type = (*i)["type"].as<std::string>(); BaseFacility *f = new BaseFacility(_rule->getBaseFacility(type), this); f->load(*i); _facilities.push_back(f); } } for (YAML::const_iterator i = node["crafts"].begin(); i != node["crafts"].end(); ++i) { std::string type = (*i)["type"].as<std::string>(); Craft *c = new Craft(_rule->getCraft(type), this); c->load(*i, _rule, save); _crafts.push_back(c); } for (YAML::const_iterator i = node["soldiers"].begin(); i != node["soldiers"].end(); ++i) { Soldier *s = new Soldier(_rule->getSoldier("XCOM"), _rule->getArmor("STR_NONE_UC")); s->load(*i, _rule); if (const YAML::Node &craft = (*i)["craft"]) { std::string type = craft["type"].as<std::string>(); int id = craft["id"].as<int>(); for (std::vector<Craft*>::iterator j = _crafts.begin(); j != _crafts.end(); ++j) { if ((*j)->getRules()->getType() == type && (*j)->getId() == id) { s->setCraft(*j); break; } } } else { s->setCraft(0); } _soldiers.push_back(s); } _items->load(node["items"]); // Some old saves have bad items, better get rid of them to avoid further bugs for (std::map<std::string, int>::iterator i = _items->getContents()->begin(); i != _items->getContents()->end();) { if (std::find(_rule->getItemsList().begin(), _rule->getItemsList().end(), i->first) == _rule->getItemsList().end()) { _items->getContents()->erase(i++); } else { ++i; } } _scientists = node["scientists"].as<int>(_scientists); _engineers = node["engineers"].as<int>(_engineers); _inBattlescape = node["inBattlescape"].as<bool>(_inBattlescape); for (YAML::const_iterator i = node["transfers"].begin(); i != node["transfers"].end(); ++i) { int hours = (*i)["hours"].as<int>(); Transfer *t = new Transfer(hours); t->load(*i, this, _rule); _transfers.push_back(t); } for (YAML::const_iterator i = node["research"].begin(); i != node["research"].end(); ++i) { std::string research = (*i)["project"].as<std::string>(); ResearchProject *r = new ResearchProject(_rule->getResearch(research)); r->load(*i); _research.push_back(r); } for (YAML::const_iterator i = node["productions"].begin(); i != node["productions"].end(); ++i) { std::string item = (*i)["item"].as<std::string>(); Production *p = new Production(_rule->getManufacture(item), 0); p->load(*i); _productions.push_back(p); } _retaliationTarget = node["retaliationTarget"].as<bool>(_retaliationTarget); }
GrammarSet Predict::ComputeFirst( Production& production ){ return ComputeFirst( production.getRHS() ); }
_option_ast handle_option(string& input, Production& p, Chart& chart) { if (p.number() == 0) return "nullable"; return ""; }