# PQL ```plantuml @startuml participant TestWrapper as TestWrapper participant PQL as pql participant PQLParser as parser participant PQLEvaluator as eval participant PKB as pkb TestWrapper -> pql : answerQuery(string query) activate TestWrapper pql -> parser: new() activate parser pql <-- parser: parser instance deactivate parser pql -> parser: runLexer(string query) activate parser loop char in query parser -> parser : tokens.add(token) end deactivate parser pql -> parser : runParser(&synonyms, &selected) activate parser parser -> parser : parseDeclarations() activate parser parser -> parser : synonyms.add(s) deactivate parser parser -> parser : parseSelected() activate parser parser -> parser : selected = s deactivate parser parser -> parser : parseSuchThat() activate parser parser -> parser : relations.add(r) deactivate parser deactivate parser pql -> eval : evalQuery(&synonyms, &selected) eval -> eval : filterSynonyms() activate eval loop synonym in synonyms eval -> pkb : isType(synonym) end deactivate eval eval -> eval : generateTuples() activate eval eval --> eval : tuples(id, .., id) deactivate eval eval -> eval : filterTuples() loop relation in relations loop tuple in tuples eval -> pkb : isRelation() end end eval -> eval : getSelectedFromTuple() activate eval eval -> pkb : getValue(id) eval --> eval : vector<string> result deactivate eval TestWrapper <-- pql : list<string> results deactivate TestWrapper @enduml ``` ## PKB design stmt by type: vector<int> getAssignments() vector<int> getIfs() vector<int> getWhiles() vector<int> getCalls() vector<int> getReads() vector<int> getPrints() by name: vector<string> getVariableNames() vector<string> getProcedureNames() design abstractions: bool uses(int assign_ln/print_ln/if_ln/while_ln/call_ln, string var_name) bool uses(string proc_name, string var_name) bool modifies(int assign_ln/read_ln/if_ln/while_ln/call_ln, string var_name) bool modifies(string proc_name, string var_name) bool follows(int ln1, int ln2) bool follows*(int ln1, int ln2) bool parent(int ln1, int ln2) bool parent*(int ln1, int ln2) by pattern: bool pattern(int ln, string lhs, string rhs) vector<int> pattern(string lhs, string rhs) assign a; while w; Select w such that Parent* (w, a) pattern a (“count”, _) procedure printAscending { read num1; read num2; noSwap = 0; if (num1 > num2) then { temp = num1; num1 = num2; num2 = temp; } else { noSwap = 1; } if (num1 > num2) { print num1; } print num1; print num2; print noSwap; temp = temp + 1 } assign a; if x; Select x such that Parent*(x, a) pattern a (“temp”, _) Select x: 63 and 74 such that Parent* (x, a): 63 pattern a(“temp”, _): 63 variable: v assign: a select: a clauses: uses(a,v), modifies(a,v) pattern: pattern a (“temp”, _) variable v; assign a; Select a such that Uses(a, v) and Modifies(a, v); v: "temp", "num1", "num2" from PKB vars = (a, v, x) set = {()} for var in vars: new_set = {} for tuple in set: for attr in pkb.get(var.type): new_tuple = tuple + attr new_set.add(new_tuple) set = new_set a = 61, 52, 44 v = "temp1", "num" {(61), (52), (44)} // get stmt line numbers by type: vector<int> getAssignments(); vector<int> getIfs(); vector<int> getWhiles(); vector<int> getCalls(); vector<int> getReads(); vector<int> getPrints(); // get names vector<string> getVariableNames(); vector<string> getProcedureNames(); // lineNumber: assign_ln/print_ln/if_ln/while_ln/call_ln bool isUses(int lineNumber, string varName); bool isUses(string procName, string varName); bool isModifies(int lineNumber, string varName); bool isModifies(string procName, string varName); bool isFollows(int lineNumber1, int lineNumber2); bool isFollowsStar(int lineNumber1, int lineNumber2); bool isParent(int lineNumber1, int lineNumber2); bool isParentStar(int lineNumber1, int lineNumber2); // by pattern: bool isPattern(int lineNumber, string lhs, string rhs); vector<int> getAssignmentsWithPattern(string lhs, string rhs); Assign a; Variable v; Select a such that Uses(a, v); Token Type Name assign assign name a ; ; variable variable name v ; ; select select name a such that such that uses uses ( ( name a , , name v ) ) ; ; Synonym type: name: v type: variable synonyms.push(s) Uses: Uses(a, v) Uses type: l: "a", synonym r: "v", synonym Uses("procname", a) Uses type: l: "procname", procedure r: "a", synonym Uses("procname", _) Uses type: l: "procname", procedure r: "_", wildcard relations.push(...)