diff --git a/query/queryLanguage/QueryParser.cpp b/query/queryLanguage/QueryParser.cpp index 0950f233e5e19b223f70a9a79fb2af5da0463a3a..3c52c6d81b3a7af48188b264af72fa2ec978685b 100644 --- a/query/queryLanguage/QueryParser.cpp +++ b/query/queryLanguage/QueryParser.cpp @@ -22,8 +22,9 @@ void QueryParser::parse( string input ) { query = input; + preprocess(); Token current; - queryTree = Constraint ( input ); + queryTree = Constraint ( query ); } /*** @@ -120,7 +121,7 @@ vector<Tuple * > QueryParser::breakOnOR( string input ) closedBracket.insert(')'); closedBracket.insert('}'); closedBracket.insert(']'); - vector<string> query = splitStr (input, ' ', true); + vector<string> query = splitStr (input, ' ', false); vector<Tuple *> constraintList; int start = 0; @@ -135,6 +136,8 @@ vector<Tuple * > QueryParser::breakOnOR( string input ) while ( depth != 0) { + if( i > query.size() ) + break; if( query[ i ] == "(") ++depth; else if ( query[ i ] == ")") @@ -144,6 +147,7 @@ vector<Tuple * > QueryParser::breakOnOR( string input ) if( text!= "") text+=" "; text+=query[ i ]; + ++i; } } Tuple * subConstraint = Constraint( text ); @@ -163,12 +167,13 @@ vector<Tuple * > QueryParser::breakOnOR( string input ) if( j < ( i -1 ) ) text+= " "; } - if( text == "" || text == " ") - break; - - Tuple * subConstraint = Constraint( text ); - constraintList.push_back( subConstraint ); + if( text != "" && text != " ") + { + Tuple * subConstraint = Constraint( text ); + constraintList.push_back( subConstraint ); + } start = i + 1; + } else if( i == query.size( ) - 1 ) { @@ -281,8 +286,8 @@ vector<Tuple * > QueryParser::breakOnAND( string input ) if( text!= "") text+=" "; text+=query[ i ]; + ++i; } - ++i; } Tuple * subConstraint = Constraint( text ); constraintList.push_back( subConstraint ); @@ -294,19 +299,6 @@ vector<Tuple * > QueryParser::breakOnAND( string input ) } else if( MatchAND( query[ i ]) && depth == 0 ) { - string text; - for ( int j = start; j < i; ++ j) - { - text+= query[ j ]; - if( j < ( i -1 ) ) - text+= " "; - } - if( text == "" || text == " ") - break; - - Tuple * subConstraint = Constraint( text ); - constraintList.push_back( subConstraint ); - start = i + 1; } else if( depth == 0 ) { @@ -325,18 +317,31 @@ vector<Tuple * > QueryParser::breakOnAND( string input ) */ void QueryParser::printCompiledQuery() { - cout << "Query Tree: \n"; + cout << "\nQuery Tree: \n"; + cout << getTestingTree(); + + } + +/*** + * generates the string that the printCompiledQuery will print + * + */ +string QueryParser::getTestingTree() + { + string output = ""; deque<Tuple *> queue; deque<int> levelQueue; queue.push_back( queryTree ); levelQueue.push_back( 0 ); - traverse( queue, levelQueue ); + traverse( queue, levelQueue, output ); + return output; } -void QueryParser::traverse(deque< Tuple*> queue, deque< int> levels) +void QueryParser::traverse(deque< Tuple*> queue, deque< int> levels, string &output) { int deepest = 0; + int level = 0; while(!queue.empty()) { Tuple *current = queue.front ( ); @@ -348,18 +353,21 @@ void QueryParser::traverse(deque< Tuple*> queue, deque< int> levels) queue.push_back( current->Next[ i ] ); levels.push_back( currLevel + 1); } - cout << " | "; + output += " | "; if( currLevel > deepest) { deepest = currLevel; - cout << "\n[ "<<deepest<<" ] "; + output += "\n[ "; + output += to_string(deepest); + output += " ] "; } - cout << " " << current->object.text << " "; + output += " "; + output += current->object.text; + output += " "; } } - /*** * destructor for the Query Parser */ @@ -380,4 +388,23 @@ void QueryParser::delete_children( Tuple* node ) delete_children( node->Next[ i ] ); delete node->Next[ i ]; } + } + +void QueryParser::preprocess( ) + { + string formattedString; + for( int i = 0; i < query.size(); ++i) + { + if( query[ i ] == '(' || query[ i ] == ')') + { + formattedString += " "; + formattedString += query[i] ; + formattedString += " "; + } + else + { + formattedString+= query[i]; + } + } + query = formattedString; } \ No newline at end of file diff --git a/query/queryLanguage/QueryParser.h b/query/queryLanguage/QueryParser.h index bdd956d32dee2b83e1b8209baaab19965b095b7b..d84902dce328d56111d8320aa73eb64c46deca5c 100644 --- a/query/queryLanguage/QueryParser.h +++ b/query/queryLanguage/QueryParser.h @@ -49,6 +49,7 @@ public: vector<Tuple * > breakOnAND( string input ); void printCompiledQuery( ); + string getTestingTree( ); ~QueryParser ( ); @@ -56,7 +57,8 @@ public: Tuple* queryTree; string query; private: - void traverse(deque< Tuple*> queue, deque< int> levels); + void preprocess( ); + void traverse(deque< Tuple*> queue, deque< int> levels, string &output); void delete_children( Tuple* node ); bool MatchOR( string input ); bool MatchAND( string input ); diff --git a/query/queryLanguage/tests/testQueryParser.cpp b/query/queryLanguage/tests/testQueryParser.cpp index f404e38c62e1b24a6d2f99db973c42259a19dcb6..d7250cf07cd8b21ef5695429859b436247371da8 100644 --- a/query/queryLanguage/tests/testQueryParser.cpp +++ b/query/queryLanguage/tests/testQueryParser.cpp @@ -5,19 +5,142 @@ #include "../QueryParser.h" #include<iostream> #include <fstream> +#include <cassert> + +using namespace std; +void testAND(); +void testOR(); +void testSimple(); +void testORwithAND(); +void testnestedOR(); +//void nestedAND(); +void testNestedORwithAND(); int main() { - string query = "apollo moon OR landing"; - QueryParser parser; - parser.parse( query ); - parser.printCompiledQuery(); + cout << "Starting QueryLang tests...\n"; + testAND(); + testOR(); + testSimple (); + testORwithAND (); + testNestedORwithAND(); + testnestedOR(); + + } + +void testAND() + { + cout << "Testing AND...\n"; + string query = "Is Lebron james the goat"; + QueryParser lebronParser; + lebronParser.parse( query ); + string correct = " | -AND- | \n[ 1 ] Is | Lebron | james | the | goat "; + assert(correct == lebronParser.getTestingTree( )); + + string dessertQuery = "I like cookies AND cake & pie && icecream and dessert"; + QueryParser dessertParser; + dessertParser.parse( dessertQuery ); + string correctDesserts = " | -AND- | \n[ 1 ] I | like | cookies | cake | pie | icecream | dessert "; + assert(correctDesserts == dessertParser.getTestingTree( )); + cout << "All AND tests passed!\n"; + + } + +void testOR() + { + cout << "Testing OR..\n"; + string query = "who or what OR when || where | why"; + QueryParser Parser; + Parser.parse( query ); + string correct = " | -OR- | \n[ 1 ] who | what | when | where | why "; + assert(correct == Parser.getTestingTree( )); + + string simple = "left or right"; + QueryParser simpleParser; + simpleParser.parse( simple ); + string simpleCorrect = " | -OR- | \n[ 1 ] left | right "; + assert( simpleCorrect == simpleParser.getTestingTree( ) ); + + cout << "All OR tests passes\n"; + + } + +void testSimple() + { + cout << "Testing Simple Case..\n"; + string simple = "Zane"; + QueryParser Parser; + Parser.parse( simple ); + string correct = " | Zane "; + assert(correct == Parser.getTestingTree( )); + cout<<"All simple tests passed!\n"; + } + +void testORwithAND() + { + cout << "Testing OR with AND\n"; + string nasa = "moon mission was a lie OR truth "; + QueryParser Parser; + Parser.parse( nasa ); + string correct = " | -OR- | \n" + "[ 1 ] -AND- | truth | \n" + "[ 2 ] moon | mission | was | a | lie "; + assert( correct == Parser.getTestingTree( ) ); + + string earth = "the earth is || isnt flat or round"; + QueryParser earthParser; + earthParser.parse( earth ); + + correct = " | -OR- | \n" + "[ 1 ] -AND- | -AND- | round | \n" + "[ 2 ] the | earth | is | isnt | flat "; + + assert( correct == earthParser.getTestingTree( ) ); + + cout <<"All OR and AND tests passed!\n"; + } + + +void testnestedOR() + { + cout << "Testing nestedOR with AND\n"; + string RB = "karan OR ( chris OR ( kareem or omaury ) ) "; + QueryParser RBParser; + RBParser.parse( RB ); + string correct = " | -OR- | \n" + "[ 1 ] karan | -OR- | \n" + "[ 2 ] chris | -OR- | \n" + "[ 3 ] kareem | omaury "; + assert( correct == RBParser.getTestingTree( ) ); + + string WR = "( DPJ or Tarik ) or (nico or oliver) or kekoa"; + QueryParser WRParser; + WRParser.parse( WR ); + correct = " | -OR- | \n" + "[ 1 ] -OR- | -OR- | kekoa | \n" + "[ 2 ] DPJ | Tarik | nico | oliver "; + assert( correct == WRParser.getTestingTree( )); + } +void testNestedORwithAND() + { + cout << "Testing nestedOR with AND\n"; + string nasa = "moon mission was a ( lie OR truth )"; + QueryParser Parser; + Parser.parse( nasa ); + string correct = " | -AND- | \n" + "[ 1 ] moon | mission | was | a | -OR- | \n" + "[ 2 ] lie | truth "; + assert( correct == Parser.getTestingTree( ) ); - string query1 = " apollo moon ( landing OR fake )"; - QueryParser parser1; - parser1.parse( query1 ); - parser1.printCompiledQuery (); + string earth = "the earth ( is || isnt)( flat or round )"; + QueryParser earthParser; + earthParser.parse( earth ); + correct = " | -AND- | \n" + "[ 1 ] the | earth | -OR- | -OR- | \n" + "[ 2 ] is | isnt | flat | round "; + assert( correct == earthParser.getTestingTree( ) ); + cout <<"All nested OR and AND tests passed!\n"; + } - } \ No newline at end of file