#include "parser.h" string parser::get_token() { string type = tokens[0].type; return type; } void parser::check_datalog() { match("SCHEMES"); match("COLON"); if(get_token() == "FACTS") { error(); } check_schemelist(get_token()); match("FACTS"); match("COLON"); check_factlist(get_token()); match("RULES"); match("COLON"); check_rulelist(get_token()); match("QUERIES"); match("COLON"); check_querylist(get_token()); out(); } string parser::out() { stringstream s; s << "Success!" << endl; s << "Schemes(" << schemelist.size() << "):" << endl; for(unsigned int i = 0; i < schemelist.size(); i++) { s << " " << schemelist[i].toString(); } s << "Facts(" << factlist.size() << "):" << endl; for(unsigned int i = 0; i < factlist.size(); i++) { s << " " << factlist[i].toString(false); } s << "Rules(" << rulelist.size() << "):" << endl; for(unsigned int i = 0; i < rulelist.size(); i++) { s << " " << rulelist[i].toString(); } s << "Queries(" << querylist.size() << "):" << endl; double a = 0; for(unsigned int i = 0; i < querylist.size(); i++) { s << " " << querylist[i].toString(a); } s << "Domain(" << domain.size() << "):" << endl; for (auto it=domain.cbegin(); it != domain.cend(); ++it) { s << " '" << *it << "'" << endl; } return s.str(); } void parser::check_schemelist(string type) { if(type == "FACTS") { return; } else { check_scheme(type); check_schemelist(get_token()); } } void parser::check_scheme(string type) { schemelist.push_back(check_predicate(type)); } void parser::check_factlist(string type) { if(type == "RULES") { return; } else { check_fact(type); check_factlist(get_token()); } } void parser::check_fact(string type) { factlist.push_back(check_predicate(type)); match("PERIOD"); } void parser::check_rulelist(string type) { if(type == "QUERIES") { return; } else { check_rule(type); check_rulelist(get_token()); } } void parser::check_rule(string type) { rule r; r.head = check_predicate(type); match("COLON_DASH"); check_predicate_list(get_token(), r); match("PERIOD"); rulelist.push_back(r); } void parser::check_querylist(string type) { check_query(type); if(tokens.empty()) { return; } else { check_querylist(get_token()); } } void parser::check_query(string type) { querylist.push_back(check_predicate(type)); match("Q_MARK"); } void parser::check_predicate_list(string type, rule& r) { r.pred_rule.push_back(check_predicate(type)); if(get_token() == "COMMA") { match("COMMA"); check_predicate_list(get_token(), r); } else { return; } } predicate parser::check_predicate(string type) { predicate pred; pred.id = tokens[0].character; match("ID"); match("LEFT_PAREN"); if(get_token() == "RIGHT_PAREN") { error(); } check_parameterlist(get_token(), pred); match("RIGHT_PAREN"); return pred; } void parser::check_parameterlist(string type, predicate& pred) { if(type == "RIGHT_PAREN") { return; } else { check_parameter(type, pred); if(get_token() == "COMMA") { match("COMMA"); if(get_token() == "RIGHT_PAREN") { error(); } check_parameterlist(get_token(), pred); } else { return; } } } void parser::check_parameter(string type, predicate& pred) { parameter para; if(type == "STRING") { domain.insert(tokens[0].character); para.param = tokens[0].character; para.type = tokens[0].type; pred.pred_list.push_back(para); match("STRING"); return; } else if(type == "ID") { para.param = tokens[0].character; para.type = tokens[0].type; pred.pred_list.push_back(para); match("ID"); return; } else { error(); } } void parser::match(string type) { if(get_token() == type) { if(tokens.empty()) { error(); } else { tokens.erase(tokens.begin()); } } else { error(); } } void parser::error() { stringstream oss; oss << tokens[0] << endl; throw oss.str(); }