├── README.md ├── example_cnf1.txt ├── .DS_Store ├── src ├── CYKAlgorithm.cpp └── CNF.cpp ├── .vs └── CYKAlgorithm │ └── v14 │ └── .suo ├── example_cnf2.txt ├── CMakeLists.txt ├── ReadMe.txt └── include └── CNF.h /README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example_cnf1.txt: -------------------------------------------------------------------------------- 1 | S->A B|B C 2 | A->B A|a 3 | B->C C|b 4 | C->A B|a 5 | -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/binhetech/CYKAlgorithm/master/.DS_Store -------------------------------------------------------------------------------- /src/CYKAlgorithm.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/binhetech/CYKAlgorithm/master/src/CYKAlgorithm.cpp -------------------------------------------------------------------------------- /.vs/CYKAlgorithm/v14/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/binhetech/CYKAlgorithm/master/.vs/CYKAlgorithm/v14/.suo -------------------------------------------------------------------------------- /example_cnf2.txt: -------------------------------------------------------------------------------- 1 | S->NP VP 2 | VP->VP PP 3 | VP->V NP 4 | VP->eats 5 | PP->P NP 6 | NP->Det N 7 | NP->she 8 | V->eats 9 | P->with 10 | N->fish 11 | N->fork 12 | Det->a 13 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | PROJECT(CYKAlgorithm) 3 | INCLUDE_DIRECTORIES(include) 4 | AUX_SOURCE_DIRECTORY(src DIR_SRCS) 5 | SET(CYKAlgorithm ${DIR_SRCS}) 6 | ADD_EXECUTABLE(${PROJECT_NAME} ${CYKAlgorithm}) 7 | add_definitions(-std=c++11) 8 | -------------------------------------------------------------------------------- /ReadMe.txt: -------------------------------------------------------------------------------- 1 | Building steps: 2 | 1. Open the "CYKAlgorithm" folder in terminal. 3 | 2. Type "mkdir build" to make a directory. 4 | 3. Go into the build directory and type "cmake .." and "make" to build the project. 5 | 4. Type "./CYKAlgorithm [Chomsky normal form CFG file path]" to run the project. 6 | 7 | This project will load the CFG file into the main memory and receive a user-input string. The project will print whether the string is accepted by the CFG or not. 8 | -------------------------------------------------------------------------------- /include/CNF.h: -------------------------------------------------------------------------------- 1 | // 2 | // CNF.h 3 | // CYKAlgorithm 4 | // 5 | // Created by Mengzhang Qian on 2018/5/6. 6 | // Copyright © 2018 QMZ. All rights reserved. 7 | // 8 | 9 | #ifndef _CNF_H_ 10 | #define _CNF_H_ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | typedef std::string Variable; 18 | typedef std::string Terminal; 19 | 20 | //************************************************************************************ 21 | //Implement a production rule with only non-terminal strings(variables) 22 | class ProductionRuleWithNonterminal { 23 | private: 24 | Variable name; 25 | Variable v1, v2; 26 | 27 | public: 28 | //Constructors 29 | ProductionRuleWithNonterminal(); 30 | ProductionRuleWithNonterminal(Variable name, Variable v1, Variable v2); 31 | //Change the production rule 32 | void changeRule(Variable name, Variable v1, Variable v2); 33 | //Judge whether two variables v1 and v2 can produce a variable through the production 34 | //Return value: the name of the produced variable or "" if they can't 35 | Variable produce(Variable v1, Variable v2) const; 36 | //Print the production 37 | void print() const; 38 | //Get the name of the variable that the production produces 39 | Variable getName() const; 40 | }; 41 | 42 | //************************************************************************************ 43 | //Implement a production rule with variable in left and terminal string in right 44 | class ProductionRuleWithTerminal { 45 | private: 46 | Variable name; 47 | Terminal str; 48 | 49 | public: 50 | //Constructors 51 | ProductionRuleWithTerminal(); 52 | ProductionRuleWithTerminal(Variable name, Terminal str); 53 | //Change the production rule 54 | void changeRule(Variable name, Terminal str); 55 | //Judge whether a string str can produce a variable through the production 56 | //Return value: the name of the produced variable or "" if it can't 57 | Variable produce(Terminal str) const; 58 | //Print the production 59 | void print() const; 60 | //Get the name of the variable that the production produces 61 | Variable getName() const; 62 | }; 63 | 64 | //************************************************************************************ 65 | //Implement a Chomsky normal form CFG 66 | class CNF { 67 | private: 68 | std::vector rulesWithNonterminal; 69 | std::vector rulesWithTerminal; 70 | Variable startSymbol; 71 | 72 | public: 73 | //Get the set of variables that the two sets of variable val1, val2 can produce 74 | std::set produce(std::set val1, std::set val2) const; 75 | //Get the set of variables that the string str can produce 76 | std::set produce(Terminal str) const; 77 | //Add a production rule 78 | void addRule(ProductionRuleWithNonterminal rule); 79 | //Add a production rule 80 | void addRule(ProductionRuleWithTerminal rule); 81 | //Get the start symbol of the CFG 82 | Variable getStartSymbol() const; 83 | //Print the CFG 84 | void print() const; 85 | }; 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /src/CNF.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // CNF.cpp 3 | // CYKAlgorithm 4 | // 5 | // Created by Mengzhang Qian on 2018/5/6. 6 | // Copyright © 2018 QMZ. All rights reserved. 7 | // 8 | 9 | #include "../include/CNF.h" 10 | 11 | //************************************************************************************ 12 | //Constructor 13 | ProductionRuleWithNonterminal::ProductionRuleWithNonterminal() { 14 | 15 | } 16 | 17 | //************************************************************************************ 18 | //Constructor 19 | ProductionRuleWithNonterminal::ProductionRuleWithNonterminal(Variable name, Variable v1, Variable v2) { 20 | this->name = name; 21 | this->v1 = v1; 22 | this->v2 = v2; 23 | } 24 | 25 | //************************************************************************************ 26 | //Change the production rule 27 | void ProductionRuleWithNonterminal::changeRule(Variable name, Variable v1, Variable v2) { 28 | this->name = name; 29 | this->v1 = v1; 30 | this->v2 = v2; 31 | } 32 | 33 | //************************************************************************************ 34 | //Judge whether two variables v1 and v2 can produce a variable through the production 35 | //Return value: the name of the produced variable or "" if they can't 36 | Variable ProductionRuleWithNonterminal::produce(Variable v1, Variable v2) const { 37 | if (v1 == this->v1 && v2 == this->v2) 38 | return name; 39 | else { 40 | Variable fail = ""; 41 | return fail; 42 | } 43 | } 44 | 45 | //************************************************************************************ 46 | //Print the production 47 | void ProductionRuleWithNonterminal::print() const { 48 | std::cout << name << "->" << v1 << ' ' << v2 << std::endl; 49 | } 50 | 51 | //************************************************************************************ 52 | //Get the name of the variable that the production produces 53 | Variable ProductionRuleWithNonterminal::getName() const { 54 | return name; 55 | } 56 | 57 | //************************************************************************************ 58 | //Constructor 59 | ProductionRuleWithTerminal::ProductionRuleWithTerminal() { 60 | 61 | } 62 | 63 | //************************************************************************************ 64 | //Constructor 65 | ProductionRuleWithTerminal::ProductionRuleWithTerminal(Variable name, Terminal str) { 66 | this->name = name; 67 | this->str = str; 68 | } 69 | 70 | //************************************************************************************ 71 | //Change the production rule 72 | void ProductionRuleWithTerminal::changeRule(Variable name, Terminal str) { 73 | this->name = name; 74 | this->str = str; 75 | } 76 | 77 | //************************************************************************************ 78 | //Judge whether a string str can produce a variable through the production 79 | //Return value: the name of the produced variable or "" if it can't 80 | Variable ProductionRuleWithTerminal::produce(Terminal str) const { 81 | if (this->str == str) 82 | return name; 83 | else { 84 | Variable fail = ""; 85 | return fail; 86 | } 87 | } 88 | 89 | //************************************************************************************ 90 | //Print the production 91 | void ProductionRuleWithTerminal::print() const { 92 | std::cout << name << "->" << str << std::endl; 93 | } 94 | 95 | //************************************************************************************ 96 | //Get the name of the variable that the production produces 97 | Variable ProductionRuleWithTerminal::getName() const { 98 | return name; 99 | } 100 | 101 | //************************************************************************************ 102 | //Get the set of variables that the two sets of variable val1, val2 can produce 103 | std::set CNF::produce(std::set val1, std::set val2) const { 104 | std::set vals; 105 | for (auto rule = rulesWithNonterminal.begin(); rule != rulesWithNonterminal.end(); rule++) { 106 | for (auto i = val1.begin(); i != val1.end(); i++) { 107 | for (auto k = val2.begin(); k != val2.end(); k++) { 108 | Variable val = rule->produce(*i, *k); 109 | if (val != "") 110 | vals.insert(val); 111 | } 112 | } 113 | } 114 | return vals; 115 | } 116 | 117 | //************************************************************************************ 118 | //Get the set of variables that the string str can produce 119 | std::set CNF::produce(Terminal str) const { 120 | std::set vals; 121 | for (auto i = rulesWithTerminal.begin(); i != rulesWithTerminal.end(); i++) { 122 | Variable val = i->produce(str); 123 | if (val != "") 124 | vals.insert(val); 125 | } 126 | return vals; 127 | } 128 | 129 | //************************************************************************************ 130 | //Add a production rule 131 | void CNF::addRule(ProductionRuleWithNonterminal rule) { 132 | rulesWithNonterminal.push_back(rule); 133 | } 134 | 135 | //************************************************************************************ 136 | //Add a production rule 137 | void CNF::addRule(ProductionRuleWithTerminal rule) { 138 | rulesWithTerminal.push_back(rule); 139 | } 140 | 141 | //************************************************************************************ 142 | //Get the start symbol of the CFG 143 | Variable CNF::getStartSymbol() const { 144 | return rulesWithNonterminal[0].getName(); 145 | } 146 | 147 | //************************************************************************************ 148 | //Print the CFG 149 | void CNF::print() const { 150 | for (auto i = rulesWithNonterminal.begin(); i != rulesWithNonterminal.end(); i++) { 151 | i->print(); 152 | } 153 | for (auto i = rulesWithTerminal.begin(); i != rulesWithTerminal.end(); i++) { 154 | i->print(); 155 | } 156 | } 157 | --------------------------------------------------------------------------------