bool parse(const sm_type &sm_, iterator &iter_, basic_match_results<sm_type> &results_, token_vector &productions_, std::multimap<typename sm_type::id_type, token_vector> *prod_map_) { while (results_.entry.action != error) { switch (results_.entry.action) { case error: break; case shift: results_.stack.push_back(results_.entry.param); productions_.push_back(typename token_vector::value_type(iter_->id, iter_->first, iter_->second)); if (results_.token_id != 0) { ++iter_; } results_.token_id = iter_->id; if (results_.token_id == iterator::value_type::npos()) { results_.entry.action = error; results_.entry.param = unknown_token; } else { results_.entry = sm_._table[results_.stack.back() * sm_._columns + results_.token_id]; } break; case reduce: { const std::size_t size_ = sm_._rules[results_.entry.param].second.size(); token<iterator> token_; if (size_) { if (prod_map_) { prod_map_->insert(std::make_pair(results_.entry.param, token_vector(productions_.end() - size_, productions_.end()))); } token_.first = (productions_.end() - size_)->first; token_.second = productions_.back().second; results_.stack.resize(results_.stack.size() - size_); productions_.resize(productions_.size() - size_); } else { if (productions_.empty()) { token_.first = token_.second = iter_->first; } else { token_.first = token_.second = productions_.back().second; } } results_.token_id = sm_._rules[results_.entry.param].first; results_.entry = sm_._table[results_.stack.back() * sm_._columns + results_.token_id]; token_.id = results_.token_id; productions_.push_back(token_); break; } case go_to: results_.stack.push_back(results_.entry.param); results_.token_id = iter_->id; results_.entry = sm_._table[results_.stack.back() * sm_._columns + results_.token_id]; break; } if (results_.entry.action == accept) { const std::size_t size_ = sm_._rules[results_.entry.param].second.size(); if (size_) { results_.stack.resize(results_.stack.size() - size_); } break; } } return results_.entry.action == accept; }
void next(const sm_type &sm_, iterator &iter_, basic_match_results<sm_type> &results_, iterator &last_eoi_, token_vector &productions_) { switch (results_.entry.action) { case error: break; case shift: { const typename sm_type::entry *ptr_ = &sm_._table[results_.entry.param * sm_._columns]; results_.stack.push_back(results_.entry.param); productions_.push_back(typename token_vector::value_type(iter_->id, iter_->first, iter_->second)); if (results_.token_id != 0) { ++iter_; } results_.token_id = iter_->id; if (results_.token_id == iterator::value_type::npos()) { results_.entry.action = error; results_.entry.param = unknown_token; } else { results_.entry = ptr_[results_.token_id]; } if (ptr_->action != error) { last_eoi_ = iter_; } break; } case reduce: { const std::size_t size_ = sm_._rules[results_.entry.param].second.size(); token<iterator> token_; if (size_) { token_.first = (productions_.end() - size_)->first; token_.second = productions_.back().second; results_.stack.resize(results_.stack.size() - size_); productions_.resize(productions_.size() - size_); } else { if (productions_.empty()) { token_.first = token_.second = iter_->first; } else { token_.first = token_.second = productions_.back().second; } } results_.token_id = sm_._rules[results_.entry.param].first; results_.entry = sm_._table[results_.stack.back() * sm_._columns + results_.token_id]; token_.id = results_.token_id; productions_.push_back(token_); break; } case go_to: results_.stack.push_back(results_.entry.param); results_.token_id = iter_->id; results_.entry = sm_._table[results_.stack.back() * sm_._columns + results_.token_id]; break; case accept: { const std::size_t size_ = sm_._rules[results_.entry.param].second.size(); if (size_) { results_.stack.resize(results_.stack.size() - size_); } break; } } }