Skip to content

Commit

Permalink
Add print_table impl and fix minor bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
Quarz0 committed Apr 21, 2018
1 parent c067c43 commit e50583e
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 12 deletions.
80 changes: 70 additions & 10 deletions parsetable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,18 @@
parsetable::entry::entry() {
}

parsetable::entry::entry(parsetable::entry::States _state, cfg::symbol::production *_prod) {
parsetable::entry::entry(parsetable::entry::States _state) {
state = _state;
prod = _prod;
}

parsetable::parsetable(cfg grammar) {
std::unordered_map<std::string, parsetable::entry> entries;
for (std::string &sym : grammar.get_symbols()) {
if (grammar.get_symbol(sym)->is_terminal() && !grammar.get_symbol(sym)->is_eps()) {
entries[sym] = parsetable::entry::entry(parsetable::entry::States::ERROR, nullptr);
entries[sym] = parsetable::entry(parsetable::entry::States::ERROR);
}
}
entries[EOI] = parsetable::entry::entry(parsetable::entry::States::ERROR, nullptr);
entries[EOI] = parsetable::entry(parsetable::entry::States::ERROR);

for (std::string &sym : grammar.get_symbols()) {
if (!grammar.get_symbol(sym)->is_terminal()) {
Expand All @@ -25,19 +24,19 @@ parsetable::parsetable(cfg grammar) {

for (std::string &sym : grammar.get_symbols()) {
bool has_eps_prod = false;
cfg::symbol::production *eps_prod = nullptr;
for (cfg::symbol::production &prod : grammar.get_symbol(sym)->get_productions()) {
cfg::symbol::production eps_prod;
for (cfg::symbol::production prod : grammar.get_symbol(sym)->get_productions()) {
for (std::string first : prod.get_first()) {
if (grammar.get_symbol(first)->is_eps()) {
has_eps_prod = true;
eps_prod = &prod;
eps_prod = prod;
} else {
if (table[sym][first].state != parsetable::entry::States::ERROR) {
throw std::invalid_argument(
"Grammar is not LL(1). Entry [" + sym + "," + first + "] has duplicate values.");
}
table[sym][first].state = parsetable::entry::States::PROD;
table[sym][first].prod = &prod;
table[sym][first].prod = prod;
}
}
}
Expand All @@ -50,7 +49,6 @@ parsetable::parsetable(cfg grammar) {
table[sym][follow].prod = eps_prod;
table[sym][follow].state = parsetable::entry::States::PROD;
} else {
table[sym][follow].prod = nullptr;
table[sym][follow].state = parsetable::entry::States::SYNC;
}
}
Expand All @@ -63,11 +61,73 @@ parsetable::entry parsetable::get_entry(std::string nonterm, std::string next_in
}
if (!parsetable::table[nonterm].count(next_input)) {
cfg::symbol::production p;
return parsetable::entry(parsetable::entry::States::ERROR, nullptr);
return parsetable::entry(parsetable::entry::States::ERROR);
}
return parsetable::table[nonterm][next_input];
}

std::string parsetable::production_to_str(cfg::symbol::production p) {
std::string s = "";
for (cfg::symbol *sym : p.get_symbols()) {
if (sym->is_eps()) {
s += "\\L";
}
else {
s += sym->get_key();
}
}
return s;
}

void parsetable::print_table() {
using namespace std;

if (table.empty()) return;

vector<vector<string>> T;
int max_len = 0;

for (auto &k : table) {
T.push_back(vector<string>());
T.back().push_back("");
for (auto &t : k.second) {
T.back().push_back(t.first);
max_len = max_len < T.back().back().length() ? T.back().back().length() : max_len;
}
break;
}

for (auto &k : table) {
T.push_back(vector<string>());
T.back().push_back(k.first);
max_len = max_len < T.back().back().length() ? T.back().back().length() : max_len;
for (int i = 1; i < T[0].size(); i++) {
if (table[T.back()[0]][T[0][i]].state == parsetable::entry::States::ERROR) {
T.back().push_back("\\ERROR");
} else if (table[T.back()[0]][T[0][i]].state == parsetable::entry::States::SYNC) {
T.back().push_back("\\SYNC");
} else {
T.back().push_back(T.back()[0] + " -> " + production_to_str(table[T.back()[0]][T[0][i]].prod));
}
max_len = max_len < T.back().back().length() ? T.back().back().length() : max_len;
}
}

for (int i = 0; i < T.size(); i++) {
for (int j = 0; j < T[i].size(); j++) {
string temp;
if (T[i][j] == EOI) {
temp = "\\$";
} else {
temp = T[i][j];
}
cout << temp;
for (int k = temp.length(); k <= max_len; k++){
cout << ' ';
}
cout << "| ";
}
cout << endl;
}
cout << endl;
}
6 changes: 4 additions & 2 deletions parsetable.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,19 @@ class parsetable {
ERROR, SYNC, PROD
};
States state;
cfg::symbol::production *prod;
cfg::symbol::production prod;

entry();

entry(States _state, cfg::symbol::production *_prod);
entry(States _state);
};

parsetable(cfg);

entry get_entry(std::string nonterm, std::string next_input);

std::string production_to_str(cfg::symbol::production p);

void print_table();

private:
Expand Down

0 comments on commit e50583e

Please sign in to comment.