// include #include #include #include #include #include #include #include #include #include "grammar.h" #include "grammar_classes.h" using namespace std; using namespace boost::spirit; typedef tree_match parse_tree_match_t; typedef parse_tree_match_t::tree_iterator iter_t; typedef map typemap; typedef tree_node > treenode; static const bool default_debug = false; static bool debug; void print_parse_tree(const iter_t& it,typemap& rule_names,int indent=0) { size_t kids = it->children.size(); string blanks=string(3*indent,' '); string nodetype=rule_names[it->value.id().to_long()]; string val=string(it->value.begin(),it->value.end()); cout << blanks << "Node with value '" << val << "' has type '" << nodetype << "', and has " << it->children.size() << " children." << endl; if (kids > 0) { cout << blanks << " Children nodes:" << endl; iter_t child=it->children.begin(); while(child!=it->children.end()) { print_parse_tree(child++,rule_names,1+indent); } } } string get_rule_name(const iter_t& it,typemap& rule_names) { return rule_names[it->value.id()]; } string get_rule_name(const treenode& tn,typemap& rule_names) { return rule_names[tn.value.id()]; } string get_node_value(const iter_t& node_it) { return( string(node_it->value.begin(),node_it->value.end()) ); } term* create_term(const iter_t& it,typemap& rule_names) { string rule_name = get_rule_name(it,rule_names); term* o; if ("parameter"==rule_name) { o = new parameter(get_node_value(it)); } else if ("constant"==rule_name) { o = new constant(get_node_value(it)); } else { o = new variable(get_node_value(it)); } return o; } pred* create_pred( treenode& node, typemap& rule_names ) { pred* pred_p = new pred(string(node.value.begin(),node.value.end())); iter_t node_it=node.children.begin(); while(node_it!=node.children.end()) { pred_p->add_term(create_term(node_it,rule_names)); node_it++; } return pred_p; } object_tree* interpret_constraint_tree( treenode& subtree, typemap& rule_names, object_tree* ot ) { string rule=get_rule_name(subtree,rule_names); if ("literalgrouping"==rule) { // check if negation exists iter_t kids=subtree.children.begin(); int numnegs=0; while(kids!=subtree.children.end()) { if (get_rule_name(kids,rule_names)=="neg") { numnegs++; } kids++; } bool truth=(0 == (numnegs%2)); pred_group* p = new pred_group(truth); if (0==ot->start) { ot->start = p; } ot->set_attachpoint(p); } return ot; } bool evaluate( tree_parse_info<>& ast, typemap& rule_names ) { const iter_t& root_it=ast.trees.begin(); // first two children are constraint theory and update assert(2==root_it->children.size()); iter_t topkids = root_it->children.begin(); // constrait theory treenode ct = *topkids; object_tree* ot = new object_tree(); ot = interpret_constraint_tree( ct, rule_names, ot ); // update-expression translated to object-tree ++topkids; treenode upd= *topkids; pred* update_pred_p = create_pred(*topkids,rule_names); return true; } void after1(pred_base* objecttree) {} void after2(pred_base* objecttree) {} void print_help() { cout << endl; cout << "Constraint set and update are separated by ;" << endl; cout << "Word in capital letters is variable." << endl; cout << "Word in small letters is constant." << endl; cout << "? followed by word in small letters is parameter." << endl; cout << "Word in small letter followed by (...) is predicate." < is inequality." << endl; cout << "q quits" << endl; cout << endl; } int main(int argc, char **argv) { if (argc>1) { debug=true; } else { debug=default_debug; } const constraint_grammar cg; typemap rule_names; rule_names[constraint_grammar::PARAMETER_id]= "parameter"; rule_names[constraint_grammar::CONSTANT_id]= "constant"; rule_names[constraint_grammar::VARIABLE_id]= "variable"; rule_names[constraint_grammar::TERM_id]= "term"; rule_names[constraint_grammar::NEG_id]= "neg"; rule_names[constraint_grammar::DNEG_id]= "dneg"; rule_names[constraint_grammar::ATOM_id]= "atom"; rule_names[constraint_grammar::JUNC_id]= "junc"; rule_names[constraint_grammar::PRED_id]= "pred"; rule_names[constraint_grammar::EQ_id]= "eq"; rule_names[constraint_grammar::LITERAL_id]= "literal"; rule_names[constraint_grammar::LITERALGROUP_id]="literalgrouping"; rule_names[constraint_grammar::LITERALSET_id]= "literalset"; rule_names[constraint_grammar::UPDATE_id]= "update"; rule_names[constraint_grammar::ENTRY_id]= "entry"; cout << "Please enter denials and update, separated by ;" << endl; cout << "... or enter 'h' for help." << endl; string input; while (getline(cin, input)) { if ("" ==input) continue; if ("q"==input) return 1; if ("h"==input) { print_help(); cout << "Please enter denials and update, or " << endl; cout << "enter 'h' for help." << endl; continue; } tree_parse_info<> ast = ast_parse( input.c_str(), cg, space_p ); if (ast.full) { if (debug) { cout << "Parse tree:" << endl; cout << "----------" << endl; print_parse_tree(ast.trees.begin(),rule_names); } cout << endl << "Result:" << endl; cout << "------" << endl; if (evaluate(ast,rule_names)) { return 0; } else { return 1; } } else { cout << "Parsing failed; try again." << endl; } } return 0; }