201 lines
4.4 KiB
C++
201 lines
4.4 KiB
C++
#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();
|
|
}
|