diff options
Diffstat (limited to 'fast/grammar.cc')
-rw-r--r-- | fast/grammar.cc | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/fast/grammar.cc b/fast/grammar.cc index 9f26bd7..a8e2747 100644 --- a/fast/grammar.cc +++ b/fast/grammar.cc @@ -3,5 +3,160 @@ namespace G { +NT::NT(string& s) +{ + s.erase(0, 1); + s.pop_back(); + stringstream ss(s); + string buf; + size_t c = 0; + index = 0; + while (ss.good() && getline(ss, buf, ',')) { + if (c == 0) { + symbol = buf; + } else { + index = stoi(buf); + } + c++; + } +} + +T::T(string& s) +{ + word = s; +} + +Item::Item(string& s) +{ + if (s.front() == '[' && s.back() == ']') { + type = NON_TERMINAL; + nt = new NT(s); + } else { + type = TERMINAL; + t = new T(s); + } +} + +Rule::Rule(string& s) +{ + stringstream ss(s); + size_t c = 0; + string buf; + while (ss >> buf) { + if (buf == "|||") { c++; continue; } + if (c == 0) { // LHS + lhs = new NT(buf); + } else if (c == 1) { // RHS + rhs.push_back(new Item(buf)); + if (rhs.back()->type == NON_TERMINAL) arity++; + } else if (c == 2) { // TARGET + target.push_back(new Item(buf)); + } else if (c == 3) { // F TODO + } else if (c == 4) { // A TODO + } else { // ERROR FIXME + } + if (c == 4) break; + } + arity = 0; +} + +Grammar::Grammar(string fn) +{ + ifstream ifs(fn); + string line; + while (getline(ifs, line)) { + G::Rule* r = new G::Rule(line); + rules.push_back(r); + if (r->arity == 0) + flat.push_back(r); + else if (r->rhs.front()->type == NON_TERMINAL) + start_nt.push_back(r); + else + start_t.push_back(r); + } +} + +string +Item::repr() const +{ + ostringstream os; + if (type == TERMINAL) + os << t->repr(); + else + os << nt->repr(); + return os.str(); +} + +ostream& +operator<<(ostream& os, const Item& i) +{ + return os << i.repr(); +} + +string +NT::repr() const +{ + ostringstream os; + os << "NT<" << symbol << "," << index << ">"; + return os.str(); +} + +ostream& +operator<<(ostream& os, const NT& nt) +{ + return os << nt.repr(); +} + +string +T::repr() const +{ + ostringstream os; + os << "T<" << word << ">"; + return os.str(); +} + +ostream& +operator<<(ostream& os, const T& t) +{ + return os << t.repr(); +} + +string +Rule::repr() const +{ + ostringstream os; + os << "Rule<lhs=" << lhs->repr() << \ + ", rhs:{"; + for (auto it = rhs.begin(); it != rhs.end(); it++) { + os << (**it).repr(); + if (next(it) != rhs.end()) os << " "; + } + os << "}, target:{"; + for (auto it = target.begin(); it != target.end(); it++) { + os << (**it).repr(); + if (next(it) != target.end()) os << " "; + } + os << "}" \ + ", f:" << "TODO" << \ + ", arity=" << arity << \ + ", map:" << "TODO" << \ + ">"; + return os.str(); +} + +ostream& +operator<<(ostream& os, const Rule& r) +{ + return os << r.repr(); +} + +ostream& +operator<<(ostream& os, const Grammar& g) +{ + for (auto it = g.rules.begin(); it != g.rules.end(); it++) + os << (**it).repr() << endl; + return os; +} + } // namespace |