├── Chapter4 ├── alg4_1 │ ├── alg4_1.cpp │ ├── gramIO.h │ ├── gramLib.h │ ├── grammer.txt │ └── lib.h ├── alg4_2 │ ├── alg4_2.cpp │ ├── gramIO.h │ ├── gramLib.h │ ├── grammer.txt │ ├── lib.h │ ├── makefile │ └── newGrammer.txt ├── alg4_3 │ ├── alg4_3.cpp │ ├── gramIO.h │ ├── gramLib.h │ ├── grammer.txt │ ├── lib.h │ ├── makefile │ └── newGrammer.txt ├── alg4_4 │ ├── 4_4_2 │ │ ├── alg4_4_2.cpp │ │ ├── gramIO.h │ │ ├── gramLib.h │ │ ├── grammer.txt │ │ ├── lib.h │ │ ├── makefile │ │ └── newGrammer.txt │ └── 4_4_4 │ │ ├── alg4_4_4.cpp │ │ ├── gramIO.h │ │ ├── gramLib.h │ │ ├── grammer.txt │ │ ├── lib.h │ │ ├── makefile │ │ └── newGrammer.txt ├── alg4_5 │ ├── alg4_5.cpp │ ├── gramIO.h │ ├── gramLib.h │ ├── grammer.txt │ ├── lib.h │ ├── makefile │ └── newGrammer.txt ├── alg4_6 │ ├── alg4_6.cpp │ ├── gramIO.h │ ├── gramLib.h │ ├── grammer.txt │ ├── latex.h │ ├── latexTable.cpp │ ├── lib.h │ ├── makefile │ ├── newGrammer.txt │ └── test ├── alg4_7 │ ├── alg4_7.cpp │ ├── gramIO.h │ ├── gramLib.h │ ├── grammer.txt │ ├── lib.h │ └── newGrammer.txt ├── alg4_8 │ ├── alg4_8.cpp │ ├── gramIO.h │ ├── gramLib.h │ ├── grammer.txt │ ├── lib.h │ └── newGrammer.txt ├── grammers │ ├── grammerA.txt │ ├── grammerB.txt │ ├── grammerC.txt │ ├── grammerD.txt │ ├── grammerE.txt │ ├── grammerF.txt │ ├── grammerG.txt │ ├── grammerH.txt │ └── grammerI.txt ├── library │ ├── gramIO.h │ ├── gramIO.h.txt │ ├── gramLib.cpp │ ├── gramLib.h │ ├── gramLib.h.txt │ ├── grammer.txt │ ├── grammer2.txt │ ├── grammerIO.cpp │ ├── index.html │ ├── lib.h │ ├── main.cpp │ └── test └── main │ ├── chap4.h │ ├── chap4.h.txt │ ├── gramIO.h │ ├── gramLib.h │ ├── grammer1.txt │ ├── grammer2.txt │ ├── grammer3.txt │ ├── grammer3Out.txt │ ├── grammerA.txt │ ├── grammerB.pdf │ ├── grammerB.txt │ ├── grammers │ ├── grammmer3.txt │ ├── main.cpp │ ├── makefile │ ├── test │ ├── testGramer.txt │ └── tmp.txt ├── Chapter5_6 ├── alg5_6 │ ├── alg5_6.cpp │ ├── dfa.txt │ ├── dfa2.txt │ ├── dfa3.txt │ ├── dfaOut.txt │ ├── finLib.h │ ├── finStateIO.h │ └── lib.h ├── alg5_7 │ ├── alg5_7.cpp │ ├── dfa.txt │ ├── dfa2.txt │ ├── dfa3.txt │ ├── dfa5.txt │ ├── dfaOut.txt │ ├── finLib.h │ ├── finStateIO.h │ └── lib.h ├── alg6_2 │ ├── alg6_2.cpp │ ├── dfa.txt │ ├── dfa5.txt │ ├── dfaOut.txt │ ├── finLib.h │ ├── finStateIO.h │ └── lib.h ├── library │ ├── dfa.txt │ ├── finLib.cpp │ ├── finLib.h │ ├── finStateIO.h │ ├── finiteStateIO.cpp │ └── lib.h └── main │ ├── chap5_6.h │ ├── dfa.txt │ ├── dfa2.txt │ ├── finLib.h │ ├── finStateIO.h │ ├── here.txt │ ├── lib.h │ ├── main.cpp │ ├── makefile │ ├── test │ └── test.cpp ├── Main ├── chap4.h ├── chap5_6.h ├── fa │ ├── alg5.6 │ ├── alg5.7 │ └── alg6.2 ├── gram │ ├── alg4.1 │ ├── alg4.2 │ ├── alg4.3 │ ├── alg4.4.2 │ ├── alg4.4.4 │ ├── alg4.5 │ ├── alg4.6 │ ├── alg4.7 │ └── alg4.8 ├── library │ ├── gramIO.h │ ├── lib.cpp │ └── lib.h ├── main.cpp ├── makefile └── shell └── README.md /Chapter4/alg4_1/alg4_1.cpp: -------------------------------------------------------------------------------- 1 | #include "gramIO.h" 2 | #include "gramLib.h" 3 | #include "lib.h" 4 | #include "../main/chap4.h" 5 | 6 | void rmRecursiveStart(std::set* grammer); 7 | void changeGrammer(std::set* grammer); 8 | char* generateNewStart(std::set* grammer); 9 | bool hasStart(char* rule, char* start); 10 | 11 | using namespace std; 12 | /*int main(){ 13 | alg4_1("grammer.txt", "newGrammer.txt"); 14 | }*/ 15 | 16 | void alg4_1(char* pathIn, char* pathOut){ 17 | 18 | set grammer[4]; 19 | parseGrammer(pathIn, grammer); 20 | rmRecursiveStart(grammer); 21 | outputGrammer(pathOut, grammer); 22 | } 23 | 24 | void rmRecursiveStart( set* grammer){ 25 | 26 | set::iterator itPro; 27 | char* start = *(grammer[START].begin()); 28 | int startSize = strlen(start); 29 | 30 | 31 | for( itPro = grammer[RULES].begin(); itPro != grammer[RULES].end(); itPro++){ 32 | if( varEqual( start, *itPro) ){ 33 | if( hasStart( getRulePtr( *itPro ), start )) { 34 | // add new start state 35 | changeGrammer(grammer); 36 | return; 37 | } 38 | } 39 | } 40 | 41 | } 42 | 43 | // Things to change: 44 | // First produce a new uniqe start symbol: S U (0)* EX: S0 or S00 etc... 45 | // Make new rule newStart -> oldStart (S' -> S) 46 | // Change the start symbol in grammer[START] 47 | void changeGrammer(set* grammer){ 48 | 49 | char* oldStart = *(grammer[START].begin()); 50 | char* newStart = generateNewStart(grammer); 51 | char* startRule = new char[MAX_RULE_SIZE+1]; 52 | 53 | strncpy(startRule, newStart, MAX_VAR_SIZE); 54 | strncat(startRule, " ", 1); 55 | strncat(startRule, oldStart, MAX_VAR_SIZE); 56 | 57 | grammer[RULES].insert(startRule); 58 | 59 | grammer[VARIABLES].insert(newStart); 60 | 61 | grammer[START].clear(); 62 | grammer[START].insert(newStart); 63 | 64 | 65 | } 66 | // RETURNS A PTR TO THE NEW START 67 | char* generateNewStart( set*grammer){ 68 | char* newStart = new char[MAX_VAR_SIZE+1]; 69 | char* oldStart = *(grammer[START].begin()); 70 | int startLen = strlen(oldStart); 71 | 72 | strncpy( newStart, oldStart, startLen); 73 | *(newStart+startLen) = '\0'; 74 | // Need to check if at any point im trying to copy past MAX_VAR_SIZE 75 | while( member(grammer[VARIABLES], newStart) ){ 76 | strncat(newStart, "0\0", 2); 77 | } 78 | return newStart; 79 | } 80 | 81 | // Checks if given a rule if the start symbol exsit in it 82 | bool hasStart(char* rule, char* start){ 83 | 84 | int size; 85 | 86 | while(*rule){ 87 | if( (size = isVariable(rule))){ 88 | if( strncmp(start, rule, size) == 0){ 89 | return true; 90 | } 91 | rule += size; 92 | } 93 | else{ 94 | rule++; 95 | } 96 | } 97 | return false; 98 | } 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /Chapter4/alg4_1/gramIO.h: -------------------------------------------------------------------------------- 1 | ../library/gramIO.h -------------------------------------------------------------------------------- /Chapter4/alg4_1/gramLib.h: -------------------------------------------------------------------------------- 1 | ../library/gramLib.h -------------------------------------------------------------------------------- /Chapter4/alg4_1/grammer.txt: -------------------------------------------------------------------------------- 1 | S -> aS | AB | AC 2 | A -> aA | $ 3 | B -> bB | bS 4 | C -> cC | $ 5 | -------------------------------------------------------------------------------- /Chapter4/alg4_1/lib.h: -------------------------------------------------------------------------------- 1 | ../../Main/library/lib.h -------------------------------------------------------------------------------- /Chapter4/alg4_2/alg4_2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "gramLib.h" 4 | #include "gramIO.h" 5 | #include "lib.h" 6 | #include "../main/chap4.h" 7 | 8 | 9 | std::set initNullSet( std::set* grammer ); 10 | std::set buildNullSet( std::set* grammer); 11 | bool ruleInPrev( char* rule, std::set prevSet ); 12 | 13 | void removeNullRules( std::set nullSet, std::set* grammer); 14 | //int variablePos( char* rule ); 15 | int getNullAmount( char* rule, std::set nullSet); 16 | 17 | char* getPermutationList( int nullAmount, char* rule); 18 | 19 | void addNewRules(char* rule, std::set nullSet, std::set& rules); 20 | 21 | void removeOldNullRules(std::set& rules, char* start); 22 | //bool compareSets( std::set setA, std::set setB); 23 | 24 | 25 | using namespace std; 26 | /*int main(){ 27 | alg4_2("grammer.txt", "newGrammer.txt"); 28 | }*/ 29 | 30 | void alg4_2(char* pathIn, char* pathOut){ 31 | set grammer[4]; 32 | parseGrammer(pathIn, grammer); 33 | removeNullRules(buildNullSet(grammer), grammer); 34 | removeOldNullRules(grammer[RULES], *(grammer[START].begin())); 35 | outputGrammer(pathOut, grammer); 36 | } 37 | 38 | void removeNullRules( set nullSet, set* grammer){ 39 | 40 | set::iterator it; 41 | char* newRule; 42 | int nullAmount = 0; 43 | char* permList; 44 | char* rule; 45 | 46 | 47 | for( it = grammer[RULES].begin(); it != grammer[RULES].end(); it++){ 48 | addNewRules( *it, nullSet, grammer[RULES]); 49 | } 50 | 51 | // If the start symbol is part of the NULL SET 52 | // Then add the rule S -> NULL_CHAR 53 | if( member(nullSet, *(grammer[START].begin()))) { 54 | newRule = new char[MAX_RULE_SIZE+1]; 55 | strncpy(newRule, *(grammer[START].begin()), MAX_VAR_SIZE); 56 | strncat(newRule, " ", 1); 57 | strncat(newRule, NULL_CHAR, 1); 58 | if( !member( grammer[RULES], newRule)) { 59 | grammer[RULES].insert(newRule); 60 | } 61 | else{ 62 | delete newRule; 63 | } 64 | 65 | } 66 | 67 | } 68 | 69 | 70 | int getNullAmount( char* rule, set nullSet ){ 71 | 72 | char tmp[MAX_VAR_SIZE]; 73 | int length = 0; 74 | int nullAmount = 0; 75 | 76 | // goes until the end of the rule 77 | while( *rule ){ 78 | // if what rules ptr is at is a variable 79 | // then it will get its length then we make 80 | // a tmp var and check if its a member of the null set 81 | // if it is then add 1 to null amount and 82 | // plus the ptr by the size of the variable 83 | if( (length = isVariable( rule ))){ 84 | strncpy(tmp, rule, length); 85 | *(tmp+length) = '\0'; 86 | if( member( nullSet, tmp ) ){ 87 | nullAmount++; 88 | } 89 | rule+=length; 90 | } 91 | else{ 92 | rule++; 93 | } 94 | 95 | } 96 | return nullAmount; 97 | } 98 | 99 | 100 | //PRODUCES A NEW CHAR* MUST DELETE THE PTR IT RETURNS 101 | char* getPermutationList( int nullAmount, char* rule ){ 102 | 103 | int numNewRules = pow(2,nullAmount)-1; 104 | char* permList; 105 | 106 | if( numNewRules ){ 107 | 108 | // size of the perm list is 2^nullAmount * nullAmount + 1 109 | // 2^nullAmount is the number of newRules generated 110 | // *nullAmount takes in account each character produced 111 | // and +1 for the '\0' char 112 | permList = new char[numNewRules*nullAmount+1]; 113 | char* ptr = permList; 114 | int num; 115 | 116 | // Outter loop for is for producing the new rules 117 | // Turn each number from 0 to (2^nullAmount)-1 into binary 118 | // so you can use this to generate all possible permentions 119 | for(int i = 0; i < numNewRules; i++){ 120 | num = i; 121 | for( int j = 0; j < nullAmount; j++){ 122 | if( num%2 == 0){ 123 | *ptr = '1'; 124 | } 125 | else{ 126 | *ptr = '0'; 127 | } 128 | num/=2; 129 | ptr++; 130 | } 131 | } 132 | *ptr = '\0'; 133 | } 134 | else{ 135 | return NULL; 136 | } 137 | 138 | return permList; 139 | 140 | } 141 | 142 | void addNewRules(char* production, set nullSet, set& rules){ 143 | 144 | 145 | vector splitRule = splitProduction( production ); 146 | vector::iterator itRule; 147 | int nullAmount = getNullAmount( getRulePtr(production), nullSet); 148 | int numNewRules = pow(2,nullAmount)-1; 149 | int size = 0; 150 | char* permList = getPermutationList( nullAmount, getRulePtr(production)); 151 | char* newRule, *permListPtr = permList; 152 | char tmpRule[MAX_RULE_SIZE+1] = "\0"; 153 | 154 | 155 | for( int i = 0; i < numNewRules; i++){ 156 | itRule = splitRule.begin(); 157 | while( ++itRule != splitRule.end() ){ 158 | if( member( nullSet, *itRule) && *(permList++) == '0'){ 159 | strncat(tmpRule, *itRule, strlen(*itRule)); 160 | } 161 | else if( (size = isTerminal(*itRule)) ){ 162 | strncat(tmpRule, *itRule, size); 163 | } 164 | } 165 | 166 | 167 | 168 | // if there is something in tmpRule 169 | if( *tmpRule ){ 170 | newRule = new char[MAX_RULE_SIZE+1]; 171 | 172 | // Copys the current var a space and the new rule 173 | // EX: S bA 174 | strncpy(newRule, splitRule[0], strlen(splitRule[0])+1); 175 | strncat(newRule, " ", 1); 176 | strncat(newRule, tmpRule, MAX_RULE_SIZE); 177 | 178 | if( !(member(rules, newRule)) ){ 179 | rules.insert(newRule); 180 | } 181 | else{ 182 | delete(newRule); 183 | } 184 | 185 | *tmpRule = '\0'; 186 | } 187 | } 188 | 189 | delete permListPtr; 190 | } 191 | 192 | 193 | void removeOldNullRules(set& rules, char* start){ 194 | 195 | set::iterator it; 196 | char* rule; 197 | 198 | for( it = rules.begin(); it != rules.end(); it++){ 199 | if( !(varEqual(start, *it))){ 200 | rule = getRulePtr(*it); 201 | if( strcmp(rule, NULL_CHAR) == 0 ){ 202 | rules.erase(it); 203 | } 204 | } 205 | } 206 | } 207 | 208 | // ALGORITHM 4.2.1 (Page 108) 209 | /* 210 | 211 | input: context-free grammer G = (V, E, P, S) 212 | 213 | 1. NULL := { A | A -> Lamda (exist in) P } 214 | 2. repeat 215 | 2.1. PREV := NULL 216 | 2.2. for each variable A (exist in) V do 217 | if there is an A rule A -> w and w (exist in) PREV*, then 218 | NULL := NULL U {A} 219 | until NULL = PREV 220 | */ 221 | set buildNullSet(set* grammer){ 222 | 223 | set nullSet = initNullSet(grammer); 224 | set prevSet; 225 | 226 | set::iterator itVar; 227 | set::iterator itPro; 228 | 229 | //repeat 230 | do{ 231 | // PREV := NULL 232 | unionSet( prevSet, nullSet ); 233 | // for each A (exist in) V 234 | for( itVar = grammer[VARIABLES].begin(); itVar != grammer[VARIABLES].end(); itVar++){ 235 | // have to iterate through the rules to find ones such that A -> w and w exsit in PREV* 236 | for( itPro = grammer[RULES].begin(); itPro != grammer[RULES].end(); itPro++){ 237 | // A -> w 238 | if( varEqual( *itVar, *itPro) ){ 239 | // w (exist in) prevSet* 240 | if( ruleInPrev( getRulePtr(*itPro), prevSet) ){ 241 | // NULL := NULL U {A} 242 | nullSet.insert(*itVar); 243 | } 244 | } 245 | } 246 | } 247 | }while( !compareSets( nullSet, prevSet ) ); 248 | return nullSet; 249 | } 250 | 251 | bool ruleInPrev( char* rule, set prevSet ){ 252 | 253 | char tmpVar[MAX_VAR_SIZE+1]; 254 | char* currentPtr = rule; 255 | int varSize = 0; 256 | 257 | while( (varSize = isVariable(currentPtr)) ){ 258 | 259 | strncpy(tmpVar, currentPtr, (varSize)); 260 | *(tmpVar+varSize) = '\0'; 261 | 262 | if(member(prevSet, tmpVar) == 0 ){ 263 | return false; 264 | } 265 | 266 | currentPtr += varSize; 267 | } 268 | // checks if the pointer has moved at all if it hasent then this is not a variable 269 | // other wise it has gone through the while loop succefully 270 | if( currentPtr == rule ){ 271 | return false; 272 | } 273 | return true; 274 | 275 | 276 | } 277 | 278 | // { A | A -> NULL_CHAR (exist in) P } 279 | set initNullSet( set* grammer){ 280 | 281 | set::iterator it; 282 | set nullSet; 283 | 284 | char* newNullVar; 285 | 286 | for( it = grammer[RULES].begin(); it != grammer[RULES].end(); it++){ 287 | if( strcmp( getRulePtr( *it ), NULL_CHAR) == 0 ){ 288 | newNullVar = new char[MAX_VAR_SIZE]; 289 | // Gets the lengtt of the var so when you use 290 | // strncpy it will only copy the variable 291 | strncpy(newNullVar, *it, variableLen(*it)); 292 | *(newNullVar + variableLen(*it)) = '\0'; 293 | 294 | if( !(member(nullSet, newNullVar)), newNullVar){ 295 | nullSet.insert(newNullVar); 296 | } 297 | else{ 298 | delete(newNullVar); 299 | } 300 | 301 | } 302 | } 303 | 304 | return nullSet; 305 | } 306 | 307 | -------------------------------------------------------------------------------- /Chapter4/alg4_2/gramIO.h: -------------------------------------------------------------------------------- 1 | ../library/gramIO.h -------------------------------------------------------------------------------- /Chapter4/alg4_2/gramLib.h: -------------------------------------------------------------------------------- 1 | ../library/gramLib.h -------------------------------------------------------------------------------- /Chapter4/alg4_2/grammer.txt: -------------------------------------------------------------------------------- 1 | S -> ACA 2 | A -> aAa | B | C 3 | B -> bB | b 4 | C -> cC | $ 5 | -------------------------------------------------------------------------------- /Chapter4/alg4_2/lib.h: -------------------------------------------------------------------------------- 1 | ../../Main/library/lib.h -------------------------------------------------------------------------------- /Chapter4/alg4_2/makefile: -------------------------------------------------------------------------------- 1 | OBJS = alg4_2.o lib.o grammerIO.o 2 | MAIN = alg4_2 3 | 4 | all: remove compile 5 | 6 | new: compile 7 | 8 | compile: $(OBJS) 9 | g++ $(OBJS) -o test 10 | 11 | $(MAIN).o: 12 | g++ -c $(MAIN).cpp 13 | 14 | lib.o: 15 | g++ -c /home/schbra02/web/library/lib.cpp 16 | 17 | grammerIO.o: 18 | g++ -c /home/schbra02/web/library/grammerIO.cpp 19 | 20 | remove: 21 | rm $(MAIN).o 22 | 23 | clean: 24 | rm -rf *o compile 25 | -------------------------------------------------------------------------------- /Chapter4/alg4_2/newGrammer.txt: -------------------------------------------------------------------------------- 1 | S -> ACA | A | C | AC | AA | CA | $ 2 | A -> aAa | B | C | aa 3 | B -> bB | b 4 | C -> cC | c 5 | -------------------------------------------------------------------------------- /Chapter4/alg4_3/alg4_3.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "gramLib.h" 5 | #include "gramIO.h" 6 | #include "lib.h" 7 | #include "../main/chap4.h" 8 | 9 | 10 | int chainRule(std::set var, char* currVar, char* production); 11 | std::set deriveChainRule(char* variable, std::set* grammer); 12 | void updateGrammer( std::set chainRules, std::set* grammer, char* curVar); 13 | void addNewRule( std::set& rules, char* rule, char* curVar); 14 | void removeOldChain( std::set* grammer ); 15 | 16 | using namespace std; 17 | /*int main(){ 18 | 19 | }*/ 20 | 21 | void alg4_3(char* pathIn, char* pathOut){ 22 | 23 | set grammer[4]; 24 | set chainX; 25 | 26 | 27 | parseGrammer(pathIn, grammer); 28 | 29 | set::iterator it; 30 | 31 | // Goes through all the variables and gets the chain rules for them 32 | // then it updates its production rules with new ones 33 | // NOTE: 34 | // generating rules compared to adding them do not effect each other 35 | // since getting chain rules is dependent on other chain rules, since 36 | // we dont add any new ones they dont effect each other. 37 | for( it = grammer[VARIABLES].begin(); it != grammer[VARIABLES].end(); it++){ 38 | chainX = deriveChainRule(*it, grammer); 39 | updateGrammer( chainX , grammer, *it ); 40 | } 41 | // Remove all the chain rules after producting all new rules 42 | removeOldChain(grammer); 43 | 44 | outputGrammer(pathOut, grammer); 45 | 46 | } 47 | 48 | // 4.3.1 49 | /* 50 | 51 | input: context-free grammer G = (V, E, P, S) 52 | 53 | 1. CHAIN(A) := {A} 54 | 2. PREV := CHAIN(A) 55 | 3. repeat 56 | 3.1. NEW := CHAIN(A) - PREV 57 | 3.2. PREV := CHAIN(A) 58 | 3.3. for each variable B (exist in) NEW do 59 | for each rule B -> C do 60 | CHAIN(A) := CHAIN(A) U {C} 61 | until CHAIN(A) = PREV 62 | */ 63 | set deriveChainRule(char* variable, set* grammer){ 64 | set chainX; 65 | set prevSet; 66 | set newSet; 67 | 68 | set::iterator itPro; 69 | set::iterator itNew; 70 | 71 | chainX.insert(variable); 72 | 73 | do{ 74 | unionSet(newSet, chainX); 75 | diffSet(newSet, prevSet); 76 | 77 | unionSet(prevSet, chainX); 78 | for( itNew = newSet.begin(); itNew != newSet.end(); itNew++){ 79 | for( itPro = grammer[RULES].begin(); itPro != grammer[RULES].end(); itPro++){ 80 | if( chainRule(grammer[VARIABLES], *itNew, *itPro) ){ 81 | insertVariable(chainX, getRulePtr(*itPro)); 82 | } 83 | } 84 | 85 | } 86 | 87 | }while( !(compareSets( chainX, prevSet)) ); 88 | 89 | 90 | return chainX; 91 | } 92 | 93 | 94 | void updateGrammer( set chainX, set* grammer, char* curVar){ 95 | set::iterator itChainX; 96 | set::iterator itRules; 97 | 98 | // The for loop is i) on page 115 ( B exist in CHAIN(A) ) 99 | for( itChainX = chainX.begin(); itChainX != chainX.end(); itChainX++){ 100 | // This for loop is for ii) ( B -> ( w exist in P ) ) 101 | for( itRules = grammer[RULES].begin(); itRules != grammer[RULES].end(); itRules++){ 102 | if( varEqual( *itChainX, *itRules ) ){ 103 | if( member( grammer[VARIABLES], getRulePtr(*itRules)) == 0){ 104 | addNewRule(grammer[RULES], *itRules, curVar); 105 | } 106 | } 107 | 108 | } 109 | } 110 | 111 | } 112 | 113 | void addNewRule(set& rules, char* rule, char* curVar){ 114 | char* newRule = new char[MAX_RULE_SIZE+1]; 115 | 116 | strncpy(newRule, curVar, MAX_VAR_SIZE); 117 | strncat(newRule, (getRulePtr(rule)-1), MAX_RULE_SIZE); 118 | 119 | // AGAIN INSERT IS NOT REMOVING DUBLICATES 120 | if( member( rules, newRule ) == 0 ){ 121 | rules.insert(newRule); 122 | } 123 | else{// if(!newRule){ 124 | delete newRule; 125 | } 126 | } 127 | 128 | // This just goes through and removes the first chain rules in the gammer // 129 | void removeOldChain( set* grammer){ 130 | 131 | set::iterator itRules; 132 | set::iterator itTmp; 133 | 134 | itRules = grammer[RULES].begin(); 135 | 136 | while(itRules != grammer[RULES].end()){ 137 | if( member( grammer[VARIABLES], getRulePtr(*itRules)) ){ 138 | itTmp = itRules; 139 | ++itRules; 140 | grammer[RULES].erase(*itTmp); 141 | } 142 | else{ 143 | ++itRules; 144 | } 145 | 146 | 147 | } 148 | } 149 | 150 | // For each production that is of the currt var 151 | int chainRule(set variable, char* currVar, char* production){ 152 | // if production rule has currVar 153 | // and productions rule is a chain rule return 1 154 | 155 | if( varEqual(currVar, production) ){ 156 | if( member(variable, getRulePtr(production)) == 1){ 157 | return 1; 158 | } 159 | } 160 | return 0; 161 | } 162 | 163 | 164 | -------------------------------------------------------------------------------- /Chapter4/alg4_3/gramIO.h: -------------------------------------------------------------------------------- 1 | ../library/gramIO.h -------------------------------------------------------------------------------- /Chapter4/alg4_3/gramLib.h: -------------------------------------------------------------------------------- 1 | ../library/gramLib.h -------------------------------------------------------------------------------- /Chapter4/alg4_3/grammer.txt: -------------------------------------------------------------------------------- 1 | S -> ACA | CA | AA | AC | A | C 2 | A -> aAa | aa | B | C 3 | B -> bB | b 4 | C -> cC | c 5 | -------------------------------------------------------------------------------- /Chapter4/alg4_3/lib.h: -------------------------------------------------------------------------------- 1 | ../../Main/library/lib.h -------------------------------------------------------------------------------- /Chapter4/alg4_3/makefile: -------------------------------------------------------------------------------- 1 | OBJS = alg4_3_New.o lib.o grammerIO.o 2 | MAIN = alg4_3_New 3 | 4 | all: remove compile 5 | 6 | new: compile 7 | 8 | compile: $(OBJS) 9 | g++ $(OBJS) -o test 10 | 11 | $(MAIN).o: 12 | g++ -c $(MAIN).cpp 13 | 14 | lib.o: 15 | g++ -c /home/schbra02/web/library/lib.cpp 16 | 17 | grammerIO.o: 18 | g++ -c /home/schbra02/web/library/grammerIO.cpp 19 | 20 | remove: 21 | rm $(MAIN).o 22 | 23 | clean: 24 | rm -rf *o compile 25 | -------------------------------------------------------------------------------- /Chapter4/alg4_3/newGrammer.txt: -------------------------------------------------------------------------------- 1 | S -> ACA | CA | AA | AC | C | cC | c | aAa | aa | bB | b 2 | A -> aAa | aa | C | bB | b | cC | c 3 | B -> bB | b 4 | C -> cC | c 5 | -------------------------------------------------------------------------------- /Chapter4/alg4_4/4_4_2/alg4_4_2.cpp: -------------------------------------------------------------------------------- 1 | #include "gramLib.h" 2 | #include "gramIO.h" 3 | #include "lib.h" 4 | #include "../../main/chap4.h" 5 | 6 | void removeUselessVar( std::set usefulVar, std::set* grammer); 7 | std::set setDeriveTermString(std::set* grammer); 8 | std::set initTermSet(std::set rules); 9 | bool inPrevAlphabet( char* rule, std::set prevSet, std::set alphabet); 10 | 11 | void removeUnReachable( std::set termSet, std::set* grammer); 12 | std::set getReachable( std::set* grammer ); 13 | 14 | using namespace std; 15 | /*int main(){ 16 | }*/ 17 | 18 | 19 | void alg4_4_2(char* pathIn, char* pathOut){ 20 | set grammer[4]; 21 | parseGrammer(pathIn, grammer); 22 | 23 | removeUselessVar( setDeriveTermString(grammer), grammer ); 24 | 25 | outputGrammer(pathOut, grammer); 26 | } 27 | 28 | 29 | void removeUselessVar( set termSet, set* grammer){ 30 | 31 | set::iterator itPro; 32 | set::iterator itRemove; 33 | 34 | itPro = grammer[RULES].begin(); 35 | 36 | // A -> w | A -> w is a rule in P, A (exist in) TERM, and w (exist in) (TERM U ALPHABET)* 37 | while( itPro != grammer[RULES].end() ){ 38 | if( !(inPrevAlphabet( getRulePtr(*itPro), termSet, grammer[ALPHABET])) ){ 39 | itRemove = itPro; 40 | ++itPro; 41 | grammer[RULES].erase(itRemove); 42 | } 43 | else{ 44 | ++itPro; 45 | } 46 | } 47 | 48 | interSet(grammer[VARIABLES], termSet); 49 | 50 | } 51 | 52 | /* Algorithm 4.4.2 (Page 117) 53 | 54 | input: context-free grammer G = (V, E, P, S) 55 | 56 | 1. TERM := {A | there is a rule A -> w (exist in) P with w (exist in) E*} 57 | 2. repeat 58 | 2.1. PREV := TERM 59 | 2.2. for each variable A (exist in) V do 60 | if there is an A rule A -> w and w (exist in) (PREV U E)* then 61 | TERM := TERM U {A} 62 | until PREV = TERM 63 | 64 | */ 65 | 66 | set setDeriveTermString(set* grammer){ 67 | 68 | // TERM := {A | there is a rule A -> w (exist in) P with w (exist in) ALPHABET*} 69 | set termSet = initTermSet(grammer[RULES]); 70 | set prevSet; 71 | set::iterator itRule; 72 | 73 | // repeat 74 | do{ 75 | // PREV := TERM 76 | unionSet(prevSet, termSet); 77 | // for each variable A (exist in) V 78 | for( itRule = grammer[RULES].begin(); itRule != grammer[RULES].end(); itRule++){ 79 | // if there is A rule A -> w and w (exist in) (PREV U ALPHABET)* 80 | if(inPrevAlphabet( getRulePtr(*itRule), prevSet, grammer[ALPHABET])){ 81 | // TERM := TERM U {A} 82 | insertVariable(termSet, *itRule); 83 | } 84 | } 85 | // until PREV = TERM 86 | }while( !(compareSets(prevSet, termSet)) ); 87 | 88 | return termSet; 89 | } 90 | 91 | 92 | 93 | bool inPrevAlphabet(char* rule, set prevSet, set alphabet){ 94 | 95 | set tmpSet; 96 | unionSet(tmpSet, prevSet); 97 | unionSet(tmpSet, alphabet); 98 | 99 | char tmpString[MAX_VAR_SIZE+1]; 100 | 101 | int size; 102 | 103 | // while the rule hasent reached the end '\0' 104 | while(*rule){ 105 | 106 | // Relies on short-circuit evalutation, 107 | // IF the rule is currently a Terminal it will be true and stop 108 | // the evaulation of second part so size wont get a 0 109 | // ELSE it is a variable and it will get a value on the second part 110 | if( (size = isTerminal(rule)) || (size = isVariable(rule)) ){ 111 | strncpy(tmpString, rule, size); 112 | *(tmpString+size) = '\0'; 113 | // if its not a member of the tmp set then fail 114 | // tmpSet = (prevSet U alphabet) 115 | if( !(member(tmpSet, tmpString))){ 116 | return false; 117 | } 118 | // move the pointer down size times 119 | rule += size; 120 | } 121 | else{ 122 | rule++; 123 | } 124 | } 125 | // checks if we went through the entire rule 126 | if(!(*rule)){ 127 | return true; 128 | } 129 | return false; 130 | 131 | 132 | 133 | } 134 | 135 | // TERM = [A | A -> w where w is some combonation of the alphabet] 136 | set initTermSet(set rules){ 137 | 138 | set termSet; 139 | set::iterator it; 140 | char* rulePtr; 141 | char* newVar; 142 | int termSize; 143 | 144 | for( it = rules.begin(); it != rules.end(); it++){ 145 | rulePtr = getRulePtr(*it); 146 | // Keeps going through the rule until it hits 147 | // '\0' or variable which will make isTerminal 148 | // return a 0 149 | while( (termSize = isTerminal( rulePtr )) ){ 150 | rulePtr += termSize; 151 | } 152 | // checks if rulePtr has reached the end '\0' 153 | // if it has then the entire rule is a terminal 154 | if( !(*rulePtr) ){ 155 | newVar = new char[MAX_VAR_SIZE]; 156 | strncpy(newVar, *it, isVariable(*it)); 157 | termSet.insert(newVar); 158 | } 159 | 160 | } 161 | 162 | 163 | return termSet; 164 | } 165 | 166 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /Chapter4/alg4_4/4_4_2/gramIO.h: -------------------------------------------------------------------------------- 1 | ../../library/gramIO.h -------------------------------------------------------------------------------- /Chapter4/alg4_4/4_4_2/gramLib.h: -------------------------------------------------------------------------------- 1 | ../../library/gramLib.h -------------------------------------------------------------------------------- /Chapter4/alg4_4/4_4_2/grammer.txt: -------------------------------------------------------------------------------- 1 | S -> AC | BS | B 2 | A -> aA | aF 3 | B -> CF | b 4 | C -> cC | D 5 | D -> aD | BD | C 6 | E -> aA | BSA 7 | F -> bB | b 8 | -------------------------------------------------------------------------------- /Chapter4/alg4_4/4_4_2/lib.h: -------------------------------------------------------------------------------- 1 | ../../../Main/library/lib.h -------------------------------------------------------------------------------- /Chapter4/alg4_4/4_4_2/makefile: -------------------------------------------------------------------------------- 1 | OBJS = alg4_4_2.o lib.o grammerIO.o 2 | MAIN = alg4_4_2 3 | 4 | all: remove compile 5 | 6 | new: compile 7 | 8 | compile: $(OBJS) 9 | g++ $(OBJS) -o test 10 | 11 | $(MAIN).o: 12 | g++ -c $(MAIN).cpp 13 | 14 | lib.o: 15 | g++ -c /home/schbra02/web/library/lib.cpp 16 | 17 | grammerIO.o: 18 | g++ -c /home/schbra02/web/library/grammerIO.cpp 19 | 20 | remove: 21 | rm $(MAIN).o 22 | 23 | clean: 24 | rm -rf *o compile 25 | -------------------------------------------------------------------------------- /Chapter4/alg4_4/4_4_2/newGrammer.txt: -------------------------------------------------------------------------------- 1 | S -> BS | B 2 | B -> b 3 | A -> aA | aF 4 | E -> aA | BSA 5 | F -> bB | b 6 | -------------------------------------------------------------------------------- /Chapter4/alg4_4/4_4_4/alg4_4_4.cpp: -------------------------------------------------------------------------------- 1 | #include "gramLib.h" 2 | #include "gramIO.h" 3 | #include "lib.h" 4 | 5 | void alg4_4_4(char* pathIn, char* pathOut); 6 | 7 | std::set getReachable( std::set* grammer ); 8 | void addToReach( char* rule, std::set& reachSet); 9 | 10 | using namespace std; 11 | /*int main(){ 12 | alg4_4_4("grammer.txt", "newGrammer.txt"); 13 | }*/ 14 | 15 | void alg4_4_4(char* pathIn, char* pathOut){ 16 | 17 | set grammer[4]; 18 | parseGrammer(pathIn, grammer); 19 | 20 | interSet(grammer[VARIABLES], getReachable(grammer)); 21 | 22 | outputGrammer(pathOut, grammer); 23 | } 24 | 25 | /* Algorithm 4.4.4 - Page 119 26 | 27 | input: context-free grammer G = (V, E, P, S) 28 | 29 | 1. REACH := {S} 30 | 2. PREV := {} 31 | 3. repeat 32 | 3.1. NEW := REACH - PREV 33 | 3.2. PREV := REACH 34 | 3.3 for each variable A (exist in) NEW do 35 | for each rule A -> w do add all variables in w to REACH 36 | unil REACH = PREV 37 | */ 38 | 39 | 40 | set getReachable( set* grammer){ 41 | 42 | 43 | set reachSet; 44 | set newSet; 45 | set prevSet; 46 | 47 | set::iterator itVar; 48 | set::iterator itPro; 49 | 50 | reachSet.insert(*(grammer[START].begin())); 51 | 52 | do{ 53 | unionSet(newSet, reachSet); 54 | diffSet(newSet, prevSet); 55 | 56 | unionSet(prevSet, reachSet); 57 | 58 | 59 | for( itVar = newSet.begin(); itVar != newSet.end(); itVar++){ 60 | for( itPro = grammer[RULES].begin(); itPro != grammer[RULES].end(); itPro++){ 61 | if( varEqual(*itVar, *itPro) ){ 62 | addToReach( getRulePtr(*itPro), reachSet); 63 | } 64 | } 65 | } 66 | 67 | 68 | }while( !(compareSets(reachSet, prevSet))); 69 | 70 | return reachSet; 71 | 72 | } 73 | 74 | 75 | void addToReach( char* rule, set& reachSet){ 76 | 77 | int size; 78 | 79 | while(*rule){ 80 | if( (size = isVariable(rule)) ){ 81 | insertVariable(reachSet, rule); 82 | rule += size; 83 | } 84 | else{ 85 | rule++; 86 | } 87 | } 88 | 89 | } 90 | 91 | -------------------------------------------------------------------------------- /Chapter4/alg4_4/4_4_4/gramIO.h: -------------------------------------------------------------------------------- 1 | ../../library/gramIO.h -------------------------------------------------------------------------------- /Chapter4/alg4_4/4_4_4/gramLib.h: -------------------------------------------------------------------------------- 1 | ../../library/gramLib.h -------------------------------------------------------------------------------- /Chapter4/alg4_4/4_4_4/grammer.txt: -------------------------------------------------------------------------------- 1 | ../4_4_2/newGrammer.txt -------------------------------------------------------------------------------- /Chapter4/alg4_4/4_4_4/lib.h: -------------------------------------------------------------------------------- 1 | ../../../Main/library/lib.h -------------------------------------------------------------------------------- /Chapter4/alg4_4/4_4_4/makefile: -------------------------------------------------------------------------------- 1 | OBJS = alg4_4_4.o lib.o grammerIO.o 2 | MAIN = alg4_4_4 3 | 4 | all: remove compile 5 | 6 | new: compile 7 | 8 | compile: $(OBJS) 9 | g++ $(OBJS) -o test 10 | 11 | $(MAIN).o: 12 | g++ -c $(MAIN).cpp 13 | 14 | lib.o: 15 | g++ -c /home/schbra02/web/library/lib.cpp 16 | 17 | grammerIO.o: 18 | g++ -c /home/schbra02/web/library/grammerIO.cpp 19 | 20 | remove: 21 | rm $(MAIN).o 22 | 23 | clean: 24 | rm -rf *o compile 25 | -------------------------------------------------------------------------------- /Chapter4/alg4_4/4_4_4/newGrammer.txt: -------------------------------------------------------------------------------- 1 | S -> BS | B 2 | B -> b 3 | -------------------------------------------------------------------------------- /Chapter4/alg4_5/alg4_5.cpp: -------------------------------------------------------------------------------- 1 | #include "gramIO.h" 2 | #include "gramLib.h" 3 | #include "lib.h" 4 | #include "../main/chap4.h" 5 | 6 | void convertToChomsky( std::set* grammer, std::set* newGrammer); 7 | 8 | void removeTerminals( std::set* grammer, std::set* newGrammer); 9 | 10 | void addNewRule( char* var, char* rule, std::set& rules); 11 | 12 | void splitNewRules(std::set* newGrammer); 13 | void produceNewRules(std::vector splitRule, std::set& rules, std::set& var); 14 | 15 | 16 | bool singleRule(std::set rules, char* production); 17 | char* generateNewVar( char* terminal, std::set variables, std::set rules); 18 | char* newTVar(std::set variables); 19 | 20 | using namespace std; 21 | /*int main(){ 22 | 23 | set grammer[4]; 24 | parseGrammer("grammer.txt", grammer); 25 | if( singleRule(grammer[RULES], "A a")){ 26 | cout << "?" << endl; 27 | } 28 | else{ 29 | cout << "nope" << endl; 30 | } 31 | 32 | alg4_5("grammer.txt", "newGrammer.txt"); 33 | 34 | }*/ 35 | 36 | 37 | void alg4_5(char* pathIn, char* pathOut){ 38 | 39 | set newGrammer[4]; 40 | set grammer[4]; 41 | parseGrammer(pathIn, grammer); 42 | 43 | convertToChomsky(grammer, newGrammer); 44 | 45 | outputGrammer(pathOut, newGrammer); 46 | } 47 | 48 | /* 49 | 50 | G = (V, ALPHABET, P, S) 51 | G' = (V', ALPHABET, P', S') 52 | Chomsky Normal Form Rules: 53 | 54 | i) A -> BC 55 | ii) A -> a, or 56 | iii) S -> Lambda 57 | 58 | where B, C (exist in) V - {S} 59 | 60 | 61 | 62 | CASE: 63 | 64 | S -> Lambda 65 | -- If this rule exist add to P' 66 | 67 | A -> a (singal terminal) 68 | -- If this rule exist add to P' 69 | 70 | A -> w 71 | where w (exist in) (( V U ALPHABET) - {S} )* and length(w) > 1 72 | -- If this then w must contain variables and terminals 73 | -- To fix this we much replace all terminals with variables 74 | -- and add new variables that are eqivalent to each terminal 75 | */ 76 | 77 | void convertToChomsky( set* grammer, set* newGrammer){ 78 | 79 | 80 | // Both of these are unchanged in producing CNF 81 | unionSet(newGrammer[ALPHABET], grammer[ALPHABET]); 82 | unionSet(newGrammer[START], grammer[START]); 83 | unionSet(newGrammer[VARIABLES], grammer[VARIABLES]); 84 | 85 | 86 | // Add any rule such that S -> Lambda or A -> w where w is a singal terminal symbol 87 | 88 | removeTerminals( grammer, newGrammer); 89 | splitNewRules(newGrammer); 90 | 91 | } 92 | 93 | 94 | void removeTerminals(set* grammer, set* newGrammer){ 95 | 96 | char* newVar; 97 | char* newRule; 98 | char tmpRule[MAX_RULE_SIZE+1] = "\0"; 99 | vector proVec; 100 | 101 | set::iterator itPro; 102 | 103 | 104 | 105 | for( itPro = grammer[RULES].begin(); itPro != grammer[RULES].end(); itPro++){ 106 | proVec = splitProduction(*itPro); 107 | for( int i = 1; i < proVec.size(); i++){ 108 | 109 | // If its a terminal and there are more then just a single terminal 110 | // FAILS IF A -> a 111 | if( isTerminal(proVec[i]) && proVec.size() > 2){ 112 | newVar = generateNewVar(proVec[i], newGrammer[VARIABLES], newGrammer[RULES]); 113 | addNewRule(newVar, proVec[i], newGrammer[RULES]); 114 | strncat(tmpRule, newVar, MAX_VAR_SIZE); 115 | insertIntoSet(newGrammer[VARIABLES], newVar); 116 | } 117 | // Else its a variable thats not in the null set or a terminal 118 | else{ 119 | strncat(tmpRule, proVec[i], MAX_RULE_SIZE); 120 | } 121 | } 122 | // New rule 123 | newRule = new char[MAX_RULE_SIZE+1]; 124 | strncpy(newRule, proVec[0], strlen(proVec[0])+1); 125 | strncat(newRule, " ", 1); 126 | strncat(newRule, tmpRule, MAX_RULE_SIZE); 127 | insertIntoSet(newGrammer[RULES], newRule); 128 | *tmpRule = '\0'; 129 | } 130 | } 131 | 132 | 133 | void splitNewRules(set* newGrammer){ 134 | 135 | vector splitRule; 136 | set tmpRules; 137 | set::iterator itRule; 138 | set::iterator itTmp; 139 | char* newVar; 140 | char* newRule; 141 | 142 | unionSet(tmpRules, newGrammer[RULES]); 143 | 144 | for( itRule = newGrammer[RULES].begin(); itRule != newGrammer[RULES].end(); itRule++){ 145 | splitRule = splitProduction(*itRule); 146 | if( splitRule.size() > 3 ){ 147 | produceNewRules(splitRule, tmpRules, newGrammer[VARIABLES]); 148 | tmpRules.erase(*itRule); 149 | } 150 | 151 | 152 | } 153 | 154 | // Keep everything they have in common 155 | interSet(newGrammer[RULES], tmpRules); 156 | // Only keep the difference of tmpRules to newGrammer 157 | diffSet(tmpRules, newGrammer[RULES]); 158 | // Unions the intersection (tmpRules and newGrammer) have in common with the difference of (tmpRules and newGrammer) 159 | unionSet(newGrammer[RULES], tmpRules); 160 | } 161 | 162 | void produceNewRules(vector splitRule, set& rules, set& variables){ 163 | 164 | char* newVar; 165 | char* newRule; 166 | char* changedRule; 167 | int size = 0; 168 | 169 | 170 | while( (size = splitRule.size()) > 3 ){ 171 | if( (newVar = newTVar(variables)) ){ 172 | newRule = new char[MAX_RULE_SIZE+1]; 173 | strncpy(newRule, newVar, strlen(newVar)+1); 174 | strncat(newRule, " ", 1); 175 | strncat(newRule, splitRule[size-2], MAX_RULE_SIZE); 176 | strncat(newRule, splitRule[size-1], MAX_RULE_SIZE); 177 | 178 | // Pops last 2 off 179 | splitRule.pop_back(); 180 | splitRule.pop_back(); 181 | splitRule.push_back(newVar); 182 | 183 | rules.insert(newRule); 184 | variables.insert(newVar); 185 | } 186 | else{ 187 | cout << "To many new T varaibles...." << endl; 188 | return; 189 | } 190 | 191 | } 192 | 193 | changedRule = flattenProductVector(splitRule); 194 | rules.insert(changedRule); 195 | } 196 | 197 | char* newTVar(set variables){ 198 | 199 | char* newVar = new char[MAX_VAR_SIZE+1]; 200 | char* ptr = (newVar+1); 201 | int size = 2; 202 | strncpy(newVar, "T0", 2); 203 | *(newVar+2) = '\0'; 204 | 205 | // Keeps going until it makes a var 206 | // Will stop before it makes a var to large to fit in the array 207 | // But will create an infinate loop, add still add one to the array 208 | while( member(variables, newVar) ){ 209 | if( *ptr == '9'){ 210 | strncat(newVar, "0", 1); 211 | ptr++; 212 | size++; 213 | *(ptr+1) = '\0'; 214 | } 215 | else{ 216 | *ptr += 1; 217 | } 218 | if( size > MAX_VAR_SIZE){ 219 | return NULL; 220 | } 221 | } 222 | 223 | return newVar; 224 | } 225 | 226 | void addNewRule(char* var, char* rule, set& rules){ 227 | char* newRule = new char[MAX_RULE_SIZE+1]; 228 | strncpy(newRule, var, strlen(var)+1); 229 | strncat(newRule, " ", 1); 230 | strncat(newRule, rule, strlen(rule)); 231 | insertIntoSet( rules, newRule); 232 | } 233 | 234 | // RETURNS A PTR TO THE NEW VAR 235 | char* generateNewVar(char* terminal, set variables, set rules){ 236 | 237 | // check if there is a rule that goes to the terminal already 238 | set::iterator itPro; 239 | vector splitRule; 240 | char* newVar = new char[MAX_VAR_SIZE+1]; 241 | char* rulePtr; 242 | int varSize = 0; 243 | 244 | // checks if there exsit a rule that goes to a terminal already 245 | for( itPro = rules.begin(); itPro != rules.end(); itPro++){ 246 | rulePtr = getRulePtr(*itPro); 247 | if( strcmp(rulePtr, terminal) == 0 && singleRule(rules, *itPro)){ 248 | varSize = isVariable(*itPro); 249 | strncpy(newVar, *itPro, varSize); 250 | *(newVar+varSize) = '\0'; 251 | return newVar; 252 | } 253 | 254 | } 255 | 256 | // ELSE generate a new one 257 | *(newVar) = (char)toupper(*terminal); 258 | *(newVar+1) = '\0'; 259 | strncat( newVar, (terminal+1), MAX_VAR_SIZE); 260 | 261 | // Need to check if at any point im trying to copy past MAX_VAR_SIZE 262 | do{ 263 | strncat(newVar, "0", 1); 264 | }while( member(variables, newVar) ); 265 | 266 | return newVar; 267 | } 268 | 269 | 270 | // Make sures that the rule can only go the terminal 271 | bool singleRule(set rules, char* production){ 272 | 273 | set::iterator itRule; 274 | int varSize = isVariable(production); 275 | int lessOne = 0; 276 | char tmpVar[MAX_VAR_SIZE+1]; 277 | strncpy(tmpVar, production, varSize); 278 | *(tmpVar+varSize) = '\0'; 279 | 280 | 281 | for( itRule = rules.begin(); itRule != rules.end(); itRule++){ 282 | if( lessOne > 1 ){ 283 | return false; 284 | } 285 | else if( varEqual(tmpVar, *itRule)){ 286 | lessOne++; 287 | } 288 | } 289 | 290 | return true; 291 | } 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | -------------------------------------------------------------------------------- /Chapter4/alg4_5/gramIO.h: -------------------------------------------------------------------------------- 1 | ../library/gramIO.h -------------------------------------------------------------------------------- /Chapter4/alg4_5/gramLib.h: -------------------------------------------------------------------------------- 1 | ../library/gramLib.h -------------------------------------------------------------------------------- /Chapter4/alg4_5/grammer.txt: -------------------------------------------------------------------------------- 1 | S -> aABC | a 2 | A -> aA | a 3 | B -> bcB | bc 4 | C -> cC | c 5 | -------------------------------------------------------------------------------- /Chapter4/alg4_5/lib.h: -------------------------------------------------------------------------------- 1 | ../../Main/library/lib.h -------------------------------------------------------------------------------- /Chapter4/alg4_5/makefile: -------------------------------------------------------------------------------- 1 | OBJS = alg4_5.o lib.o grammerIO.o 2 | MAIN = alg4_5 3 | 4 | all: remove compile 5 | 6 | new: compile 7 | 8 | compile: $(OBJS) 9 | g++ $(OBJS) -o test 10 | 11 | $(MAIN).o: 12 | g++ -c $(MAIN).cpp 13 | 14 | lib.o: 15 | g++ -c /home/schbra02/web/library/lib.cpp 16 | 17 | grammerIO.o: 18 | g++ -c /home/schbra02/web/library/grammerIO.cpp 19 | 20 | remove: 21 | rm $(MAIN).o 22 | 23 | clean: 24 | rm -rf *o compile 25 | -------------------------------------------------------------------------------- /Chapter4/alg4_5/newGrammer.txt: -------------------------------------------------------------------------------- 1 | S -> a | A0T1 2 | C -> C0C | c 3 | A0 -> a 4 | B -> B0C0 | B0T2 5 | C0 -> c 6 | A -> A0A | a 7 | T0 -> BC 8 | B0 -> b 9 | T1 -> AT0 10 | T2 -> C0B 11 | -------------------------------------------------------------------------------- /Chapter4/alg4_6/alg4_6.cpp: -------------------------------------------------------------------------------- 1 | #include "gramLib.h" 2 | #include "gramIO.h" 3 | #include "lib.h" 4 | #include "latex.h" 5 | 6 | #define MAX_NUM_VAR 8 7 | 8 | void CYKalg(std::set* grammer, char* input, char* pathOut); 9 | void addDerivableVars( std::set B, std::set C, std::set& addTo, std::set rules); 10 | setMatrix init2DMatrix(int n); 11 | 12 | void outputMatrix(setMatrix X, char* pathOut, int size); 13 | int maxSetSize(setMatrix X, int n); 14 | void printDiagMatrix( setMatrix, int n); 15 | 16 | 17 | 18 | using namespace std; 19 | void alg4_6(char* pathIn, char* pathOut, char* input){ 20 | set grammer[4]; 21 | parseGrammer(pathIn, grammer); 22 | 23 | CYKalg(grammer, input, pathOut); 24 | } 25 | 26 | /* 27 | Algorithm 4.6.1 - Page 126-127 28 | 29 | input: context-free grammer G = (V, E, P, S) 30 | string u = x1,x2,...xn (exist in) E* 31 | 32 | 1. initialize all Xi,j to {} 33 | 2. for i = 1 to n 34 | for each variable A, if there is a rule A -> xi then Xi,i := Xi,i U {A} 35 | 3. for step = 2 to n 36 | 3.1. for i = 1 to n - step + 1 37 | 3.1.1 for k = i to i + step - 2 38 | if there are variables B (exist in) Xi,k , C (exist in) Xk+1, i+step-1, and 39 | a rule A -> BC, then Xi,i+step-1 := Xi,i+step-1 U{A} 40 | 4. u (exist in) L(G) if S (exist in) X 1,n 41 | 42 | */ 43 | 44 | void CYKalg(set* grammer, char* input, char* pathOut){ 45 | 46 | vector splitInput = splitProduction(input);// splitProduction(input); 47 | set::iterator itPro; 48 | char* var; 49 | int n = splitInput.size(); 50 | 51 | // 1. initialize all Xi,j to {} 52 | setMatrix X = init2DMatrix(n); 53 | 54 | // 2. for i = 1 to n 55 | // for each variable A, if there is a rule A -> xi then Xi,i := Xi,i U {A} 56 | for(int i = 1; i <= n; i++){ 57 | for( itPro = grammer[RULES].begin(); itPro != grammer[RULES].end(); itPro++){ 58 | if( strncmp( getRulePtr(*itPro), splitInput[i-1], MAX_RULE_SIZE) == 0 ){ 59 | X[i][i].insert( getVariable(*itPro)); 60 | } 61 | } 62 | } 63 | 64 | //3. 65 | for( int step = 2; step <= n; step++){ 66 | for( int i = 1; i <= (n - step + 1); i++){ 67 | for( int k = i; k <= (i + step - 2 ); k++){ 68 | addDerivableVars(X[i][k], X[k+1][i+step-1], X[i][i+step-1], grammer[RULES]); 69 | } 70 | } 71 | 72 | } 73 | 74 | //4. 75 | if( member(X[1][n], *(grammer[START].begin()))){ 76 | cout << input << ": is in the language" << endl; 77 | } 78 | else{ 79 | cout << input << ": is not in the language" << endl; 80 | } 81 | 82 | // Should add choice from the user to print into latex or a txt file. 83 | //printDiagMatrix(X, n); 84 | outputLatex(X, pathOut, n); 85 | // outputMatrix(X, pathOut, n); 86 | } 87 | 88 | 89 | // if A -> BC, returns the variable that was 90 | void addDerivableVars( set B, set C, set& addTo, set rules){ 91 | 92 | set::iterator itPro; 93 | set::iterator itB; 94 | set::iterator itC; 95 | char* var; 96 | char* rule, *rulePtr; 97 | int size = 0; 98 | 99 | if( B.size() <= 0 && C.size() <= 0 ){ 100 | return; 101 | } 102 | 103 | for( itPro = rules.begin(); itPro != rules.end(); itPro++){ 104 | rule = getRulePtr(*itPro); 105 | rulePtr = rule; 106 | for( itB = B.begin(); itB != B.end(); itB++){ 107 | for( itC = C.begin(); itC != C.end(); itC++){ 108 | 109 | if( (size = isVariable(rulePtr)) && strncmp(rulePtr, *itB, size) == 0){ 110 | rulePtr+=size; 111 | } 112 | 113 | if( (size = isVariable(rulePtr)) && strncmp(rulePtr, *itC, size) == 0){ 114 | rulePtr+=size; 115 | } 116 | 117 | if( !(*rulePtr) ){ 118 | var = getVariable(*itPro); 119 | insertIntoSet(addTo, var); 120 | } 121 | rulePtr = rule; 122 | } 123 | } 124 | } 125 | } 126 | 127 | setMatrix init2DMatrix(int n){ 128 | 129 | setMatrix X; 130 | 131 | X.resize(n+1); 132 | for( int i = 1; i <= n; i++){ 133 | X[i].resize(n+1); 134 | } 135 | 136 | return X; 137 | } 138 | 139 | 140 | 141 | // *** Looking pretty functions *** \\\ 142 | 143 | void outputMatrix(setMatrix X, char* pathOut, int n){ 144 | 145 | set::iterator it; 146 | char outputStream[MAX_FILE_SIZE*2] = ""; 147 | 148 | for( int i = 1; i <= n; i++){ 149 | for( int j = 1; j <= n; j++){ 150 | if( j < i ){ 151 | strncat(outputStream, "-\t\t\t", 4); 152 | } 153 | else{ 154 | strncat(outputStream, "{", 1); 155 | for(it = X[i][j].begin(); it != X[i][j].end();){ 156 | strncat(outputStream, *it, MAX_VAR_SIZE); 157 | if( (++it) != (X[i][j].end())) 158 | strncat(outputStream, ",", 1); 159 | } 160 | strncat(outputStream, "}\t\t\t", 4); 161 | } 162 | } 163 | strncat(outputStream, "\n", 1); 164 | } 165 | 166 | sendStream(pathOut, outputStream); 167 | } 168 | 169 | 170 | 171 | int maxSetSize(setMatrix X, int n){ 172 | 173 | int tmpSize, maxSize = 0; 174 | 175 | for( int i = 1; i <= n; i++){ 176 | for( int j = 1; j <= n; j++){ 177 | tmpSize = X[i][j].size(); 178 | if( tmpSize > maxSize){ 179 | maxSize = tmpSize; 180 | } 181 | } 182 | } 183 | 184 | return maxSize; 185 | } 186 | 187 | 188 | void printDiagMatrix( setMatrix X, int n){ 189 | 190 | 191 | set::iterator it; 192 | int numTab = (maxSetSize(X, n) * MAX_VAR_SIZE)/5; 193 | 194 | cout << numTab << "--" << endl; 195 | 196 | for(int i = 1; i <= n; i++){ 197 | for(int j = 1; j <= n; j++){ 198 | if( j < i ){ 199 | cout << "-\t"; 200 | } 201 | else{ 202 | cout << "{"; 203 | for(it = X[i][j].begin(); it != X[i][j].end();){ 204 | cout << *it; 205 | if( (++it) != (X[i][j].end())){ 206 | cout << ","; 207 | } 208 | } 209 | cout << "}\t"; 210 | } 211 | 212 | } 213 | cout << endl; 214 | } 215 | } 216 | -------------------------------------------------------------------------------- /Chapter4/alg4_6/gramIO.h: -------------------------------------------------------------------------------- 1 | ../library/gramIO.h -------------------------------------------------------------------------------- /Chapter4/alg4_6/gramLib.h: -------------------------------------------------------------------------------- 1 | ../library/gramLib.h -------------------------------------------------------------------------------- /Chapter4/alg4_6/grammer.txt: -------------------------------------------------------------------------------- 1 | S -> aXb | ab 2 | X -> aXb | ab 3 | -------------------------------------------------------------------------------- /Chapter4/alg4_6/latex.h: -------------------------------------------------------------------------------- 1 | #include "gramLib.h" 2 | #include "gramIO.h" 3 | 4 | 5 | void outputLatex( std::vector > > matrix, char* pathOut, int size); 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Chapter4/alg4_6/latexTable.cpp: -------------------------------------------------------------------------------- 1 | #include "gramLib.h" 2 | #include "gramIO.h" 3 | #include "stdlib.h" 4 | #include "latex.h" 5 | 6 | using namespace std; 7 | 8 | void outputLatex( vector > > matrix, char* pathOut, int size){ 9 | 10 | 11 | char final[MAX_FILE_SIZE*2] = ""; 12 | char topHalf[MAX_FILE_SIZE*2] = "\\documentclass{article}\n\n\\usepackage[english]{babel}\n\n\\begin{document}\n\n\\begin{center}\n\t\\begin{tabular}{"; 13 | char botHalf[] = "\t\\hline\n\t\\end{tabular}\n\\end{center}\n\n\\end{document}\n"; 14 | char pdflatex[256] = "pdflatex "; 15 | set::iterator it; 16 | 17 | strncat(topHalf, " |", 2); 18 | for( int i = 0; i < size; i++){ 19 | strncat(topHalf, " c |", 4); 20 | } 21 | 22 | strncat(topHalf, "}\n\t\\hline\n\t", 12); 23 | 24 | for( int i = 1; i <= size; i++){ 25 | for( int j = 1; j <= size; j++){ 26 | if( j < i ) { 27 | strncat(topHalf, "-", 1); 28 | } 29 | else{ 30 | strncat(topHalf, "\\{", 2); 31 | for( it = matrix[i][j].begin(); it != matrix[i][j].end();){ 32 | strncat(topHalf, *it, MAX_VAR_SIZE); 33 | if( (++it) != (matrix[i][j].end())){ 34 | strncat(topHalf, ", ", 1); 35 | } 36 | } 37 | 38 | strncat(topHalf, "\\}", 2); 39 | } 40 | 41 | if( (j+1) <= size ){ 42 | strncat(topHalf, " & ", 4); 43 | } 44 | 45 | } 46 | 47 | strncat(topHalf, " \\\\ \\hline\n\t", 12); 48 | 49 | } 50 | 51 | 52 | strcat(final, topHalf); 53 | strcat(final, botHalf); 54 | sendStream(pathOut, final); 55 | strcat(pdflatex, pathOut); 56 | strcat(pdflatex, " >/dev/null"); 57 | system(pdflatex); 58 | 59 | 60 | /* system("rm tmp.log"); 61 | system("rm tmp.tex"); 62 | system("rm tmp.aux"); */ 63 | 64 | 65 | 66 | } 67 | -------------------------------------------------------------------------------- /Chapter4/alg4_6/lib.h: -------------------------------------------------------------------------------- 1 | ../../Main/library/lib.h -------------------------------------------------------------------------------- /Chapter4/alg4_6/makefile: -------------------------------------------------------------------------------- 1 | OBJS = alg4_5.o lib.o grammerIO.o 2 | MAIN = alg4_5 3 | 4 | all: remove compile 5 | 6 | new: compile 7 | 8 | compile: $(OBJS) 9 | g++ $(OBJS) -o test 10 | 11 | $(MAIN).o: 12 | g++ -c $(MAIN).cpp 13 | 14 | lib.o: 15 | g++ -c /home/schbra02/web/library/lib.cpp 16 | 17 | grammerIO.o: 18 | g++ -c /home/schbra02/web/library/grammerIO.cpp 19 | 20 | remove: 21 | rm $(MAIN).o 22 | 23 | clean: 24 | rm -rf *o compile 25 | -------------------------------------------------------------------------------- /Chapter4/alg4_6/newGrammer.txt: -------------------------------------------------------------------------------- 1 | S -> a | A0T1 2 | C -> C0C | c 3 | A0 -> a 4 | B -> B0C0 | B0T2 5 | C0 -> c 6 | A -> A0A | a 7 | T0 -> BC 8 | B0 -> b 9 | T1 -> AT0 10 | T2 -> C0B 11 | -------------------------------------------------------------------------------- /Chapter4/alg4_6/test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlas-2192/Language-Algorithms/7c7c47ae661f6fed94347eacfa253395bc3a3e43/Chapter4/alg4_6/test -------------------------------------------------------------------------------- /Chapter4/alg4_7/alg4_7.cpp: -------------------------------------------------------------------------------- 1 | #include "gramIO.h" 2 | #include "gramLib.h" 3 | #include "lib.h" 4 | #include "../main/chap4.h" 5 | #include 6 | #include 7 | 8 | void removeDirectLeftRec(std::set* grammer, std::set* newGrammer, char* variable); 9 | 10 | bool isDLR(std::set* grammer, char* var); 11 | 12 | char* generateNewVar(std::set variables); 13 | 14 | using namespace std; 15 | void alg4_7(char* pathIn, char* pathOut){ 16 | 17 | srand( time(NULL) ); 18 | 19 | set newGrammer[4]; 20 | set grammer[4]; 21 | set::iterator it; 22 | 23 | parseGrammer(pathIn, grammer); 24 | 25 | unionSet(newGrammer[ALPHABET], grammer[ALPHABET]); 26 | unionSet(newGrammer[VARIABLES], grammer[VARIABLES]); 27 | unionSet(newGrammer[START], grammer[START]); 28 | 29 | for( it = grammer[VARIABLES].begin(); it != grammer[VARIABLES].end(); it++){ 30 | removeDirectLeftRec(grammer, newGrammer, *it); 31 | } 32 | 33 | 34 | outputGrammer(pathOut, newGrammer); 35 | 36 | freeCont(grammer[3]); 37 | freeCont(grammer[2]); 38 | freeCont(grammer[1]); 39 | freeCont(grammer[0]); 40 | // freeCont(newGrammer[3]); 41 | freeCont(newGrammer[2]); 42 | // freeCont(newGrammer[1]); 43 | // freeCont(newGrammer[0]); 44 | 45 | } 46 | 47 | // This function is for GNF, since it has 48 | // to check if any of the new rules have DLR 49 | // This way I can modifiy the grammer on the fly 50 | void alg4_7_GNF(set* grammer, char* var){ 51 | set newGrammer[4]; 52 | set::iterator it, tmp; 53 | 54 | unionSet(newGrammer[VARIABLES], grammer[VARIABLES]); 55 | 56 | removeDirectLeftRec(grammer, newGrammer, var); 57 | 58 | for( it = grammer[RULES].begin(); it != grammer[RULES].end(); ){ 59 | if( varEqual( var, *it ) ){ 60 | tmp = it; 61 | ++it; 62 | grammer[RULES].erase(tmp); 63 | } 64 | else{ 65 | ++it; 66 | } 67 | } 68 | 69 | unionSet(grammer[RULES], newGrammer[RULES]); 70 | unionSet(grammer[VARIABLES], newGrammer[VARIABLES]); 71 | } 72 | 73 | /* Removal of Direct Left Recusion 74 | 75 | Example 1: 76 | A -> Aa | b 77 | ----------- 78 | A -> bZ | b 79 | A -> aZ | a 80 | 81 | Example 2: 82 | A -> Aa | Ab | b | c 83 | -------------------- 84 | A -> bZ | cZ | b | c 85 | Z -> aZ | bZ | a | b 86 | 87 | Example 3: 88 | A -> AB | BA | a 89 | B -> b | c 90 | ---------------- 91 | A -> BAZ | aZ | BA | a 92 | Z -> BZ | B 93 | B -> b | c 94 | 95 | A rules are broken into 2 categories: 96 | -Left Recursive Rules: 97 | A -> Au1 | Au2 | ... | Auj 98 | -The Rules 99 | A -> v1 | v2 | ... | vk 100 | 101 | Which will produce these new rules 102 | A -> v1 | ... | vk | v1Z | ... | vkZ 103 | Z -> u1Z | ... | ujZ | u1 | ... | uj 104 | 105 | 106 | */ 107 | 108 | 109 | 110 | 111 | // Need to check if such a rule exist A -> AAAAa 112 | void removeDirectLeftRec(set* grammer, set* newGrammer, char* variable){ 113 | 114 | set::iterator itPro; 115 | char* rulePtr; 116 | char* newVar = generateNewVar(newGrammer[VARIABLES]); 117 | char* newRule; 118 | char* tmp; 119 | int oldRuleSize = newGrammer[RULES].size(); 120 | int size; 121 | 122 | if( isDLR(grammer, variable) ){ 123 | insertIntoSet(newGrammer[VARIABLES], newVar); 124 | 125 | for( itPro = grammer[RULES].begin(); itPro != grammer[RULES].end(); ++itPro){ 126 | if( varEqual(variable, *itPro) ){ 127 | rulePtr = getRulePtr(*itPro); 128 | // If a rule is direct left recurisve 129 | if( (size = isVariable(rulePtr)) && (strncmp(variable, rulePtr, size)) == 0 ){ 130 | // First one for Z -> u1 | ... | uj 131 | tmp = new char[MAX_RULE_SIZE+1]; 132 | // rulePtr+size skips the recusive variable 133 | strncpy(tmp, (rulePtr+size), strnlen(rulePtr, MAX_RULE_SIZE)); 134 | newRule = newProduction(newVar, tmp); 135 | 136 | delete(tmp); 137 | 138 | // Now need to make new memory for the Z -> Au1 | ... | Auj 139 | tmp = new char[MAX_RULE_SIZE+1]; 140 | strncpy(tmp, newRule, MAX_RULE_SIZE); 141 | 142 | // Insert the u1 | ... | uj rule, since this can delete the pointer 143 | // we need to make sure we copy it into a tmp first 144 | insertIntoSet(newGrammer[RULES], newRule); 145 | 146 | // Now add the newVar on to u1 | ... | uj such that Z -> u1Z | ... | ujZ 147 | strncat(tmp, newVar, MAX_VAR_SIZE); 148 | 149 | //Puts the new rule into the RULES, it will take care of 150 | //the delete if it is already in RULES 151 | insertIntoSet(newGrammer[RULES], tmp); 152 | } 153 | // It is a non-DLR rule 154 | else{ 155 | newRule = new char[MAX_RULE_SIZE+1]; 156 | strncpy(newRule, *itPro, MAX_RULE_SIZE+1); 157 | 158 | tmp = new char[MAX_RULE_SIZE+1]; 159 | strncpy(tmp, newRule, MAX_RULE_SIZE+1); 160 | strncat(tmp, newVar, MAX_VAR_SIZE); 161 | 162 | 163 | insertIntoSet(newGrammer[RULES], newRule); 164 | insertIntoSet(newGrammer[RULES], tmp); 165 | } 166 | } 167 | 168 | } 169 | 170 | } 171 | else{ 172 | for( itPro = grammer[RULES].begin(); itPro != grammer[RULES].end(); ++itPro){ 173 | if( varEqual(variable, *itPro) ){ 174 | newRule = new char[MAX_RULE_SIZE+1]; 175 | strncpy(newRule, *itPro, MAX_RULE_SIZE+1); 176 | insertIntoSet(newGrammer[RULES], newRule); 177 | } 178 | } 179 | } 180 | 181 | } 182 | // Use this to tell if a grammer is DLR 183 | bool isDLR(set* grammer, char* var){ 184 | 185 | set::iterator it; 186 | char* rulePtr; 187 | int size; 188 | 189 | for( it = grammer[RULES].begin(); it != grammer[RULES].end(); ++it){ 190 | rulePtr = getRulePtr(*it); 191 | if( varEqual(var, *it) ){ 192 | if( (size = isVariable(rulePtr)) && strncmp(var, rulePtr, size) == 0) { 193 | return true; 194 | } 195 | } 196 | 197 | } 198 | 199 | return false; 200 | 201 | } 202 | 203 | 204 | char* generateNewVar(set variables){ 205 | 206 | char* newVar = new char[MAX_VAR_SIZE+1]; 207 | char* ptr = (newVar+1); 208 | int random; 209 | strncpy(newVar, "Z\0", 2); 210 | 211 | while( member(variables, newVar) && strnlen(newVar, MAX_VAR_SIZE) <= MAX_VAR_SIZE){ 212 | random = (rand() % 10); 213 | *(ptr++) = (char)(((int)'0')+random); 214 | *(ptr) = '\0'; 215 | } 216 | 217 | return newVar; 218 | } 219 | -------------------------------------------------------------------------------- /Chapter4/alg4_7/gramIO.h: -------------------------------------------------------------------------------- 1 | ../library/gramIO.h -------------------------------------------------------------------------------- /Chapter4/alg4_7/gramLib.h: -------------------------------------------------------------------------------- 1 | ../library/gramLib.h -------------------------------------------------------------------------------- /Chapter4/alg4_7/grammer.txt: -------------------------------------------------------------------------------- 1 | A -> AB | BA | a 2 | B -> b | c 3 | -------------------------------------------------------------------------------- /Chapter4/alg4_7/lib.h: -------------------------------------------------------------------------------- 1 | ../../Main/library/lib.h -------------------------------------------------------------------------------- /Chapter4/alg4_7/newGrammer.txt: -------------------------------------------------------------------------------- 1 | A -> BA | BAZ | a | aZ 2 | B -> b | c 3 | Z -> BZ | B 4 | -------------------------------------------------------------------------------- /Chapter4/alg4_8/alg4_8.cpp: -------------------------------------------------------------------------------- 1 | #include "gramIO.h" 2 | #include "gramLib.h" 3 | #include "lib.h" 4 | #include "../main/chap4.h" 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | void convertToGBN(std::set* grammer); 11 | 12 | bool ruleViolation(char* production, std::map numbers); 13 | 14 | void assignNumbers(std::set variables, char* start, std::map& numbers); 15 | 16 | std::set lemma4_1_3(char* production, std::set& rules); 17 | 18 | using namespace std; 19 | void alg4_8(char* pathIn, char* pathOut){ 20 | 21 | 22 | srand( time(NULL) ); 23 | 24 | set grammer[4]; 25 | 26 | alg4_7(pathIn, pathIn); 27 | 28 | parseGrammer(pathIn, grammer); 29 | 30 | convertToGBN(grammer); 31 | 32 | set::iterator it, it2; 33 | int tmp = 0; 34 | 35 | /* 36 | for( it = grammer[VARIABLES].begin(); it != grammer[VARIABLES].end(); ++it){ 37 | for( it2 = grammer[RULES].begin(); it2 != grammer[RULES].end(); ++it2){ 38 | if( varEqual(*it, *it2) ){ 39 | tmp++; 40 | } 41 | } 42 | cout << "Var: " << *it << " has " << tmp << " rules" << endl; 43 | tmp = 0; 44 | }*/ 45 | 46 | 47 | outputGrammer(pathOut, grammer); 48 | 49 | freeCont(grammer[3]); 50 | freeCont(grammer[2]); 51 | freeCont(grammer[1]); 52 | freeCont(grammer[0]); 53 | } 54 | 55 | /* Greibach Normal Form 56 | 57 | It is GNF if each of the rules follow one of these rules: 58 | A -> aA1A2...An 59 | A -> a 60 | S -> S 61 | 62 | where a (exist in) E and Ai (exist in) V - {S} for i = 1,2,...,n 63 | 64 | We will remove direct left recursion from a G in chomsky normal form 65 | so the rules will follow one of these rules: 66 | A -> BC 67 | A -> a 68 | S -> $ 69 | 70 | Now all we have to replace are A -> BC, with lemma 4.1.3 71 | 72 | P' = ( P - {A -> uBv}) U {A -> uw1v | uw2v | ... | uwnv} 73 | 74 | 75 | */ 76 | 77 | 78 | void convertToGBN(set* grammer){ 79 | 80 | map numbers; 81 | 82 | assignNumbers(grammer[VARIABLES], *(grammer[START].begin()), numbers); 83 | 84 | /* 85 | 86 | Loop until all uphold the rule 87 | S -> $ 88 | A -> aw, w (exist in) V* 89 | A -> Bw, w (exist in) V*, and the number assgined to B is > then A 90 | 91 | loop 1-numbers.size(); 92 | char* currentVar = (find the next i); 93 | for( it = rules....++it){ 94 | removeDLR(grammer); 95 | if( varEqual( curVar, *it) && ruleViolation(*it, numbers){ 96 | lemma4_1_3(*it, grammer[RULES]); 97 | } 98 | } 99 | */ 100 | 101 | 102 | set newRules; 103 | set::iterator itPro, itVar; 104 | set::iterator end = grammer[RULES].end(); 105 | set::iterator tmp; 106 | char* curVar; 107 | int numSize = numbers.size(); 108 | 109 | 110 | for( int i = 1; i <= numSize; i++){ 111 | curVar = numbers[i]; 112 | for( itPro = grammer[RULES].begin(); itPro != end ;){ 113 | if( varEqual(curVar, *itPro) && ruleViolation(*itPro, numbers)){ 114 | tmp = itPro; 115 | ++itPro; 116 | unionSet(newRules, lemma4_1_3(*tmp, grammer[RULES])); 117 | } 118 | else{ 119 | ++itPro; 120 | } 121 | } 122 | unionSet(grammer[RULES], newRules); 123 | newRules.clear(); 124 | alg4_7_GNF(grammer, curVar); 125 | } 126 | 127 | // Now have to keep applying lema4_1_3 until all vars are in the form of: 128 | // A -> aw, w (exist in) V* 129 | 130 | /* 131 | 132 | for( itVar ... ++itVar){ 133 | for( itPro ... ++itPro){ 134 | if( varEqual( *itVar, *itPro) && isVariable(getRulePtr(*itPro) ){ 135 | lemma4_1_3( 136 | } 137 | } 138 | } 139 | */ 140 | 141 | for( itVar = grammer[VARIABLES].begin(); itVar != grammer[VARIABLES].end(); ++itVar){ 142 | for( itPro = grammer[RULES].begin(); itPro != grammer[RULES].end();){ 143 | if( varEqual( *itVar, *itPro) && isVariable(getRulePtr(*itPro)) ){ 144 | tmp = itPro; 145 | ++itPro; 146 | unionSet(newRules, lemma4_1_3(*tmp, grammer[RULES])); 147 | } 148 | else{ 149 | ++itPro; 150 | } 151 | unionSet(grammer[RULES], newRules); 152 | newRules.clear(); 153 | } 154 | } 155 | 156 | 157 | map::iterator it; 158 | 159 | cout << "Mapping of the Variables:" << endl; 160 | for( it = numbers.begin(); it != numbers.end(); ++it){ 161 | cout << it->first << " | " << it->second << endl; 162 | } 163 | } 164 | 165 | bool ruleViolation(char* production, map numbers){ 166 | 167 | char* rulePtr = getRulePtr(production); 168 | char* tmpNull = (rulePtr-1); 169 | *tmpNull = '\0'; 170 | int size = isVariable(rulePtr); 171 | int curVarNum; 172 | int ruleVarNum; 173 | 174 | map::iterator it; 175 | 176 | // check for A -> Bw 177 | for( it = numbers.begin(); it != numbers.end(); ++it){ 178 | if( strncmp(it->second, production, MAX_VAR_SIZE) == 0 ){ 179 | curVarNum = it->first; 180 | } 181 | if( strncmp(it->second, rulePtr, size) == 0 ){ 182 | ruleVarNum = it->first; 183 | } 184 | } 185 | 186 | *tmpNull = ' '; 187 | if( curVarNum > ruleVarNum ){ 188 | return true; 189 | } 190 | return false; 191 | } 192 | 193 | 194 | void assignNumbers(set variables, char* start, map& numbers){ 195 | 196 | set::iterator itVar; 197 | int i = 2; 198 | 199 | /* 200 | numbers.insert(std::pair(1,start)); 201 | numbers.insert(std::pair(2,"A")); 202 | numbers.insert(std::pair(3,"B")); 203 | numbers.insert(std::pair(4,"C")); 204 | numbers.insert(std::pair(5,"D")); 205 | */ 206 | numbers.insert(std::pair(1,start)); 207 | 208 | for( itVar = variables.begin(); itVar != variables.end(); ++itVar){ 209 | if( strncmp( *itVar, start, MAX_VAR_SIZE) != 0 ){ 210 | numbers.insert(std::pair(i, *itVar)); 211 | i++; 212 | } 213 | } 214 | 215 | } 216 | 217 | 218 | 219 | // P' = ( P - {A -> uBv} ) U { A -> uw1v | uw2v | ... | uwnv 220 | set lemma4_1_3(char* production, set& rules){ 221 | 222 | set newRules; 223 | set::iterator itPro; 224 | char* rulePtr = getRulePtr(production); 225 | char* newRule; 226 | int size = isVariable(rulePtr); 227 | 228 | 229 | 230 | //{ A -> uw1v | uw2v | ... | uwnv } 231 | for( itPro = rules.begin(); itPro != rules.end(); ++itPro ){ 232 | if( strncmp(rulePtr, *itPro, size) == 0 ){ 233 | newRule = new char[MAX_RULE_SIZE+1]; 234 | // Copys the prdocutions var + the space 235 | strncpy(newRule, production, (rulePtr-production)); 236 | *(newRule+(rulePtr-production)) = '\0'; 237 | //copys thes new rule B -> w to A -> uwv 238 | strncat(newRule, getRulePtr(*itPro), MAX_RULE_SIZE); 239 | //copys the rest of the rule v to uw, and skips the 240 | // var we are repalcing 241 | strncat(newRule, (rulePtr+size), MAX_RULE_SIZE); 242 | insertIntoSet(newRules, newRule); 243 | } 244 | } 245 | 246 | //( P - {A -> uBv} ) 247 | for( itPro = rules.begin(); itPro != rules.end(); ++itPro){ 248 | if(strncmp(production, *itPro, MAX_RULE_SIZE) == 0){ 249 | rules.erase(*itPro); 250 | itPro = (--rules.end()); 251 | } 252 | } 253 | // The union happens by just removing the old rule and inserting the new rules 254 | 255 | return newRules; 256 | } 257 | 258 | 259 | 260 | 261 | 262 | -------------------------------------------------------------------------------- /Chapter4/alg4_8/gramIO.h: -------------------------------------------------------------------------------- 1 | ../library/gramIO.h -------------------------------------------------------------------------------- /Chapter4/alg4_8/gramLib.h: -------------------------------------------------------------------------------- 1 | ../library/gramLib.h -------------------------------------------------------------------------------- /Chapter4/alg4_8/grammer.txt: -------------------------------------------------------------------------------- 1 | S -> AB | $ 2 | A -> CB | CBZ | a | aZ 3 | B -> AB | b 4 | C -> AC | c 5 | Z -> BZ | B 6 | -------------------------------------------------------------------------------- /Chapter4/alg4_8/lib.h: -------------------------------------------------------------------------------- 1 | ../../Main/library/lib.h -------------------------------------------------------------------------------- /Chapter4/alg4_8/newGrammer.txt: -------------------------------------------------------------------------------- 1 | S -> $ | aB | aZB | cBB | cZ7BB | aCBB | aCZ7BB | aZCBB | aZCZ7BB | cBZB | cZ7BZB | aCBZB | aCZ7BZB | aZCBZB | aZCZ7BZB 2 | C -> c | cZ7 | aC | aCZ7 | aZC | aZCZ7 3 | Z -> bZ | aBZ | aZBZ | b | aB | aZB | cBBZ | cZ7BBZ | aCBBZ | aCZ7BBZ | aZCBBZ | aZCZ7BBZ | cBZBZ | cZ7BZBZ | aCBZBZ | aCZ7BZBZ | aZCBZBZ | aZCZ7BZBZ | cBB | cZ7BB | aCBB | aCZ7BB | aZCBB | aZCZ7BB | cBZB | cZ7BZB | aCBZB | aCZ7BZB | aZCBZB | aZCZ7BZB 4 | A -> a | aZ | cB | cZ7B | aCB | aCZ7B | aZCB | aZCZ7B | cBZ | cZ7BZ | aCBZ | aCZ7BZ | aZCBZ | aZCZ7BZ 5 | B -> b | aB | aZB | cBB | cZ7BB | aCBB | aCZ7BB | aZCBB | aZCZ7BB | cBZB | cZ7BZB | aCBZB | aCZ7BZB | aZCBZB | aZCZ7BZB 6 | Z7 -> bCZ7 | aBCZ7 | aZBCZ7 | cBBCZ7 | cZ7BBCZ7 | aCBBCZ7 | aCZ7BBCZ7 | aZCBBCZ7 | aZCZ7BBCZ7 | cBZBCZ7 | cZ7BZBCZ7 | aCBZBCZ7 | aCZ7BZBCZ7 | aZCBZBCZ7 | aZCZ7BZBCZ7 | bC | aBC | aZBC | cBBC | cZ7BBC | aCBBC | aCZ7BBC | aZCBBC | aZCZ7BBC | cBZBC | cZ7BZBC | aCBZBC | aCZ7BZBC | aZCBZBC | aZCZ7BZBC | bZCZ7 | aBZCZ7 | aZBZCZ7 | cBBZCZ7 | cZ7BBZCZ7 | aCBBZCZ7 | aCZ7BBZCZ7 | aZCBBZCZ7 | aZCZ7BBZCZ7 | cBZBZCZ7 | cZ7BZBZCZ7 | aCBZBZCZ7 | aCZ7BZBZCZ7 | aZCBZBZCZ7 | aZCZ7BZBZCZ7 | bZC | aBZC | aZBZC | cBBZC | cZ7BBZC | aCBBZC | aCZ7BBZC | aZCBBZC | aZCZ7BBZC | cBZBZC | cZ7BZBZC | aCBZBZC | aCZ7BZBZC | aZCBZBZC | aZCZ7BZBZC 7 | -------------------------------------------------------------------------------- /Chapter4/grammers/grammerA.txt: -------------------------------------------------------------------------------- 1 | S -> aS | AB | AC 2 | B -> bS | bB 3 | A -> aA | $ 4 | C -> cC | $ 5 | -------------------------------------------------------------------------------- /Chapter4/grammers/grammerB.txt: -------------------------------------------------------------------------------- 1 | S -> ACA 2 | A -> aAa | B | C 3 | B -> bB | b 4 | C -> cC | $ 5 | -------------------------------------------------------------------------------- /Chapter4/grammers/grammerC.txt: -------------------------------------------------------------------------------- 1 | S -> ACA | CA | AA | AC | A | C 2 | A -> aAa | aa | B | C 3 | B -> bB | b 4 | C -> cC | c 5 | -------------------------------------------------------------------------------- /Chapter4/grammers/grammerD.txt: -------------------------------------------------------------------------------- 1 | S -> AC | BS | B 2 | A -> aA | aF 3 | B -> CF | b 4 | C -> cC | D 5 | D -> aD | BD | C 6 | E -> aA | BSA 7 | F -> bB | b 8 | -------------------------------------------------------------------------------- /Chapter4/grammers/grammerE.txt: -------------------------------------------------------------------------------- 1 | S -> BS | B 2 | A -> aA | aF 3 | B -> b 4 | E -> aA | BSA 5 | F -> bB | b 6 | -------------------------------------------------------------------------------- /Chapter4/grammers/grammerF.txt: -------------------------------------------------------------------------------- 1 | A -> bDcF 2 | -------------------------------------------------------------------------------- /Chapter4/grammers/grammerG.txt: -------------------------------------------------------------------------------- 1 | S -> AC | BS | B 2 | A -> aA | aF 3 | B -> CF | b 4 | C -> cC | D 5 | D -> aD | BD | C 6 | E -> aA | BSA 7 | F -> bB | b 8 | -------------------------------------------------------------------------------- /Chapter4/grammers/grammerH.txt: -------------------------------------------------------------------------------- 1 | S -> aABC | a 2 | A -> aA | a 3 | B -> bcB | bc 4 | C -> cC | c 5 | -------------------------------------------------------------------------------- /Chapter4/grammers/grammerI.txt: -------------------------------------------------------------------------------- 1 | S -> aXb | ab 2 | X -> aXb | ab 3 | -------------------------------------------------------------------------------- /Chapter4/library/gramIO.h: -------------------------------------------------------------------------------- 1 | 2 | //########################################## 3 | // -Author: Brandon Schaefer 4 | // -Created: 5/14/11 5 | // -File Name: gramIO.h 6 | //########################################## 7 | 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | 16 | 17 | //############################## 18 | // Reading in File Functions 19 | //############################## 20 | 21 | #define MAX_FILE_SIZE 512 22 | 23 | // Uses readFile to get a dynamic array with the 24 | // exact size of the file in a char* 25 | char* readGrammer(char* path); 26 | 27 | // If you dont want a dynamic array with the exact 28 | // size of the file use readFile(...); 29 | int readFile(char* path, char* file); 30 | 31 | void freeFile(char* file); 32 | 33 | 34 | //############################## 35 | // End of Reading in a file 36 | //############################## 37 | 38 | //############################## 39 | // Parsing Grammer Functions 40 | //############################## 41 | // This uses the reading in file so the user wont have to worry about mem leaks 42 | // its gets handled, all they have to provide is a set grammer[3]. 43 | 44 | #define VARIABLES 0 45 | #define ALPHABET 1 46 | #define RULES 2 47 | #define START 3 48 | 49 | #define MAX_VAR_SIZE 8 50 | #define MAX_TERM_SIZE 8 51 | #define MAX_RULE_SIZE 32 52 | 53 | //---- 54 | void parseGrammer(char* path, std::set* grammer); 55 | void parseLine(std::set* grammer, char* line); 56 | 57 | // gets the variable and also returns a pointer to the var 58 | char* getVariable(std::set& variables, char* line); 59 | 60 | // Goes through the line and finds terminals and adds those to 61 | // the alphabet 62 | void getAlphabet(std::set& alphabet, char* line); 63 | //int isTerminal(char* term); 64 | 65 | // Gets the rules from the line and the var found 66 | void getRules(std::set& rules, char* line, char* var); 67 | 68 | //############################## 69 | // End of Parsing Functions 70 | //############################## 71 | 72 | 73 | //############################## 74 | // Start of Outputing Grammer 75 | //############################## 76 | 77 | // Takes a file, and a grammer you used when reading in a grammer 78 | void outputGrammer( char* file, std::set* grammer); 79 | 80 | // Adds the start symbol first 81 | void insertStart( std::set* grammer, char* outputStream ); 82 | 83 | // Used when re-constructing the grammer into a format that it was read in 84 | void insertRules( char* var, std::set rules, char* outputStream); 85 | 86 | // Used to send the outputStream made in outputGrammer 87 | void sendStream( char* path, char* outputStream ); 88 | 89 | 90 | //############################## 91 | // End of Outputing Grammer 92 | //############################## 93 | -------------------------------------------------------------------------------- /Chapter4/library/gramIO.h.txt: -------------------------------------------------------------------------------- 1 | gramIO.h -------------------------------------------------------------------------------- /Chapter4/library/gramLib.cpp: -------------------------------------------------------------------------------- 1 | 2 | //########################################## 3 | // -Author: Brandon Schaefer 4 | // -Created: 5/08/11 5 | // -File Name: lib.cpp 6 | //########################################## 7 | #include "gramLib.h" 8 | #include "gramIO.h" 9 | #include "lib.h" 10 | #include 11 | 12 | 13 | using namespace std; 14 | 15 | /* 16 | // Set Functions ------- Member, Union, Intersection, Difference 17 | bool member(set mySet, char* data){ 18 | 19 | set::iterator it; 20 | 21 | for( it = mySet.begin(); it != mySet.end(); it++){ 22 | if( strcmp( *it, data) == 0 ){ 23 | return 1; 24 | } 25 | } 26 | return 0; 27 | 28 | } 29 | 30 | void unionSet(set& setA, set setB){ 31 | 32 | set::iterator it; 33 | 34 | for( it = setB.begin(); it != setB.end(); it++){ 35 | setA.insert(*it); 36 | } 37 | 38 | } 39 | 40 | 41 | void interSet(set& setA, set setB){ 42 | 43 | set::iterator it; 44 | set::iterator tmp; 45 | 46 | it = setA.begin(); 47 | 48 | while( it != setA.end() ){ 49 | if( !(member(setB, *it)) ){ 50 | tmp = it; 51 | ++it; 52 | setA.erase(tmp); 53 | } 54 | else{ 55 | ++it; 56 | } 57 | } 58 | } 59 | 60 | void diffSet(set& setA, set setB){ 61 | 62 | set::iterator it; 63 | set::iterator tmp; 64 | 65 | it = setA.begin(); 66 | 67 | while( it != setA.end()){ 68 | if( member( setB, *it) ){ 69 | tmp = it; 70 | ++it; 71 | setA.erase(tmp); 72 | } 73 | else{ 74 | ++it; 75 | } 76 | 77 | } 78 | } 79 | 80 | // ---- End of Set Functions 81 | 82 | 83 | 84 | // Takes a set and checks if the new data is already in the set 85 | void insertIntoSet(std::set& set, char* data){ 86 | 87 | if( !(member(set, data)) ){ 88 | set.insert(data); 89 | } 90 | else{ 91 | delete(data); 92 | } 93 | 94 | } 95 | 96 | 97 | bool compareSets( set setA, set setB ){ 98 | 99 | // check size of each first, its faster that way 100 | if( setA.size() == setB.size()){ 101 | 102 | set::iterator itA; 103 | set::iterator itB; 104 | 105 | for( itA = setA.begin(); itA != setA.end(); itA++){ 106 | if( member( setB, *itA ) == 0 ){ 107 | return false; 108 | } 109 | } 110 | return true; 111 | } 112 | return false; 113 | } 114 | 115 | 116 | void displaySet(set setA){ 117 | 118 | set::iterator it; 119 | 120 | for( it = setA.begin(); it != setA.end(); it++){ 121 | cout << *it << endl; 122 | } 123 | 124 | } 125 | 126 | bool isLowChar( char letter ){ 127 | int ascii = (int)letter; 128 | if( ascii >= 97 && ascii <= 122) 129 | return true; 130 | return false; 131 | } 132 | 133 | // return the size of the term or 0 if its false 134 | int isTerminal(char* term){ 135 | //checks if the first char is a letter 136 | int termSize = 0; 137 | if( isLowChar( *term++ ) || strcmp(term, NULL_CHAR) == 0 ){ 138 | termSize++; 139 | while( isDigit( *term++ ) ){ 140 | termSize++; 141 | } 142 | return termSize; 143 | } 144 | return termSize; 145 | } 146 | 147 | bool isDigit( char digit ){ 148 | int ascii = (int)digit; 149 | if( ascii >= 48 && ascii <= 57 ) 150 | return true; 151 | return false; 152 | } 153 | 154 | 155 | */ 156 | 157 | char* insertVariable( std::set& variables, char* production){ 158 | 159 | 160 | char* newVar = new char[MAX_VAR_SIZE+1]; 161 | int varSize = isVariable(production); 162 | strncpy(newVar, production, varSize); 163 | *(newVar+varSize) = '\0'; 164 | if( !(member(variables, newVar)) ){ 165 | variables.insert(newVar); 166 | } 167 | else{ 168 | delete(newVar); 169 | return NULL; 170 | } 171 | 172 | return newVar; 173 | } 174 | 175 | 176 | 177 | 178 | char* newProduction(char* variable, char* rule){ 179 | 180 | char* newPro = new char[MAX_RULE_SIZE+1]; 181 | 182 | strncpy(newPro, variable, strnlen(variable, MAX_VAR_SIZE)+1); 183 | 184 | strncat(newPro, " ", 1); 185 | strncat(newPro, rule, strnlen(rule, MAX_RULE_SIZE)); 186 | 187 | return newPro; 188 | } 189 | 190 | 191 | 192 | 193 | void displayGrammer(set* grammer){ 194 | for( int i = 0; i < 4; i++){ 195 | 196 | switch(i){ 197 | case(0): 198 | cout << "*-*-*-Variables-*-*-*" << endl; 199 | break; 200 | case(1): 201 | cout << "*-*-*-Alphabet-*-*-*" << endl; 202 | break; 203 | case(2): 204 | cout << "*-*-Production Rules-*-*" << endl; 205 | break; 206 | case(3): 207 | cout << "*-*-*-Start Symbol-*-*-*" << endl; 208 | break; 209 | } 210 | displaySet(grammer[i]); 211 | cout << "\n" << endl; 212 | } 213 | 214 | } 215 | 216 | 217 | 218 | // Takes the variable from a prodcution and makes a new char* 219 | // RETURNS A DYNAMICLY ALLOCATED POINTER 220 | char* getVariable(char* production){ 221 | 222 | int size = 0; 223 | char* newVar; 224 | 225 | if( (size = isVariable(production)) ){ 226 | newVar = new char[MAX_VAR_SIZE+1]; 227 | strncpy(newVar, production, size+1); 228 | *(newVar+size) = '\0'; 229 | return newVar; 230 | } 231 | return NULL; 232 | } 233 | 234 | // Takes a production and returns a pointer to the start of the rule 235 | // Eample: input with "S Aab" returns "Aab" 236 | char* getRulePtr(char* production){ 237 | while(*(production) && *(production++) != ' '); 238 | return production; 239 | } 240 | 241 | // takes a var and sees if its the same as a production var 242 | int varEqual(char* var, char* proVar){ 243 | int varSize = strlen(var); 244 | int ruleSize = variableLen(proVar); 245 | 246 | if( ruleSize == varSize && strncmp(var,proVar, ruleSize) == 0){ 247 | return 1; 248 | } 249 | 250 | return 0; 251 | } 252 | 253 | // Returns the size of the variable, so you can copy it into 254 | // another char* 255 | int variableLen( char* rule ){ 256 | int size = 0; 257 | 258 | while(*rule && *rule != ' '){ 259 | rule++; 260 | size++; 261 | } 262 | 263 | return size; 264 | } 265 | 266 | 267 | bool isUppChar( char letter ){ 268 | int ascii = (int)letter; 269 | if( ascii >= 65 && ascii <= 90 ) 270 | return true; 271 | return false; 272 | } 273 | 274 | 275 | 276 | // returns the size of the var in char*. 277 | // If it cannot it returns 0 ( varSize == 0 ) 278 | int isVariable(char* var){ 279 | int varSize = 0; 280 | if( isUppChar( *var++ ) ){ 281 | varSize++; 282 | while( isDigit( *var++ )){ 283 | varSize++; 284 | } 285 | return varSize; 286 | } 287 | return varSize; 288 | } 289 | 290 | 291 | 292 | 293 | char* flattenProductVector(vector splitRule){ 294 | 295 | int size = 0; 296 | 297 | if( (size = splitRule.size()) > 1 ){ 298 | char* flatRule = new char[MAX_RULE_SIZE+1]; 299 | 300 | strncpy(flatRule, splitRule[0], strlen(splitRule[0])+1); 301 | strncat(flatRule, " ", 1); 302 | for( int i = 1; i < size; i++){ 303 | strncat(flatRule, splitRule[i], MAX_RULE_SIZE); 304 | } 305 | return flatRule; 306 | } 307 | else{ 308 | return splitRule[0]; 309 | } 310 | 311 | 312 | 313 | } 314 | 315 | 316 | // Takes a production and put it into a vector 317 | // The production variable is stored in [0], so if you want to iterate through the rules start from [1] to [size()] 318 | // #### Will also turn just a rule into a vector ##### 319 | vector splitProduction(char* production){ 320 | 321 | vector proVec; 322 | char* newEntry;// = new char[MAX_RULE_SIZE+1]; 323 | int size; 324 | 325 | while( (size = isVariable(production)) || (size = isTerminal(production))){ 326 | newEntry = new char[MAX_RULE_SIZE+1]; 327 | strncpy(newEntry, production, size); 328 | *(newEntry+size) = '\0'; 329 | proVec.push_back(newEntry); 330 | production += size; 331 | // This is just for the space sperating the 332 | // variable form the rule. 333 | while( *production == ' ' ){ 334 | production++; 335 | } 336 | } 337 | 338 | 339 | return proVec; 340 | } 341 | 342 | 343 | void freeSet(set& setA){ 344 | 345 | set::iterator it; 346 | 347 | for( it = setA.begin(); it != setA.end(); ++it){ 348 | delete(*it); 349 | } 350 | } 351 | -------------------------------------------------------------------------------- /Chapter4/library/gramLib.h: -------------------------------------------------------------------------------- 1 | //########################################## 2 | // -Author: Brandon Schaefer 3 | // -Created: 5/08/11 4 | // -File Name: gramLib.h 5 | //########################################## 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | // Used in alg4_6 13 | typedef std::vector > > setMatrix; 14 | 15 | #define NULL_CHAR "$" 16 | 17 | /* 18 | #ifndef __LIB_H 19 | #define __LIB_H 20 | 21 | // Basic Set Functions 22 | bool member(std::set setA, char* data); 23 | void unionSet(std::set& setA, std::set setB); 24 | void interSet(std::set& setA, std::set setB); 25 | void diffSet(std::set& setA, std::set setB); 26 | // --- End of set funcs 27 | 28 | void insertIntoSet(std::set& set, char* data); 29 | 30 | bool compareSets( std::set setA, std::set setB ); 31 | 32 | void displaySet(std::set setA); 33 | 34 | bool isDigit( char digit ); 35 | bool isCapChar( char letter ); 36 | bool isLowChar( char letter ); 37 | 38 | // Both of these return 0 if no terminal or var is found 39 | // otherwise it returns the size of the term or var in the 40 | // char* 41 | 42 | NULL_CHAR IS NOT A TERMINAL, NEED TO FIX THIS 43 | int isTerminal( char* term ); 44 | 45 | 46 | */ 47 | 48 | 49 | int isVariable( char* var ); 50 | 51 | 52 | char* newProduction(char* variable, char* rule); 53 | 54 | // Takes a production rule and takes the variable off it and 55 | // inserts it into the set. 56 | char* insertVariable( std::set& variables, char* production); 57 | 58 | // returns a pointer the rule of the production 59 | char* getRulePtr(char* production); 60 | 61 | // RETURNS A NEW CHAR[MAX_VAR_SIZE+1]; 62 | char* getVariable(char* production); 63 | 64 | // Checks if a variable is equal to one in a production rule 65 | int varEqual(char* var, char* proVar); 66 | 67 | // gets the length of a variable in a production rule 68 | int variableLen( char* production ); 69 | 70 | void displayGrammer(std::set* grammer); 71 | 72 | 73 | 74 | 75 | //************************************************************ 76 | /* bug :: SKIPPING THE NULL_CHAR, NEED TO PUT NULL_CHAR INTO THE VECTOR */ 77 | //************************************************************ 78 | // Splits a rule up by terminals and varibles 79 | // and puts it into a vector 80 | std::vector splitProduction(char* production); 81 | char* flattenProductVector(std::vector splitRule); 82 | 83 | #ifndef __FREE_H 84 | #define __FREE_H 85 | 86 | template 87 | inline void freeCont(T& cont){ 88 | typename T::iterator it; 89 | 90 | for( it = cont.begin(); it != cont.end(); it++){ 91 | delete(*it); 92 | } 93 | } 94 | 95 | #endif 96 | 97 | 98 | void freeGrammer(std::set* grammer); 99 | -------------------------------------------------------------------------------- /Chapter4/library/gramLib.h.txt: -------------------------------------------------------------------------------- 1 | gramLib.h -------------------------------------------------------------------------------- /Chapter4/library/grammer.txt: -------------------------------------------------------------------------------- 1 | S -> A214C124A124 | $ | C124A124 | A124A124 | A124C124 | A634 | C 2 | A -> aAa | aa | B | C 3 | B -> bB | b 4 | C -> cC | c 5 | -------------------------------------------------------------------------------- /Chapter4/library/grammer2.txt: -------------------------------------------------------------------------------- 1 | S -> ACA | CA | AA | AC | A | C 2 | A -> aAa | aa | B | C 3 | B -> bB | b 4 | C -> cC | c 5 | -------------------------------------------------------------------------------- /Chapter4/library/grammerIO.cpp: -------------------------------------------------------------------------------- 1 | 2 | //########################################## 3 | // -Author: Brandon Schaefer 4 | // -Created: 5/14/11 5 | // -File Name: grammerIO.cpp 6 | //########################################## 7 | #include "gramLib.h" 8 | #include "gramIO.h" 9 | #include "lib.h" 10 | 11 | using namespace std; 12 | 13 | 14 | //############################## 15 | // Start of Reading in Grammer from File 16 | //############################## 17 | 18 | 19 | char* readGrammer(char* path){ 20 | 21 | // MAX_FILE_SIZE is 256 22 | char* tmpPtr = new char[MAX_FILE_SIZE]; 23 | 24 | // Does 2 things, gets the raw file data and the size of the file 25 | // We put it in a tmpPtr so we can allocate a new array. 26 | int size = readFile(path, tmpPtr); 27 | 28 | // readFile returns the size of the file so we can now 29 | // make an array to fit the exact size of the file +1 for '\0' 30 | char* file = new char[size+1]; 31 | strncpy(file, tmpPtr, size+1); 32 | 33 | // Delete the tmp ptr 34 | delete tmpPtr; 35 | return file; 36 | } 37 | 38 | int readFile(char* path, char* file){ 39 | int length; 40 | ifstream is; 41 | 42 | is.open(path); 43 | 44 | if( is.is_open() && is.good()){ 45 | // Gets the length of the file 46 | is.seekg(0, ios::end); 47 | length = is.tellg(); 48 | is.seekg(0, ios::beg); 49 | 50 | // Takes the raw data from the file and put it in file. 51 | is.read(file, length); 52 | /* DOUBLE CHECK THAT I DONT NEED TO BE OUT SIDE THE IF */ 53 | } 54 | else{ 55 | cerr << "Bad File Name: " << path << endl; 56 | throw; 57 | } 58 | 59 | is.close(); 60 | *(file+length) = '\0'; 61 | return length; 62 | } 63 | 64 | void freeFile(char* file){ 65 | delete(file); 66 | } 67 | 68 | 69 | //############################## 70 | // ---------------- End of reading in a grammer from a file 71 | //############################## 72 | 73 | 74 | 75 | 76 | //############################## 77 | // -------- Start of ParsingGrammer Functions into a set ------------ // 78 | //############################## 79 | // Sample use: 80 | /* 81 | // You have to allocate space for grammer 82 | std::set grammer[3]; 83 | parseGrammer("grammer.txt", grammer); 84 | 85 | displaySet(grammer[VARIABLES]); 86 | cout << "---- END OF VARS ----" << endl; 87 | displaySet(grammer[ALPHABET]); 88 | cout << "---- END OF ALPH ----" << endl; 89 | displaySet(grammer[RULES]); 90 | 91 | */ 92 | 93 | 94 | // The grammer is a set of sets in the form of 95 | // V = The variables, the set non-terminals 96 | // A = The alaphabet, the set of all possible terminals 97 | // P = The productions, the 98 | void parseGrammer( char* path, set* grammer ){ 99 | 100 | char* file = readGrammer(path); 101 | char* p; 102 | char* line = strtok_r(file, "\n", &p); 103 | 104 | 105 | // Gets the start symbol 106 | insertVariable( grammer[START], line); 107 | 108 | while( line ){ 109 | parseLine(grammer, line); 110 | line = strtok_r(NULL, "\n", &p); 111 | } 112 | 113 | 114 | freeFile(file); 115 | } 116 | 117 | 118 | void parseLine( set* grammer, char* line){ 119 | char* var = getVariable(grammer[VARIABLES], line); 120 | if( var ){ 121 | getAlphabet(grammer[ALPHABET], line); 122 | getRules(grammer[RULES], line, var); 123 | } 124 | } 125 | 126 | /*################## FIX ME ######################### USE NEW isVariable FUNCTION */ 127 | 128 | // Stores the var the grammer set and also returns a pointer to the var thats found 129 | char* getVariable( set& variables, char* line){ 130 | 131 | char* newVar; 132 | 133 | if( isVariable(line)){ 134 | newVar = insertVariable(variables, line); 135 | return newVar; 136 | } 137 | return NULL; 138 | } 139 | 140 | 141 | //get any letter that is lower case which is a terminal meaning there can only be 26 different terminals 142 | void getAlphabet(set& alphabet, char* line){ 143 | char* newAlph, *linePtr = line; 144 | int termSize = 0; 145 | 146 | while(*linePtr){ 147 | if(( termSize = isTerminal(linePtr))){ 148 | newAlph = new char[termSize+1]; 149 | *(newAlph+termSize) = '\0'; 150 | strncpy(newAlph, linePtr, termSize); 151 | linePtr+= termSize; 152 | 153 | // Here so if already in set we need to free the memory 154 | // Otherwise mem leak. 155 | if(!member(alphabet, newAlph)){ 156 | alphabet.insert(newAlph); 157 | } 158 | else{ 159 | delete(newAlph); 160 | } 161 | 162 | } 163 | else{ 164 | linePtr++; 165 | } 166 | // Moves ptr to next term or var. 167 | 168 | } 169 | 170 | } 171 | 172 | void getRules( set& rules, char* line, char* var){ 173 | char* rule, *ptr, *p; 174 | 175 | // Skips of var until it hits the ->, 176 | // then it eats up all the empty spaces 177 | while(*line && *(line++) != '>'); 178 | while(*line && *(++line) == ' '); 179 | 180 | ptr = strtok_r(line, "| ", &p); 181 | 182 | 183 | while(ptr){ 184 | rule = new char[MAX_RULE_SIZE]; 185 | strncpy(rule, var, MAX_VAR_SIZE); 186 | strncat(rule, " ", 1); 187 | strncat(rule, ptr, MAX_RULE_SIZE); 188 | rules.insert(rule); 189 | ptr = strtok_r(NULL, "| ", &p); 190 | } 191 | } 192 | 193 | 194 | //############################## 195 | // ------- END OF PARSING AND READING A GRAMMER IN ---------------- 196 | //############################## 197 | 198 | 199 | //############################## 200 | // ------ START OF GRAMMER OUTPUT TO A FILE ------------------------- 201 | //############################## 202 | 203 | void outputGrammer( char* file, set* grammer){ 204 | 205 | set::iterator itVar; 206 | char* start = *(grammer[START].begin()); 207 | char outputStream[MAX_FILE_SIZE*4] = ""; 208 | 209 | insertStart(grammer, outputStream); 210 | 211 | // Iterates through the variables then goes to insertRules to get the productions rules for each 212 | // variable 213 | for( itVar = grammer[VARIABLES].begin(); itVar != grammer[VARIABLES].end(); itVar++){ 214 | if( strcmp(start, *itVar) != 0 ){ 215 | strncat(outputStream, *itVar, MAX_VAR_SIZE); 216 | strncat(outputStream, " -> ", 4); 217 | insertRules( *itVar, grammer[RULES], outputStream); 218 | strncat(outputStream, "\n", 1); 219 | } 220 | } 221 | 222 | sendStream( file, outputStream ); 223 | 224 | } 225 | 226 | 227 | void insertStart( set* grammer, char* outputStream){ 228 | 229 | char* start = *(grammer[START].begin()); 230 | 231 | strncat(outputStream, start, MAX_VAR_SIZE); 232 | strncat(outputStream, " -> ", 4); 233 | insertRules( start, grammer[RULES], outputStream); 234 | strncat(outputStream, "\n", 1); 235 | 236 | } 237 | 238 | 239 | // Takes a variable and the rules from the grammer and finds the rules of the variable 240 | // and adds it the outputStream char* so it can be outputed to a file later. 241 | void insertRules( char* variable, set rules, char* outputStream ){ 242 | 243 | set::iterator itRule; 244 | char* ptr; 245 | 246 | for( itRule = rules.begin(); itRule != rules.end(); itRule++){ 247 | if( varEqual( variable, *itRule) ){ 248 | strncat(outputStream, getRulePtr(*itRule), MAX_RULE_SIZE); 249 | strncat(outputStream, " | ", 3); 250 | } 251 | 252 | } 253 | // removes the extra bar that the end, and the extra 0 254 | //*(strrchr(outputStream, '|')-1) = '\0'; 255 | if( (ptr = strrchr(outputStream, '|')) != NULL ){ 256 | *(ptr-1) = '\0'; 257 | } 258 | } 259 | 260 | // Takes the outputStream made in outputGrammer(...) and sends it to a specified file. 261 | void sendStream( char* path, char* outputStream ){ 262 | 263 | int size = strlen(outputStream); 264 | 265 | ofstream outfile( path ); 266 | if( outfile.is_open() && outfile.good()){ 267 | 268 | outfile.write(outputStream, size); 269 | } 270 | else{ 271 | cerr << "Error in opening file: " << path << endl; 272 | throw; 273 | } 274 | outfile.close(); 275 | } 276 | 277 | 278 | //############################## 279 | // End of output grammer functions 280 | //############################## 281 | -------------------------------------------------------------------------------- /Chapter4/library/index.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 |

Library Functions

6 | 7 |

Having a set of library functions will help implement the algorithms striaght out of the book
8 | Added a GrammerIO file to deal with reading in a grammer and also writing out a grammer to a file

9 |
    10 |
  • Source Code 11 | 17 |
  • Functions 18 |
      19 |
    • Set functions ( Member, Union, Insertsion, Difference) 20 |
    • Reading in a grammer from a file 21 |
    • Parsing productions to get a ptr to the rule. (EX: "A Aa" -> "Aa") 22 |
    • Parsing a gramming into a set<char*> grammer[3], for V, A, P. 23 |
    • Output a grammer to a file, converting it back to how CFG normally look. 24 |
    • Compare Set, Display Set 25 |
    26 |
27 | back 28 | 29 | 30 | -------------------------------------------------------------------------------- /Chapter4/library/lib.h: -------------------------------------------------------------------------------- 1 | ../../Main/library/lib.h -------------------------------------------------------------------------------- /Chapter4/library/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "gramIO.h" 3 | #include "lib.h" 4 | 5 | 6 | using namespace std; 7 | int main(){ 8 | 9 | vector splitRule; 10 | 11 | set grammer[4]; 12 | set::iterator it; 13 | 14 | parseGrammer("grammer2.txt", grammer); 15 | for( it = grammer[RULES].begin(); it != grammer[RULES].end(); it++){ 16 | splitRule = splitProduction(*it); 17 | cout << flattenProductVector(splitRule) << "--" << endl; 18 | } 19 | 20 | /* parseGrammer("grammer.txt", grammer); 21 | parseGrammer("grammer.txt", grammer); 22 | parseGrammer("grammer.txt", grammer); 23 | parseGrammer("grammer.txt", grammer); 24 | parseGrammer("grammer.txt", grammer); 25 | parseGrammer("grammer.txt", grammer); 26 | parseGrammer("grammer.txt", grammer); 27 | parseGrammer("grammer.txt", grammer); 28 | parseGrammer("grammer.txt", grammer); 29 | parseGrammer("grammer.txt", grammer); 30 | parseGrammer("grammer.txt", grammer); 31 | parseGrammer("grammer.txt", grammer); 32 | parseGrammer("grammer.txt", grammer); 33 | parseGrammer("grammer.txt", grammer); 34 | parseGrammer("grammer.txt", grammer); 35 | parseGrammer("grammer.txt", grammer); 36 | parseGrammer("grammer.txt", grammer); 37 | parseGrammer("grammer.txt", grammer); */ 38 | } 39 | -------------------------------------------------------------------------------- /Chapter4/library/test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlas-2192/Language-Algorithms/7c7c47ae661f6fed94347eacfa253395bc3a3e43/Chapter4/library/test -------------------------------------------------------------------------------- /Chapter4/main/chap4.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // remove recusive start symbols 4 | void alg4_1(char* pathIn, char* pathOut); 5 | 6 | // Remove lambda rules 7 | void alg4_2(char* pathIn, char* pathOut); 8 | 9 | // Remove chain rules 10 | void alg4_3(char* pathIn, char* pathOut); 11 | 12 | // Generate strings that derive terminal, remove ones that dont 13 | void alg4_4_2(char* pathIn, char* pathOut); 14 | 15 | // Remove un-reachable productions 16 | void alg4_4_4(char* pathIn, char* pathOut); 17 | 18 | // Chomsky Normal Form 19 | void alg4_5(char* pathIn, char* pathOut); 20 | 21 | // CYK Algorithm 22 | void alg4_6(char* pathIn, char* pathOut, char* input); 23 | 24 | // Removal of Direct Left Recursion 25 | void alg4_7(char* pathIn, char* pathOut); 26 | void alg4_7_GNF(std::set* grammer, char* var); 27 | 28 | //Greibach Normal Form 29 | void alg4_8(char* pathIn, char* pathOut); 30 | -------------------------------------------------------------------------------- /Chapter4/main/chap4.h.txt: -------------------------------------------------------------------------------- 1 | chap4.h -------------------------------------------------------------------------------- /Chapter4/main/gramIO.h: -------------------------------------------------------------------------------- 1 | ../library/gramIO.h -------------------------------------------------------------------------------- /Chapter4/main/gramLib.h: -------------------------------------------------------------------------------- 1 | ../library/gramLib.h -------------------------------------------------------------------------------- /Chapter4/main/grammer1.txt: -------------------------------------------------------------------------------- 1 | A -> Aa | b 2 | -------------------------------------------------------------------------------- /Chapter4/main/grammer2.txt: -------------------------------------------------------------------------------- 1 | A -> Aa | Ab | b | c 2 | -------------------------------------------------------------------------------- /Chapter4/main/grammer3.txt: -------------------------------------------------------------------------------- 1 | S -> AB | $ 2 | A -> CB | CBZ | a | aZ 3 | B -> AB | b 4 | C -> AC | c 5 | Z -> BZ | B 6 | -------------------------------------------------------------------------------- /Chapter4/main/grammer3Out.txt: -------------------------------------------------------------------------------- 1 | S -> $ | aB | aZ1B | aZB | aZZ1B | cBB | cBZ1B | cBZB | cBZZ1B 2 | C -> c | aC | aZ1C | aZC | aZZ1C | cBC | cBZ1C | cBZC | cBZZ1C 3 | Z -> bZ | aBZ | aZ1BZ | aZBZ | aZZ1BZ | cBBZ | cBZ1BZ | cBZBZ | cBZZ1BZ | b | aB | aZ1B | aZB | aZZ1B | cBB | cBZ1B | cBZB | cBZZ1B 4 | A -> a | aZ1 | aZ | aZZ1 | cB | cBZ1 | cBZ | cBZZ1 5 | B -> b | aB | aZ1B | aZB | aZZ1B | cBB | cBZ1B | cBZB | cBZZ1B 6 | Z1 -> cBZ1 | aCBZ1 | aZ1CBZ1 | aZCBZ1 | aZZ1CBZ1 | cBCBZ1 | cBZ1CBZ1 | cBZCBZ1 | cBZZ1CBZ1 | cB | aCB | aZ1CB | aZCB | aZZ1CB | cBCB | cBZ1CB | cBZCB | cBZZ1CB | cBZZ1 | aCBZZ1 | aZ1CBZZ1 | aZCBZZ1 | aZZ1CBZZ1 | cBCBZZ1 | cBZ1CBZZ1 | cBZCBZZ1 | cBZZ1CBZZ1 | cBZ | aCBZ | aZ1CBZ | aZCBZ | aZZ1CBZ | cBCBZ | cBZ1CBZ | cBZCBZ | cBZZ1CBZ 7 | -------------------------------------------------------------------------------- /Chapter4/main/grammerA.txt: -------------------------------------------------------------------------------- 1 | S -> A0B0 | A0T0 2 | X -> A0B0 | A0T0 3 | A0 -> a 4 | B0 -> b 5 | T0 -> XB0 6 | -------------------------------------------------------------------------------- /Chapter4/main/grammerB.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlas-2192/Language-Algorithms/7c7c47ae661f6fed94347eacfa253395bc3a3e43/Chapter4/main/grammerB.pdf -------------------------------------------------------------------------------- /Chapter4/main/grammerB.txt: -------------------------------------------------------------------------------- 1 | S -> 2 | A0 -> 3 | X -> 4 | B0 -> 5 | T0 -> 6 | -------------------------------------------------------------------------------- /Chapter4/main/grammers: -------------------------------------------------------------------------------- 1 | ../grammers/ -------------------------------------------------------------------------------- /Chapter4/main/grammmer3.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlas-2192/Language-Algorithms/7c7c47ae661f6fed94347eacfa253395bc3a3e43/Chapter4/main/grammmer3.txt -------------------------------------------------------------------------------- /Chapter4/main/main.cpp: -------------------------------------------------------------------------------- 1 | #include "gramLib.h" 2 | #include "gramIO.h" 3 | #include "chap4.h" 4 | 5 | using namespace std; 6 | int main(){ 7 | 8 | 9 | char gramIn[30] = "grammers/grammerA.txt"; 10 | 11 | char gramOutA[30] = "grammer3.txt"; 12 | char gramOutB[30] = "grammer3Out.txt"; 13 | 14 | int i = 0; 15 | 16 | // char* test[10] = {"a", "aa", "aab", "baa", "aabb", "bbaa", "bbbaaa", "aaabbb", "abba", "bababa"}; 17 | 18 | while(i++ < 1 ){ 19 | alg4_8(gramOutA, gramOutB);//, test[i++]); 20 | } 21 | 22 | /* 23 | alg4_1(gramOutA, gramOutB); 24 | alg4_2(gramOutB, gramOutA); 25 | alg4_3(gramOutA, gramOutB); 26 | alg4_4_2(gramOutB, gramOutA); 27 | alg4_4_4(gramOutA, gramOutB);*/ 28 | // alg4_3(gramOutA, gramOutB); 29 | // alg4_4_2(gramOutA, gramOutB); 30 | // alg4_4_4(gramOutA, gramOutB); 31 | // *(gramOutA+10) += 1; 32 | // *(gramIn+16) += 1; 33 | //} 34 | 35 | // alg4_1("testGramer.txt", gramOutA); 36 | 37 | // alg4_2(gramOutA, gramOutB); 38 | // alg4_2(gramOutA, gramOutB); 39 | // alg4_2(gramOutA, gramOutB); 40 | /* *(gramOutA + 10) += 1; 41 | alg4_3(gramOutB, gramOutA); 42 | *(gramOutB + 10) += 1; 43 | alg4_4_2(gramOutA, gramOutB); 44 | *(gramOutA + 10) += 1; 45 | alg4_4_4(gramOutB, gramOutA); */ 46 | cout << gramOutA << endl; 47 | cout << "WORKED" << endl; 48 | while(1); 49 | } 50 | 51 | 52 | -------------------------------------------------------------------------------- /Chapter4/main/makefile: -------------------------------------------------------------------------------- 1 | OBJS = $(MAIN).o alg4_1.o alg4_2.o alg4_3.o alg4_4_2.o alg4_4_4.o alg4_5.o alg4_6.o alg4_7.o alg4_8.o latexTable.o lib.o gramLib.o grammerIO.o 2 | MAIN = main 3 | 4 | all: clean compile 5 | 6 | compile: $(OBJS) 7 | g++ $(OBJS) -o test 8 | 9 | $(MAIN).o: 10 | g++ -c $(MAIN).cpp 11 | 12 | alg4_1.o: 13 | g++ -c ../alg4_1/alg4_1.cpp 14 | 15 | alg4_2.o: 16 | g++ -c ../alg4_2/alg4_2.cpp 17 | 18 | alg4_3.o: 19 | g++ -c ../alg4_3/alg4_3.cpp 20 | 21 | alg4_4_2.o: 22 | g++ -c ../alg4_4/4_4_2/alg4_4_2.cpp 23 | 24 | alg4_4_4.o: 25 | g++ -c ../alg4_4/4_4_4/alg4_4_4.cpp 26 | 27 | alg4_5.o: 28 | g++ -c ../alg4_5/alg4_5.cpp 29 | 30 | alg4_6.o: 31 | g++ -c ../alg4_6/alg4_6.cpp 32 | 33 | alg4_7.o: 34 | g++ -c ../alg4_7/alg4_7.cpp 35 | 36 | alg4_8.o: 37 | g++ -c ../alg4_8/alg4_8.cpp 38 | 39 | latexTable.o: 40 | g++ -c ../alg4_6/latexTable.cpp 41 | 42 | lib.o: 43 | g++ -c ../../Main/library/lib.cpp 44 | 45 | gramLib.o: 46 | g++ -c ../library/gramLib.cpp 47 | 48 | grammerIO.o: 49 | g++ -c ../library/grammerIO.cpp 50 | 51 | remove: 52 | rm $(MAIN).o 53 | 54 | clean: 55 | rm -rf *o compile 56 | -------------------------------------------------------------------------------- /Chapter4/main/test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlas-2192/Language-Algorithms/7c7c47ae661f6fed94347eacfa253395bc3a3e43/Chapter4/main/test -------------------------------------------------------------------------------- /Chapter4/main/testGramer.txt: -------------------------------------------------------------------------------- 1 | S -> aS | bS | B 2 | B -> bb | C | $ 3 | C -> cC | $ 4 | -------------------------------------------------------------------------------- /Chapter4/main/tmp.txt: -------------------------------------------------------------------------------- 1 | A -> Aa | Ab | b | c 2 | -------------------------------------------------------------------------------- /Chapter5_6/alg5_6/alg5_6.cpp: -------------------------------------------------------------------------------- 1 | #include "finStateIO.h" 2 | #include "finLib.h" 3 | #include "lib.h" 4 | 5 | void alg5_6(char* pathIn, char* pathOut); 6 | void removeNonDeterminism(std::set* finiteState); 7 | void finalStates(std::set Q, std::set* finiteState); 8 | char* getY(char* letter, std::set statesX, std::set* finiteState); 9 | char* makeNewTransition(char* state, char* letter, char* state2); 10 | bool noArc(std::set states, std::set alphabet, std::set transitions); 11 | bool transitionExist(char* state, char* letter, std::set transitions); 12 | 13 | std::set inputTransitionFunction(char* state, char* letter, std::set* finiteState); 14 | std::set lambdaClosure(char* tran, std::set transitions); 15 | std::set canReachLetter(char* letter, std::set reach, std::set transitions); 16 | 17 | using namespace std; 18 | /*int main(){ 19 | 20 | alg5_6("dfa.txt", "dfaOut.txt"); 21 | 22 | }*/ 23 | 24 | 25 | 26 | 27 | 28 | void alg5_6(char* pathIn, char* pathOut){ 29 | 30 | set finiteState[4]; 31 | parseFiniteState(pathIn, finiteState); 32 | 33 | //displaySet(inputTransitionFunction("q1", "b", finiteState)); 34 | 35 | // displaySet(finiteState[TRANSITIONS]); 36 | 37 | 38 | removeNonDeterminism(finiteState); 39 | 40 | outputFiniteState(pathOut, finiteState); 41 | 42 | 43 | freeCont(finiteState[0]); 44 | freeCont(finiteState[1]); 45 | freeCont(finiteState[2]); 46 | freeCont(finiteState[3]); 47 | } 48 | 49 | 50 | 51 | 52 | /* Construction of DM, a DFA Equivalent to NFA-Lambda M 53 | 54 | input: an NFA-Lambda M = {Q, E, d, q0, F} 55 | 56 | 1. init Q' to lambda-closure(q0) 57 | 2. repeat 58 | 2.1. IF there is a noda X (exist in) Q' and a symbol a (exist in) E with no arc 59 | leaving X labeled a, THEN 60 | 2.1.1. let Y = U inputTransitionFunction(qi, a) where qi (exist in) X 61 | 2.1.2. IF Y (does not exist in) Q', then set Q' := Q' U{Y} 62 | 2.1.3. add an arc from X to Y labeled a 63 | else done := true 64 | until done 65 | 66 | 67 | */ 68 | 69 | 70 | void removeNonDeterminism(std::set* finiteState){ 71 | 72 | set Q = lambdaClosure((char*)"q0", finiteState[TRANSITIONS]); 73 | set tmpSet; 74 | set statesX; 75 | set::iterator X = Q.begin(); 76 | set::iterator itAlph; 77 | char* Y; 78 | char* newTran; 79 | bool done = false; 80 | 81 | 82 | 83 | do{ 84 | if( noArc(Q, finiteState[ALPHABET], tmpSet) && X != Q.end()){ 85 | statesX = parseStateString(*X); 86 | for(itAlph = finiteState[ALPHABET].begin(); itAlph != finiteState[ALPHABET].end(); itAlph++){ 87 | Y = getY(*itAlph, statesX, finiteState); 88 | newTran = makeNewTransition(*X, *itAlph, Y); 89 | insertIntoSet(Q, Y); 90 | insertIntoSet(tmpSet, newTran); 91 | } 92 | freeCont(statesX); 93 | ++X; 94 | } 95 | else{ 96 | done = true; 97 | } 98 | 99 | }while(!done); 100 | 101 | freeCont(finiteState[TRANSITIONS]); 102 | finiteState[TRANSITIONS].clear(); 103 | unionSet(finiteState[TRANSITIONS], tmpSet); 104 | 105 | finalStates(Q, finiteState); 106 | } 107 | 108 | void finalStates(set Q, set* finiteState){ 109 | 110 | set newFinalStates; 111 | set splitState; 112 | set::iterator itState; 113 | set::iterator it; 114 | 115 | for( itState = Q.begin(); itState != Q.end(); itState++){ 116 | splitState = parseStateString(*itState); 117 | for( it = splitState.begin(); it != splitState.end(); it++){ 118 | if( member( finiteState[FINAL], *it ) ){ 119 | insertIntoSet(newFinalStates, *itState); 120 | } 121 | } 122 | freeCont(splitState); 123 | } 124 | 125 | freeCont(finiteState[FINAL]); 126 | finiteState[FINAL].clear(); 127 | unionSet(finiteState[FINAL], newFinalStates); 128 | } 129 | 130 | 131 | 132 | char* makeNewTransition(char* state1, char* letter, char* state2){ 133 | 134 | char* newTran = new char[MAX_TRAN_SIZE+1]; 135 | 136 | if( *state2){ 137 | newTran = newTransition(state1, letter, state2); 138 | } 139 | else{ 140 | if(*state1){ 141 | newTran = newTransition(state1, letter, (char*)EMPTY_SET); 142 | } 143 | else{ 144 | newTran = newTransition((char*)EMPTY_SET, letter, (char*)EMPTY_SET); 145 | } 146 | } 147 | 148 | return newTran; 149 | } 150 | 151 | char* getY( char* letter, set statesX, set* finiteState){ 152 | 153 | set Y; 154 | char* strY; 155 | set::iterator itState; 156 | 157 | 158 | for( itState = statesX.begin(); itState != statesX.end(); itState++){ 159 | unionSet(Y, inputTransitionFunction(*itState, letter, finiteState)); 160 | } 161 | strY = convertSetToString(Y); 162 | freeCont(Y); 163 | return strY; 164 | } 165 | // Returns true if it is not a DFA yet, hence that there is a state 166 | // that does not have an arc for all the alphabet letters 167 | bool noArc(set states, set alphabet, set transitions){ 168 | 169 | set::iterator itState; 170 | set::iterator itAlph; 171 | 172 | for( itState = states.begin(); itState != states.end(); itState++){ 173 | for( itAlph = alphabet.begin(); itAlph != alphabet.end(); itAlph++){ 174 | if(!transitionExist(*itState, *itAlph, transitions)){ 175 | return true; 176 | } 177 | } 178 | } 179 | return false; 180 | } 181 | 182 | // Finds a trasition for the given state a letter, if none exist return false 183 | bool transitionExist(char* state, char* letter, set transitions){ 184 | vector splitTran; 185 | set::iterator itTran; 186 | 187 | 188 | for( itTran = transitions.begin(); itTran != transitions.end(); itTran++){ 189 | splitTran = splitTransition(*itTran); 190 | if( strcmp(state, splitTran[0]) == 0 && strcmp(letter, splitTran[1]) == 0){ 191 | return true; 192 | } 193 | 194 | delete splitTran[2]; 195 | delete splitTran[1]; 196 | delete splitTran[0]; 197 | 198 | } 199 | 200 | return false; 201 | 202 | 203 | } 204 | // ###################### Input Transition Function ################################## 205 | /* 206 | 207 | t(qi, a) = U lambdaClosure(d(qj,a)), qj (exist in) lambdaClosure(qi) 208 | 209 | */ 210 | set inputTransitionFunction(char* state, char* letter, set* finiteState){ 211 | 212 | set lambdaSet; 213 | set reachable; 214 | set::iterator itState; 215 | 216 | 217 | lambdaSet = lambdaClosure(state, finiteState[TRANSITIONS]); 218 | 219 | unionSet(reachable, canReachLetter(letter, lambdaSet, finiteState[TRANSITIONS])); 220 | 221 | freeCont(lambdaSet); 222 | 223 | return reachable; 224 | } 225 | 226 | // What qi can reach with out processing any chars 227 | // Lambda Closure 228 | set lambdaClosure(char* state, set transitions){ 229 | 230 | vector splitTran; 231 | set::iterator itTran; 232 | set reachable; 233 | char* newState; 234 | int size; 235 | 236 | newState = new char[MAX_STATE_SIZE+1]; 237 | strncpy(newState, state, MAX_STATE_SIZE); 238 | insertIntoSet(reachable, newState); 239 | 240 | for( itTran = transitions.begin(); itTran != transitions.end(); itTran++){ 241 | splitTran = splitTransition(*itTran); 242 | if( strcmp(splitTran[1], NULL_CHAR) == 0 && strcmp(state, splitTran[0]) == 0){ 243 | unionSet(reachable, lambdaClosure(splitTran[2], transitions)); 244 | } 245 | //cout << splitTran[0] << ", " << splitTran[1] << " = " << splitTran[2] << endl; 246 | delete splitTran[0]; 247 | delete splitTran[1]; 248 | delete splitTran[2]; 249 | } 250 | 251 | 252 | return reachable; 253 | } 254 | 255 | set canReachLetter(char* letter, set lambdaSet, set transitions){ 256 | 257 | vector splitTran; 258 | set reachable; 259 | set::iterator itTran; 260 | set::iterator itReach; 261 | char* newState; 262 | int size; 263 | 264 | for( itReach = lambdaSet.begin(); itReach != lambdaSet.end(); itReach++){ 265 | for( itTran = transitions.begin(); itTran != transitions.end(); itTran++){ 266 | splitTran = splitTransition(*itTran); 267 | 268 | // U lambdaClosure(d(state, letter)), state (exist in) lambdaClosure of qi 269 | if(strcmp(*itReach, splitTran[0]) == 0 && strcmp(letter, splitTran[1]) == 0){ 270 | unionSet(reachable, lambdaClosure(splitTran[2], transitions)); 271 | } 272 | delete splitTran[0]; 273 | delete splitTran[1]; 274 | delete splitTran[2]; 275 | } 276 | } 277 | 278 | return reachable; 279 | } 280 | 281 | -------------------------------------------------------------------------------- /Chapter5_6/alg5_6/dfa.txt: -------------------------------------------------------------------------------- 1 | d(q0, a) = q0 2 | d(q0, a) = q1 3 | d(q0, a) = q2 4 | d(q1, b) = q1 5 | d(q2, c) = q2 6 | d(q2, $) = q1 7 | 8 | F{q1} 9 | -------------------------------------------------------------------------------- /Chapter5_6/alg5_6/dfa2.txt: -------------------------------------------------------------------------------- 1 | d(q0, a) = q1 2 | d(q0, a) = q0 3 | d(q1, b) = q1 4 | d(q1, b) = q2 5 | 6 | F{q2} 7 | -------------------------------------------------------------------------------- /Chapter5_6/alg5_6/dfa3.txt: -------------------------------------------------------------------------------- 1 | d(q0, a) = q1 2 | d(q0, b) = q0 3 | d(q0, c) = q0 4 | d(q0, d) = q0 5 | d(q1, b) = q1 6 | 7 | F{q1} 8 | -------------------------------------------------------------------------------- /Chapter5_6/alg5_6/dfaOut.txt: -------------------------------------------------------------------------------- 1 | d(q0, a) = q0q1q2 2 | d(q0, b) = 0 3 | d(q0, c) = 0 4 | d(q0q1q2, a) = q0q1q2 5 | d(q0q1q2, b) = q1 6 | d(q0q1q2, c) = q2q1 7 | d(0, a) = 0 8 | d(0, b) = 0 9 | d(0, c) = 0 10 | d(q1, a) = 0 11 | d(q1, b) = q1 12 | d(q1, c) = 0 13 | d(q2q1, a) = 0 14 | d(q2q1, b) = q1 15 | d(q2q1, c) = q1q2 16 | d(q1q2, a) = 0 17 | d(q1q2, b) = q1 18 | d(q1q2, c) = q2q1 19 | 20 | F{q0q1q2,q1,q2q1,q1q2} 21 | -------------------------------------------------------------------------------- /Chapter5_6/alg5_6/finLib.h: -------------------------------------------------------------------------------- 1 | ../library/finLib.h -------------------------------------------------------------------------------- /Chapter5_6/alg5_6/finStateIO.h: -------------------------------------------------------------------------------- 1 | ../library/finStateIO.h -------------------------------------------------------------------------------- /Chapter5_6/alg5_6/lib.h: -------------------------------------------------------------------------------- 1 | ../../Main/library/lib.h -------------------------------------------------------------------------------- /Chapter5_6/alg5_7/alg5_7.cpp: -------------------------------------------------------------------------------- 1 | #include "finStateIO.h" 2 | #include "finLib.h" 3 | #include "lib.h" 4 | #include 5 | 6 | //typedef std::vector > > setMatrix; 7 | 8 | void alg5_7(char* pathIn, char* pathOut); 9 | void determinEquialentStates(std::set* finiteState, char* pathOut); 10 | 11 | bool oneIsFinal(std::set final, char* qi, char* qj); 12 | 13 | void dist(int i, int j, int** D, setMatrix S); 14 | bool equalTransitions(char* qi, char* qj, int** D, std::set* finiteState); 15 | int* sameLetterTran(char* qi, char* qj, char* letter, std::set transitions); 16 | 17 | void addToS(std::set& S, int i, int j); 18 | 19 | int** initD(int size); 20 | setMatrix initS(int size); 21 | 22 | void freeContMatrix(setMatrix S, int size); 23 | 24 | void outputD(char* pathOut, int** D, int size); 25 | void displayD(int** D, int size); 26 | void displayS(setMatrix S, int size); 27 | 28 | 29 | 30 | using namespace std; 31 | /*int main(){ 32 | 33 | alg5_6("dfa.txt", "dfaOut.txt"); 34 | 35 | }*/ 36 | 37 | 38 | 39 | void alg5_7(char* pathIn, char* pathOut){ 40 | 41 | set finiteState[4]; 42 | parseFiniteState(pathIn, finiteState); 43 | 44 | determinEquialentStates(finiteState, pathOut); 45 | 46 | freeCont(finiteState[3]); 47 | freeCont(finiteState[2]); 48 | freeCont(finiteState[1]); 49 | freeCont(finiteState[0]); 50 | } 51 | 52 | 53 | 54 | 55 | /* Determination of Equivalnt States of DFA 56 | 57 | input: DFA M = (Q, E, d, q0, F) 58 | 59 | 1. (Initialization) 60 | for every pair of states qi and qj, i < j 61 | 1.1. D[i,j] := 0 62 | 1.2. S[i,j] := EMPTY_SET 63 | end for 64 | 2. for every pair i,j, i < j, if one of qi or qj is an accepting state and 65 | the other is not an accepting state, then set D[i,j] := 1 66 | 3. for every pair i,j, i < j, with D[i,j] = 0, do 67 | 3.1. if there exist an a (exist in) E such that d(qi, a) = qm, d(qj, a) = qn and 68 | D[m,n] = 1 or D[n.m] = 1, then DIST(i,j) 69 | 3.2. else for each a (exist in) E, do: Let d(qi, a) = qm and d(qj, a) = qn 70 | if m < n and [i.j] != [m,n], then add [i,j] to S[m,n] 71 | else if m > n and [i,j] != [n,m], then add [i,j] to S[n,m] 72 | end for 73 | 74 | DIST(i,j); 75 | begin 76 | D[i,j] := 1 77 | for all [m,n] (exist in) S[i,j], DIST(m,n) 78 | end 79 | 80 | */ 81 | 82 | 83 | void determinEquialentStates(set* finiteState, char* pathOut){ 84 | 85 | int stateSize = finiteState[STATES].size(); 86 | int** D = initD(stateSize); 87 | int* qnm; 88 | setMatrix S = initS(stateSize); 89 | 90 | set::iterator qi, qj, itAlph; 91 | 92 | int i,j; 93 | 94 | // For eery pair, first is i 95 | for( qi = finiteState[STATES].begin(); qi != finiteState[STATES].end(); qi++){ 96 | i = atoi(*(qi)+1); 97 | // This is the j pair 98 | for( qj = finiteState[STATES].begin(); qj != finiteState[STATES].end(); qj++){ 99 | j = atoi(*(qj)+1); 100 | // checks if i < j and if either qi or qj is an accepting state and the other is not 101 | if( i < j && oneIsFinal(finiteState[FINAL], *qi, *qj) ){ 102 | D[i][j] = 1; 103 | } 104 | } 105 | 106 | } 107 | 108 | // 3. for every pair i,j, i < j && D[i][j] == 0 109 | for( qi = finiteState[STATES].begin(); qi != finiteState[STATES].end(); qi++){ 110 | i = atoi(*(qi)+1); 111 | for( qj = finiteState[STATES].begin(); qj != finiteState[STATES].end(); qj++){ 112 | j = atoi(*(qj)+1); 113 | if( i < j && D[i][j] == 0 ){ 114 | // If there exist an a (exist in) E such that d(qi, a) = qm, d(qj, a) = qn and 115 | // D[m][n] == 1 or D[n][m] == 1 then DIST(i,j) 116 | if( equalTransitions(*qi, *qj, D, finiteState) ){ 117 | dist(i,j, D, S); 118 | } 119 | else{ 120 | // Else for each a (exist in) E do: Let d(qi, a) = qm and d(qj, a) = qn 121 | for(itAlph = finiteState[ALPHABET].begin(); itAlph != finiteState[ALPHABET].end(); itAlph++){ 122 | if( (qnm = sameLetterTran(*qi, *qj, *itAlph, finiteState[TRANSITIONS])) != NULL ){ 123 | // If m < n and [i,j] != [m,n] then add [i,j] to S[m,n] 124 | if( qnm[0] < qnm[1] && i != qnm[0] && j != qnm[1] ){ 125 | addToS(S[qnm[0]][qnm[1]], i, j); 126 | } 127 | // Else if m > n and [i,j] != [n,m] then add [i,j] to S[n,m] 128 | else if( qnm[0] > qnm[1] && i != qnm[1] && j != qnm[0]) { 129 | addToS(S[qnm[1]][qnm[0]], i, j); 130 | } 131 | delete(qnm); 132 | } 133 | 134 | } 135 | } 136 | 137 | } 138 | 139 | } 140 | } 141 | 142 | outputD(pathOut, D, stateSize); 143 | //displayD(D, stateSize); 144 | //displayS(S, stateSize); 145 | 146 | for( i = 0; i < stateSize; i++){ 147 | delete(D[i]); 148 | } 149 | delete(D); 150 | 151 | freeContMatrix(S, stateSize); 152 | } 153 | 154 | 155 | bool oneIsFinal(set final, char* qi, char* qj){ 156 | if( (member(final, qi) && !member(final, qj)) || (member(final, qj) && !member(final, qi))){ 157 | return true; 158 | } 159 | return false; 160 | } 161 | 162 | 163 | 164 | bool equalTransitions(char* qi, char* qj, int** D, set* finiteState){ 165 | int* qnm; 166 | 167 | set::iterator itAlph, itTran; 168 | 169 | for( itAlph = finiteState[ALPHABET].begin(); itAlph != finiteState[ALPHABET].end(); itAlph++){ 170 | if( (qnm = sameLetterTran(qi, qj, *itAlph, finiteState[TRANSITIONS])) != NULL){ 171 | if(D[qnm[0]][qnm[1]] == 1 || D[qnm[1]][qnm[0]] == 1){ 172 | delete(qnm); 173 | return true; 174 | } 175 | 176 | delete(qnm); 177 | } 178 | } 179 | return false; 180 | } 181 | 182 | int* sameLetterTran(char* qi, char* qj, char* letter, set transitions){ 183 | 184 | set::iterator it; 185 | vector splitTran; 186 | 187 | int* qnm = new int[2]; 188 | 189 | qnm[0] = -1; qnm[1] = -1; 190 | 191 | for( it = transitions.begin(); it != transitions.end(); it++){ 192 | splitTran = splitTransition(*it); 193 | if( (strncmp(qi, splitTran[0], MAX_TRAN_SIZE) == 0) && (strcmp(letter, splitTran[1]) == 0)) { 194 | qnm[0] = atoi(splitTran[2]+1); 195 | } 196 | if( (strncmp(qj, splitTran[0], MAX_TRAN_SIZE) == 0) && (strcmp(letter, splitTran[1]) == 0)) { 197 | qnm[1] = atoi(splitTran[2]+1); 198 | } 199 | freeCont(splitTran); 200 | } 201 | 202 | 203 | if( qnm[0] == -1 || qnm[1] == -1 || qnm[0] == qnm[1] ){ 204 | delete(qnm); 205 | return NULL; 206 | } 207 | 208 | return qnm; 209 | 210 | } 211 | 212 | 213 | 214 | void dist(int i, int j, int** D, setMatrix S){ 215 | 216 | set::iterator it; 217 | 218 | D[i][j] = 1; 219 | 220 | for( it = S[i][j].begin(); it != S[i][j].end(); it++){ 221 | //TO DO 222 | dist((*it)[0], (*it)[1], D, S); 223 | } 224 | 225 | } 226 | 227 | 228 | 229 | void addToS(set& S, int i, int j){ 230 | int* tmp = new int[2]; 231 | 232 | tmp[0] = i; 233 | tmp[1] = j; 234 | 235 | S.insert(tmp); 236 | } 237 | 238 | int** initD(int size){ 239 | 240 | int** D = new int*[size]; 241 | 242 | for( int i = 0; i < size; i++){ 243 | D[i] = new int[size]; 244 | for( int j = 0; j < size; j++){ 245 | // if( i < j ){ 246 | D[i][j] = 0; 247 | // } 248 | } 249 | 250 | } 251 | 252 | return D; 253 | 254 | } 255 | 256 | 257 | setMatrix initS(int size){ 258 | 259 | setMatrix S; 260 | 261 | S.resize(size); 262 | for(int i = 0; i < size; i++){ 263 | S[i].resize(size); 264 | for( int j = 0; j < size; j++){ 265 | if( i < j){ 266 | // S[i][j].insert(tmp); 267 | } 268 | } 269 | } 270 | 271 | return S; 272 | 273 | 274 | } 275 | 276 | 277 | void outputD(char* pathOut, int** D, int size){ 278 | 279 | char outputStream[MAX_FILE_SIZE] = ""; 280 | char* ptr = outputStream; 281 | 282 | for( int i = 0; i < size; i++){ 283 | for( int j = 0; j < size; j++){ 284 | if( i < j){ 285 | *(ptr++) = (char)(((int)'0')+D[i][j]); 286 | *(ptr++) = ' '; 287 | } 288 | else{ 289 | *(ptr++) = '-'; 290 | *(ptr++) = ' '; 291 | 292 | } 293 | } 294 | strncat(outputStream, "\n", 1); 295 | ptr++; 296 | } 297 | 298 | *(--ptr) = '\0'; 299 | 300 | sendOutputStream(pathOut, outputStream); 301 | } 302 | 303 | void displayD(int** D, int size){ 304 | 305 | for( int i = 0; i < size; i++){ 306 | for( int j = 0; j < size; j++){ 307 | if( i < j ){ 308 | cout << D[i][j]; 309 | } 310 | else{ 311 | cout << "-"; 312 | } 313 | } 314 | cout << endl; 315 | } 316 | } 317 | 318 | 319 | void displayS( setMatrix S, int size){ 320 | 321 | set::iterator it; 322 | 323 | for( int i = 0; i < size; i++){ 324 | 325 | for( int j = 0; j < size; j++){ 326 | if( i < j){ 327 | for( it = S[i][j].begin(); it != S[i][j].end(); it++){ 328 | cout << '(' << (*it)[0] << ',' << (*it)[1] << "),"; 329 | 330 | } 331 | cout << '\t'; 332 | } 333 | else{ 334 | cout << "-\t"; 335 | } 336 | } 337 | cout << endl; 338 | 339 | } 340 | } 341 | 342 | 343 | 344 | void freeContMatrix(setMatrix S, int size){ 345 | 346 | set::iterator it; 347 | 348 | for( int i = 0; i < size; i++){ 349 | for( int j = 0; j < size; j++){ 350 | for( it = S[i][j].begin(); it != S[i][j].end(); it++){ 351 | delete(*it); 352 | } 353 | } 354 | 355 | } 356 | 357 | 358 | 359 | } 360 | -------------------------------------------------------------------------------- /Chapter5_6/alg5_7/dfa.txt: -------------------------------------------------------------------------------- 1 | d(q0, a) = q1 2 | d(q0, b) = q4 3 | d(q1, a) = q2 4 | d(q1, b) = q3 5 | d(q2, a) = q7 6 | d(q2, b) = q7 7 | d(q3, a) = q7 8 | d(q3, b) = q3 9 | d(q4, a) = q5 10 | d(q4, b) = q6 11 | d(q5, a) = q7 12 | d(q5, b) = q7 13 | d(q6, a) = q7 14 | d(q6, b) = q6 15 | d(q7, a) = q7 16 | d(q7, b) = q7 17 | 18 | F{q1,q2,q3,q4,q5,q6} 19 | -------------------------------------------------------------------------------- /Chapter5_6/alg5_7/dfa2.txt: -------------------------------------------------------------------------------- 1 | d(q0, a) = q4 2 | d(q0, b) = q1 3 | d(q1, a) = q5 4 | d(q1, b) = q2 5 | d(q2, a) = q6 6 | d(q2, b) = q3 7 | d(q3, a) = q3 8 | d(q3, b) = q3 9 | d(q4, a) = q4 10 | d(q4, b) = q4 11 | d(q5, a) = q5 12 | d(q5, b) = q5 13 | d(q6, a) = q6 14 | d(q6, b) = q6 15 | 16 | F{q4,q5,q6} 17 | -------------------------------------------------------------------------------- /Chapter5_6/alg5_7/dfa3.txt: -------------------------------------------------------------------------------- 1 | d(q0, a) = q1 2 | d(q0, b) = q3 3 | d(q1, a) = q1 4 | d(q1, b) = q2 5 | d(q2, a) = q2 6 | d(q2, b) = q5 7 | d(q3, a) = q3 8 | d(q3, b) = q4 9 | d(q4, a) = q4 10 | d(q4, b) = q5 11 | d(q5, a) = q5 12 | d(q5, b) = q5 13 | 14 | F{q5} 15 | -------------------------------------------------------------------------------- /Chapter5_6/alg5_7/dfa5.txt: -------------------------------------------------------------------------------- 1 | d(q0, a) = q1 2 | d(q0, b) = q3 3 | d(q1, a) = q2 4 | d(q1, b) = q4 5 | d(q2, a) = q5 6 | d(q2, b) = q5 7 | d(q3, a) = q4 8 | d(q3, b) = q2 9 | d(q4, a) = q5 10 | d(q4, b) = q5 11 | d(q5, a) = q6 12 | d(q5, b) = q5 13 | d(q6, a) = q6 14 | d(q6, b) = q6 15 | 16 | F{q1,q3,q5,q6} 17 | -------------------------------------------------------------------------------- /Chapter5_6/alg5_7/dfaOut.txt: -------------------------------------------------------------------------------- 1 | d(q0, a) = q0q1q2 2 | d(q0, b) = 0 3 | d(q0, c) = 0 4 | d(q0q1q2, a) = q0q1q2 5 | d(q0q1q2, b) = q1 6 | d(q0q1q2, c) = q2q1 7 | d(0, a) = 0 8 | d(0, b) = 0 9 | d(0, c) = 0 10 | d(q1, a) = 0 11 | d(q1, b) = q1 12 | d(q1, c) = 0 13 | d(q2q1, a) = 0 14 | d(q2q1, b) = q1 15 | d(q2q1, c) = q2q1 16 | 17 | F{q0q1q2,q1,q2q1} 18 | -------------------------------------------------------------------------------- /Chapter5_6/alg5_7/finLib.h: -------------------------------------------------------------------------------- 1 | ../library/finLib.h -------------------------------------------------------------------------------- /Chapter5_6/alg5_7/finStateIO.h: -------------------------------------------------------------------------------- 1 | ../library/finStateIO.h -------------------------------------------------------------------------------- /Chapter5_6/alg5_7/lib.h: -------------------------------------------------------------------------------- 1 | ../../Main/library/lib.h -------------------------------------------------------------------------------- /Chapter5_6/alg6_2/alg6_2.cpp: -------------------------------------------------------------------------------- 1 | #include "finStateIO.h" 2 | #include "finLib.h" 3 | #include "lib.h" 4 | #include 5 | 6 | void convertFAtoRE(std::set* finiteState); 7 | 8 | void makeOneFinalState(std::set* finiteState); 9 | 10 | char* hasTransition(char* qi, char* qj, std::set transitions); 11 | 12 | void removeTransitions(std::set* finiteState); 13 | 14 | using namespace std; 15 | void alg6_2(char* pathIn, char* pathOut){ 16 | 17 | set finiteState[4]; 18 | parseFiniteState(pathIn, finiteState); 19 | 20 | convertFAtoRE(finiteState); 21 | 22 | 23 | outputFiniteState(pathOut, finiteState); 24 | 25 | 26 | freeCont(finiteState[3]); 27 | freeCont(finiteState[2]); 28 | freeCont(finiteState[1]); 29 | freeCont(finiteState[0]); 30 | } 31 | 32 | 33 | 34 | 35 | void convertFAtoRE(set* finiteState){ 36 | 37 | 38 | set removedStates; 39 | set::iterator i,j,k; 40 | char* wji, *wik, *wii, *newTran, *tmp; 41 | 42 | 43 | // wji = (char*)EMPTY_SET; 44 | // wik = EMPTY_SET; 45 | // wii = EMPTY_SET; 46 | 47 | if( finiteState[FINAL].size() > 1 ){ 48 | makeOneFinalState(finiteState); 49 | } 50 | 51 | for( i = finiteState[STATES].begin(); i != finiteState[STATES].end(); ++i){ 52 | if( strncmp( "q0", *i, 2) != 0 && !member(finiteState[FINAL], *i)){ 53 | for( j = finiteState[STATES].begin(); j != finiteState[STATES].end(); ++j){ 54 | if( j != i && !member(removedStates, *j) ){ 55 | for( k = finiteState[STATES].begin(); k != finiteState[STATES].end(); ++k){ 56 | if( k != i && !member(removedStates, *k) ){ 57 | if( (wji = hasTransition(*j, *i, finiteState[TRANSITIONS])) != EMPTY_SET && 58 | (wik = hasTransition(*i, *k, finiteState[TRANSITIONS])) != EMPTY_SET && 59 | (wii = hasTransition(*i, *i, finiteState[TRANSITIONS])) == EMPTY_SET){ 60 | 61 | 62 | tmp = new char[MAX_STATE_SIZE+1]; 63 | strncpy(tmp, wji, MAX_STATE_SIZE+1); 64 | strncat(tmp, wik, MAX_STATE_SIZE); 65 | 66 | newTran = newTransition(*j, tmp, *k); 67 | insertIntoSet(finiteState[TRANSITIONS], newTran); 68 | delete(tmp); 69 | delete(wji); 70 | delete(wik); 71 | 72 | } 73 | if( ((wji = hasTransition(*j, *i, finiteState[TRANSITIONS])) != EMPTY_SET && 74 | (wik = hasTransition(*i, *k, finiteState[TRANSITIONS])) != EMPTY_SET) && 75 | (wii = hasTransition(*i, *i, finiteState[TRANSITIONS])) != EMPTY_SET){ 76 | 77 | tmp = new char[MAX_STATE_SIZE+1]; 78 | strncpy(tmp, wji, MAX_STATE_SIZE+1); 79 | strncat(tmp, wii, MAX_STATE_SIZE); 80 | strncat(tmp, "*", 1); 81 | strncat(tmp, wik, MAX_STATE_SIZE); 82 | 83 | newTran = newTransition(*j, tmp, *k); 84 | 85 | insertIntoSet(finiteState[TRANSITIONS], newTran); 86 | delete(tmp); 87 | delete(wji); 88 | delete(wik); 89 | delete(wii); 90 | 91 | } 92 | } 93 | } 94 | } 95 | } 96 | removedStates.insert(*i); 97 | } 98 | 99 | } 100 | 101 | diffSet(finiteState[STATES], removedStates); 102 | removeTransitions(finiteState); 103 | } 104 | 105 | void makeOneFinalState(set* finiteState){ 106 | 107 | set::iterator itFinal; 108 | char* newFinal = new char[MAX_STATE_SIZE+1]; 109 | char* newTran; 110 | strncpy(newFinal, "q000", 5); 111 | 112 | for( itFinal = finiteState[FINAL].begin(); itFinal != finiteState[FINAL].end(); ++itFinal){ 113 | newTran = newTransition(*itFinal, (char*)NULL_CHAR, newFinal); 114 | finiteState[TRANSITIONS].insert(newTran); 115 | } 116 | 117 | freeCont(finiteState[FINAL]); 118 | finiteState[FINAL].clear(); 119 | finiteState[FINAL].insert(newFinal); 120 | finiteState[STATES].insert(newFinal); 121 | } 122 | 123 | char* hasTransition(char* qi, char* qj, set transitions){ 124 | 125 | set::iterator itTran; 126 | vector splitTran; 127 | 128 | for( itTran = transitions.begin(); itTran != transitions.end(); ++itTran){ 129 | 130 | splitTran = splitTransition(*itTran); 131 | 132 | if( strncmp( qi, splitTran[0], MAX_TRAN_SIZE) == 0 && strncmp( qj, splitTran[2], MAX_TRAN_SIZE) == 0 ){ 133 | delete(splitTran[0]); 134 | delete(splitTran[2]); 135 | return splitTran[1]; 136 | } 137 | else{ 138 | freeCont(splitTran); 139 | } 140 | } 141 | 142 | return (char*)EMPTY_SET; 143 | } 144 | 145 | 146 | void removeTransitions(set* finiteState){ 147 | 148 | set removedTran; 149 | set::iterator it; 150 | vector splitTran; 151 | 152 | for( it = finiteState[TRANSITIONS].begin(); it != finiteState[TRANSITIONS].end(); ++it){ 153 | splitTran = splitTransition(*it); 154 | 155 | if( member(finiteState[STATES], splitTran[0]) == 0 || member(finiteState[STATES], splitTran[2]) == 0 ){ 156 | removedTran.insert(*it); 157 | } 158 | freeCont(splitTran); 159 | } 160 | diffSet(finiteState[TRANSITIONS], removedTran); 161 | // freeCont(removedTran); 162 | } 163 | -------------------------------------------------------------------------------- /Chapter5_6/alg6_2/dfa.txt: -------------------------------------------------------------------------------- 1 | d(q0, a) = q1 2 | d(q0, b) = q4 3 | d(q1, a) = q2 4 | d(q1, b) = q3 5 | d(q2, a) = q7 6 | d(q2, b) = q7 7 | d(q3, a) = q7 8 | d(q3, b) = q3 9 | d(q4, a) = q5 10 | d(q4, b) = q6 11 | d(q5, a) = q7 12 | d(q5, b) = q7 13 | d(q6, a) = q7 14 | d(q6, b) = q6 15 | d(q7, a) = q7 16 | d(q7, b) = q7 17 | 18 | F{q1,q2,q3,q4,q5,q6} 19 | -------------------------------------------------------------------------------- /Chapter5_6/alg6_2/dfa5.txt: -------------------------------------------------------------------------------- 1 | d(q0, a) = q1 2 | d(q0, b) = q3 3 | d(q1, a) = q2 4 | d(q1, b) = q4 5 | d(q2, a) = q5 6 | d(q2, b) = q5 7 | d(q3, a) = q4 8 | d(q3, b) = q2 9 | d(q4, a) = q5 10 | d(q4, b) = q5 11 | d(q5, a) = q6 12 | d(q5, b) = q5 13 | d(q6, a) = q6 14 | d(q6, b) = q6 15 | 16 | F{q1,q3,q5,q6} 17 | -------------------------------------------------------------------------------- /Chapter5_6/alg6_2/dfaOut.txt: -------------------------------------------------------------------------------- 1 | d(q0, a) = q0q1q2 2 | d(q0, b) = 0 3 | d(q0, c) = 0 4 | d(q0q1q2, a) = q0q1q2 5 | d(q0q1q2, b) = q1 6 | d(q0q1q2, c) = q2q1 7 | d(0, a) = 0 8 | d(0, b) = 0 9 | d(0, c) = 0 10 | d(q1, a) = 0 11 | d(q1, b) = q1 12 | d(q1, c) = 0 13 | d(q2q1, a) = 0 14 | d(q2q1, b) = q1 15 | d(q2q1, c) = q2q1 16 | 17 | F{q0q1q2,q1,q2q1} 18 | -------------------------------------------------------------------------------- /Chapter5_6/alg6_2/finLib.h: -------------------------------------------------------------------------------- 1 | ../library/finLib.h -------------------------------------------------------------------------------- /Chapter5_6/alg6_2/finStateIO.h: -------------------------------------------------------------------------------- 1 | ../library/finStateIO.h -------------------------------------------------------------------------------- /Chapter5_6/alg6_2/lib.h: -------------------------------------------------------------------------------- 1 | ../../Main/library/lib.h -------------------------------------------------------------------------------- /Chapter5_6/library/dfa.txt: -------------------------------------------------------------------------------- 1 | d(q0, a) = q1 2 | d(q0, b) = q0 3 | d(q1, a) = q1 4 | d(q1, b) = q0 5 | 6 | F{q1,q2,q5} 7 | -------------------------------------------------------------------------------- /Chapter5_6/library/finLib.cpp: -------------------------------------------------------------------------------- 1 | 2 | //########################################## 3 | // -Author: Brandon Schaefer 4 | // -Created: 5/08/11 5 | // -File Name: lib.cpp 6 | //########################################## 7 | #include "finLib.h" 8 | #include "finStateIO.h" 9 | #include "lib.h" 10 | #include 11 | 12 | 13 | using namespace std; 14 | 15 | /* 16 | // Set Functions ------- Member, Union, Intersection, Difference 17 | bool member(set mySet, char* data){ 18 | 19 | set::iterator it; 20 | 21 | for( it = mySet.begin(); it != mySet.end(); it++){ 22 | if( strcmp( *it, data) == 0 ){ 23 | return 1; 24 | } 25 | } 26 | return 0; 27 | 28 | } 29 | 30 | void unionSet(set& setA, set setB){ 31 | 32 | set::iterator it; 33 | 34 | for( it = setB.begin(); it != setB.end(); it++){ 35 | // setA.insert(*it); 36 | insertIntoSet(setA, *it); 37 | } 38 | 39 | } 40 | 41 | 42 | void interSet(set& setA, set setB){ 43 | 44 | set::iterator it; 45 | set::iterator tmp; 46 | 47 | it = setA.begin(); 48 | 49 | while( it != setA.end() ){ 50 | if( !(member(setB, *it)) ){ 51 | tmp = it; 52 | ++it; 53 | setA.erase(tmp); 54 | } 55 | else{ 56 | ++it; 57 | } 58 | } 59 | } 60 | 61 | void diffSet(set& setA, set setB){ 62 | 63 | set::iterator it; 64 | set::iterator tmp; 65 | 66 | it = setA.begin(); 67 | 68 | while( it != setA.end()){ 69 | if( member( setB, *it) ){ 70 | tmp = it; 71 | ++it; 72 | setA.erase(tmp); 73 | } 74 | else{ 75 | ++it; 76 | } 77 | 78 | } 79 | } 80 | 81 | // ---- End of Set Functions 82 | 83 | 84 | 85 | // Takes a set and checks if the new data is already in the set 86 | void insertIntoSet(std::set& set, char* data){ 87 | 88 | if( !(member(set, data)) ){ 89 | set.insert(data); 90 | } 91 | else{ 92 | delete(data); 93 | } 94 | 95 | } 96 | 97 | 98 | 99 | void displaySet(set setA){ 100 | 101 | set::iterator it; 102 | 103 | for( it = setA.begin(); it != setA.end(); it++){ 104 | cout << *it << endl; 105 | } 106 | 107 | } 108 | 109 | 110 | bool compareSets( set setA, set setB ){ 111 | 112 | // check size of each first, its faster that way 113 | if( setA.size() == setB.size()){ 114 | 115 | set::iterator itA; 116 | set::iterator itB; 117 | 118 | for( itA = setA.begin(); itA != setA.end(); itA++){ 119 | if( member( setB, *itA ) == 0 ){ 120 | return false; 121 | } 122 | } 123 | return true; 124 | } 125 | return false; 126 | } 127 | 128 | 129 | 130 | 131 | bool isDigit( char digit ){ 132 | int ascii = (int)digit; 133 | if( ascii >= 48 && ascii <= 57 ) 134 | return true; 135 | return false; 136 | } 137 | 138 | 139 | bool isLowChar( char letter ){ 140 | int ascii = (int)letter; 141 | if( ascii >= 97 && ascii <= 122) 142 | return true; 143 | return false; 144 | } 145 | 146 | 147 | 148 | // return the size of the term or 0 if its false 149 | int isTerminal(char* term){ 150 | //checks if the first char is a letter 151 | int termSize = 0; 152 | if( isLowChar( *term ) || *term == *NULL_CHAR ){ 153 | term++; 154 | termSize++; 155 | while( isDigit( *term++ ) ){ 156 | termSize++; 157 | } 158 | } 159 | return termSize; 160 | } 161 | */ 162 | 163 | int isState(char* state){ 164 | int stateSize = 0; 165 | if( *state++ == 'q' || strncmp(state, EMPTY_SET, 1) == 0 ){ 166 | stateSize++; 167 | while( isDigit( *state++ )){ //|| strncmp(state, EMPTY_SET, 1) == 0 ){ 168 | stateSize++; 169 | } 170 | } 171 | 172 | return stateSize; 173 | } 174 | 175 | // d(state1, letter) = state2 176 | char* newTransition(char* state1, char* letter, char* state2){ 177 | char* newTran = new char[MAX_TRAN_SIZE+1]; 178 | 179 | strncpy(newTran, "d(\0", 3); 180 | strncat(newTran, state1, strlen(state1)); 181 | strncat(newTran, ", ", 2); 182 | strncat(newTran, letter, strlen(letter)); 183 | strncat(newTran, ") = ", 4); 184 | strncat(newTran, state2, strlen(state2)); 185 | 186 | return newTran; 187 | } 188 | 189 | 190 | vector splitTransition(char* transition){ 191 | 192 | vector vecTransition; 193 | char* newChar; 194 | int size; 195 | 196 | 197 | while( *transition != '(' && *transition ){ 198 | transition++; 199 | } 200 | 201 | 202 | 203 | // finds the first transition 204 | while( !(size = isState(transition)) && *transition ){ 205 | transition++; 206 | } 207 | 208 | 209 | if( size ){ 210 | newChar = new char[size+1]; 211 | strncpy(newChar, transition, size); 212 | *(newChar+size) = '\0'; 213 | vecTransition.push_back(newChar); 214 | transition+=size; 215 | } 216 | 217 | // Finds the alphabet its goes too 218 | while( !(size = isTerminal(transition)) && *transition){ 219 | transition++; 220 | } 221 | 222 | 223 | if( size ){ 224 | newChar = new char[size+1]; 225 | strncpy(newChar, transition, size); 226 | *(newChar+size) = '\0'; 227 | vecTransition.push_back(newChar); 228 | transition+=size; 229 | } 230 | 231 | 232 | // Findes the state that this transitions goes too. 233 | while( !(size = isState(transition)) && *transition ){ 234 | transition++; 235 | } 236 | 237 | if( size ){ 238 | newChar = new char[size+1]; 239 | strncpy(newChar, transition, size); 240 | *(newChar+size) = '\0'; 241 | vecTransition.push_back(newChar); 242 | transition+=size; 243 | } 244 | 245 | 246 | 247 | return vecTransition; 248 | } 249 | 250 | char* flattenSplitTransition(vector vecTransition){ 251 | 252 | char* transition = new char[MAX_TRAN_SIZE+1]; 253 | 254 | strncpy(transition, "d(\0", 3); 255 | 256 | strncat(transition, vecTransition[0], strlen(vecTransition[0])); 257 | strncat(transition, ", ", 2); 258 | strncat(transition, vecTransition[1], strlen(vecTransition[1])); 259 | strncat(transition, ") = ", 4); 260 | strncat(transition, vecTransition[2], strlen(vecTransition[2])); 261 | 262 | return transition; 263 | } 264 | 265 | char* convertSetToString(set setA){ 266 | char* newString = new char[MAX_TRAN_SIZE+1]; 267 | set::iterator it; 268 | *(newString) = '\0'; 269 | 270 | for(it = setA.begin(); it != setA.end(); it++){ 271 | strncat(newString, *it, strnlen(*it, MAX_STATE_SIZE)); 272 | } 273 | 274 | return newString; 275 | } 276 | 277 | set parseStateString(char* states){ 278 | 279 | set setStates; 280 | char* newState; 281 | int size; 282 | 283 | while((size = isState(states))){ 284 | newState = new char[MAX_STATE_SIZE+1]; 285 | strncpy(newState, states, size); 286 | *(newState+size) = '\0'; 287 | insertIntoSet(setStates, newState); 288 | states+=size; 289 | } 290 | 291 | return setStates; 292 | } 293 | 294 | 295 | 296 | 297 | -------------------------------------------------------------------------------- /Chapter5_6/library/finLib.h: -------------------------------------------------------------------------------- 1 | //########################################## 2 | // -Author: Brandon Schaefer 3 | // -Created: 5/08/11 4 | // -File Name: lib.h 5 | //########################################## 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #define EMPTY_SET "0" 13 | #define NULL_CHAR "$" 14 | 15 | typedef std::vector > > setMatrix; 16 | /* 17 | #ifndef __LIB_H 18 | #define __LIB_H 19 | 20 | // Basic Set Functions 21 | bool member(std::set setA, char* data); 22 | void unionSet(std::set& setA, std::set setB); 23 | void interSet(std::set& setA, std::set setB); 24 | void diffSet(std::set& setA, std::set setB); 25 | // --- End of set funcs 26 | 27 | 28 | void insertIntoSet(std::set& set, char* data); 29 | 30 | bool compareSets( std::set setA, std::set setB ); 31 | 32 | void displaySet(std::set setA); 33 | 34 | bool isDigit( char digit ); 35 | 36 | bool isLowChar( char letter ); 37 | 38 | // Both of these return 0 if no terminal or var is found 39 | // otherwise it returns the size of the term or var in the 40 | // char* 41 | 42 | int isTerminal( char* term ); 43 | int isVariable( char* var ); 44 | 45 | #endif 46 | 47 | */ 48 | 49 | 50 | int isState(char* state); 51 | 52 | // returns dynmically allocated memery. 53 | // d(state1, letter) = state2 54 | char* newTransition(char* state1, char* letter, char* state2); 55 | 56 | char* flattenSplitTransition(std::vector vecTranisition); 57 | std::vector splitTransition(char* transition); 58 | 59 | // Takes a set of states and converts it into a char* 60 | char* convertSetToString(std::set setA); 61 | 62 | // Takes a char* of states and converts it to a set. 63 | std::set parseStateString(char* states); 64 | 65 | void freeSet(std::set& setA); 66 | void freeVector(std::vector& vec); 67 | 68 | template 69 | inline void freeCont(T& cont){ 70 | 71 | typename T::iterator it; 72 | 73 | for( it = cont.begin(); it != cont.end(); it++){ 74 | delete(*it); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Chapter5_6/library/finStateIO.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | 8 | #define MAX_FILE_SIZE 512 9 | 10 | 11 | #define STATES 0 12 | #define ALPHABET 1 13 | #define TRANSITIONS 2 14 | #define FINAL 3 15 | 16 | #define MAX_TRAN_SIZE 40 17 | #define MAX_STATE_SIZE 8 18 | 19 | void outputFiniteState(char* outPath, std::set* finiteState); 20 | void sendOutputStream(char* pathOut, char* outputStream); 21 | 22 | 23 | void parseFiniteState(char* path, std::set* fininteState); 24 | 25 | 26 | -------------------------------------------------------------------------------- /Chapter5_6/library/finiteStateIO.cpp: -------------------------------------------------------------------------------- 1 | #include "finStateIO.h" 2 | #include "finLib.h" 3 | #include "lib.h" 4 | 5 | /* 6 | M = {Q, E, D, q0, F} 7 | Q :: finite set of states 8 | E :: alphabet 9 | D :: transition funcitons 10 | q0 :: start state 11 | F :: set of final or accepting states 12 | 13 | D is a total function such Q x E to Q 14 | meaning, (Q, E) to Q 15 | 16 | Examples: 17 | Q{ q0, q1, q2, ..., qn } 18 | E{ a,b,c,a23,v23 } 19 | D{ d(q0, a) = q1 20 | d(q0, b) = q0 21 | d(q1, a) = q1 22 | d(q1, b) = q0 } 23 | F{ q1 } 24 | 25 | */ 26 | 27 | void outputFiniteState( char* outPath, std::set* finitesState ); 28 | void sendOutputStream(char* path, char* outputStream); 29 | 30 | void parseFiniteState(char* path, std::set* finiteState); 31 | void parseLine(char* line, std::set* finiteState); 32 | 33 | void getStates(char* line, std::set& states); 34 | void getAlphabet(char* line, std::set& alphabet); 35 | bool getTransitions(char* line, std::set& transitions); 36 | void getFinalStates(char* line, std::set& final); 37 | 38 | int readInput(char* path, char* file); 39 | 40 | 41 | 42 | using namespace std; 43 | /*int main(){ 44 | 45 | set finiteState[4]; 46 | 47 | parseFiniteState("dfa.txt", finiteState); 48 | 49 | vector test = splitTransition(*(finiteState[TRANSITIONS].begin())); 50 | 51 | 52 | cout << test[0] << endl; 53 | cout << test[1] << endl; 54 | cout << test[2] << endl; 55 | cout << flattenSplitTransition(test) << endl; 56 | }*/ 57 | 58 | void outputFiniteState( char* outPath, set* finiteState){ 59 | 60 | set::iterator itTran; 61 | set::iterator itFinal; 62 | char outStream[MAX_FILE_SIZE] = ""; 63 | 64 | for( itTran = finiteState[TRANSITIONS].begin(); itTran != finiteState[TRANSITIONS].end(); itTran++){ 65 | strncat(outStream, *itTran, MAX_TRAN_SIZE); 66 | strncat(outStream, "\n", 1); 67 | } 68 | 69 | 70 | strncat(outStream, "\nF{", 3); 71 | for( itFinal = finiteState[FINAL].begin(); itFinal != finiteState[FINAL].end(); itFinal++){ 72 | strncat(outStream, *itFinal, MAX_STATE_SIZE); 73 | if( ++itFinal != finiteState[FINAL].end()){ 74 | strncat(outStream, ",", 1); 75 | } 76 | itFinal--; 77 | } 78 | 79 | strncat(outStream, "}\n", 2); 80 | 81 | sendOutputStream(outPath, outStream); 82 | } 83 | 84 | 85 | void sendOutputStream( char* path, char* outputStream ){ 86 | 87 | int size = strlen(outputStream); 88 | 89 | ofstream outfile( path ); 90 | if( outfile.is_open() && outfile.good()){ 91 | 92 | outfile.write(outputStream, size); 93 | } 94 | else{ 95 | cerr << "Error in opening file: " << path << endl; 96 | throw; 97 | } 98 | outfile.close(); 99 | } 100 | 101 | 102 | void parseFiniteState(char* path, set* finiteState){ 103 | 104 | char* p; 105 | char file[MAX_FILE_SIZE]; 106 | char* line; 107 | 108 | readInput(path, file); 109 | 110 | line = strtok_r(file, "\n", &p); 111 | 112 | while( line ){ 113 | parseLine(line, finiteState); 114 | line = strtok_r(NULL, "\n", &p); 115 | } 116 | } 117 | 118 | void parseLine(char* line, set* finiteState){ 119 | 120 | 121 | 122 | if( getTransitions(line, finiteState[TRANSITIONS])){ 123 | getStates(line, finiteState[STATES]); 124 | getAlphabet(line, finiteState[ALPHABET]); 125 | } 126 | else{ 127 | getFinalStates(line, finiteState[FINAL]); 128 | } 129 | 130 | } 131 | 132 | 133 | void getStates(char* line, std::set& states){ 134 | 135 | int size; 136 | char* newState; 137 | 138 | while( *line ){ 139 | 140 | if( (size = isState(line)) ){ 141 | newState = new char[size+1]; 142 | strncpy(newState, line, size); 143 | *(newState+size) = '\0'; 144 | insertIntoSet(states, newState); 145 | line+=size; 146 | } 147 | else{ 148 | line++; 149 | } 150 | 151 | } 152 | 153 | } 154 | 155 | 156 | void getAlphabet(char* line, std::set& alphabet){ 157 | 158 | int size; 159 | char* newAlph; 160 | 161 | while(*line != ',' && *line){ line++; } 162 | 163 | while( *line ){ 164 | if( *line != 'q' && (size = isTerminal(line)) && *line != *NULL_CHAR ){ 165 | newAlph = new char[size+1]; 166 | strncpy(newAlph, line, size); 167 | *(newAlph+size) = '\0'; 168 | insertIntoSet(alphabet, newAlph); 169 | line+=size; 170 | } 171 | else{ 172 | line++; 173 | } 174 | } 175 | 176 | } 177 | 178 | bool getTransitions(char* line, std::set& transitions){ 179 | 180 | char* newTran = new char[MAX_TRAN_SIZE+1]; 181 | 182 | if( *line != 'd' ) 183 | return false; 184 | 185 | strncpy(newTran, line, strlen(line)+1); 186 | 187 | insertIntoSet(transitions, newTran); 188 | 189 | return true; 190 | } 191 | 192 | void getFinalStates(char* line, std::set& final){ 193 | 194 | int size; 195 | char* newFinal; 196 | 197 | if( *line == 'F' ){ 198 | while( *line ){ 199 | if( (size = isState(line)) ){ 200 | newFinal = new char[size+1]; 201 | strncpy(newFinal, line, size); 202 | *(newFinal+size) = '\0'; 203 | insertIntoSet(final, newFinal); 204 | line+=size; 205 | } 206 | else{ 207 | line++; 208 | } 209 | } 210 | 211 | } 212 | } 213 | 214 | int readInput(char* path, char* file){ 215 | 216 | int length; 217 | ifstream is; 218 | 219 | is.open(path); 220 | 221 | if( is.is_open() && is.good() ){ 222 | is.seekg(0, ios::end); 223 | length = is.tellg(); 224 | is.seekg(0, ios::beg); 225 | 226 | is.read(file, length); 227 | } 228 | else{ 229 | 230 | cerr << "Bad file name: " << path << endl; 231 | } 232 | 233 | is.close(); 234 | *(file+length) = '\0'; 235 | return length; 236 | } 237 | -------------------------------------------------------------------------------- /Chapter5_6/library/lib.h: -------------------------------------------------------------------------------- 1 | ../../Main/library/lib.h -------------------------------------------------------------------------------- /Chapter5_6/main/chap5_6.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | //Remove non-determinism 5 | void alg5_6(char* pathIn, char* pathOut); 6 | 7 | //Determin equivalant states 8 | void alg5_7(char* pathIn, char* pathOut); 9 | 10 | //Finite State to a regular expression 11 | void alg6_2(char* pathIn, char* pathOut); 12 | -------------------------------------------------------------------------------- /Chapter5_6/main/dfa.txt: -------------------------------------------------------------------------------- 1 | d(q0, a) = q1 2 | d(q0, b) = q4 3 | d(q1, a) = q2 4 | d(q1, b) = q3 5 | d(q2, a) = q7 6 | d(q2, b) = q7 7 | d(q3, a) = q7 8 | d(q3, b) = q3 9 | d(q4, a) = q5 10 | d(q4, b) = q6 11 | d(q5, a) = q7 12 | d(q5, b) = q7 13 | d(q6, a) = q7 14 | d(q6, b) = q6 15 | d(q7, a) = q7 16 | d(q7, b) = q7 17 | 18 | F{q1,q2,q3,q4,q5,q6} 19 | -------------------------------------------------------------------------------- /Chapter5_6/main/dfa2.txt: -------------------------------------------------------------------------------- 1 | d(q0, a) = q2 2 | d(q0, b) = q0 3 | d(q0, b) = q1 4 | d(q1, a) = q2 5 | d(q1, b) = q1 6 | d(q2, a) = q1 7 | d(q2, b) = q0 8 | 9 | F{q2} 10 | -------------------------------------------------------------------------------- /Chapter5_6/main/finLib.h: -------------------------------------------------------------------------------- 1 | ../library/finLib.h -------------------------------------------------------------------------------- /Chapter5_6/main/finStateIO.h: -------------------------------------------------------------------------------- 1 | ../library/finStateIO.h -------------------------------------------------------------------------------- /Chapter5_6/main/here.txt: -------------------------------------------------------------------------------- 1 | - 0 1 2 | - - 1 3 | - - - -------------------------------------------------------------------------------- /Chapter5_6/main/lib.h: -------------------------------------------------------------------------------- 1 | ../../Main/library/lib.h -------------------------------------------------------------------------------- /Chapter5_6/main/main.cpp: -------------------------------------------------------------------------------- 1 | #include "chap5_6.h" 2 | #include "lib.h" 3 | #include "finLib.h" 4 | #include "finStateIO.h" 5 | 6 | using namespace std; 7 | int main(){ 8 | 9 | int i = 0; 10 | while(i++ < 1000){ 11 | alg5_7("dfa2.txt", "here.txt"); 12 | } 13 | cout << "--END--" << endl; 14 | 15 | // To Test for mem leaks. 16 | while(1); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /Chapter5_6/main/makefile: -------------------------------------------------------------------------------- 1 | OBJS = $(MAIN).o alg5_6.o alg5_7.o alg6_2.o lib.o finLib.o finiteStateIO.o 2 | MAIN = main 3 | 4 | all: clean compile 5 | 6 | compile: $(OBJS) 7 | g++ $(OBJS) -o test 8 | 9 | $(MAIN).o: 10 | g++ -c $(MAIN).cpp 11 | 12 | alg5_6.o: 13 | g++ -c ../alg5_6/alg5_6.cpp 14 | 15 | alg5_7.o: 16 | g++ -c ../alg5_7/alg5_7.cpp 17 | 18 | alg6_2.o: 19 | g++ -c ../alg6_2/alg6_2.cpp 20 | 21 | lib.o: 22 | g++ -c ../../Main/library/lib.cpp 23 | 24 | finLib.o: 25 | g++ -c ../library/finLib.cpp 26 | 27 | finiteStateIO.o: 28 | g++ -c ../library/finiteStateIO.cpp 29 | 30 | remove: 31 | rm $(MAIN).o 32 | 33 | clean: 34 | rm -rf *o compile 35 | -------------------------------------------------------------------------------- /Chapter5_6/main/test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlas-2192/Language-Algorithms/7c7c47ae661f6fed94347eacfa253395bc3a3e43/Chapter5_6/main/test -------------------------------------------------------------------------------- /Chapter5_6/main/test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | template 7 | void freeCont(T& cont); 8 | 9 | void test(); 10 | using namespace std; 11 | int main(){ 12 | 13 | int i = 0; 14 | 15 | while( i++ < 1){ 16 | test(); 17 | } 18 | 19 | 20 | while(1); 21 | //freeCont(test); 22 | 23 | } 24 | 25 | 26 | void test(){ 27 | 28 | cout << "test" << endl; 29 | vector test; 30 | char* tmp; 31 | /* 32 | for( int i = 0; i < 10; i++){ 33 | tmp = new char[10]; 34 | strncpy(tmp, "hello", 6); 35 | *(tmp+6) = ((char)i)+1; 36 | *(tmp+7) = '\0'; 37 | test.push_back(tmp); 38 | } 39 | 40 | */ 41 | } 42 | 43 | template 44 | void freeCont(T& cont){ 45 | 46 | typename T::iterator it; 47 | 48 | //cont.~T(); 49 | 50 | // Could use ++it, but not defined for all STL Containers 51 | for( it = cont.begin(); it != cont.end(); it++){ 52 | delete(*it); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Main/chap4.h: -------------------------------------------------------------------------------- 1 | ../Chapter4/main/chap4.h -------------------------------------------------------------------------------- /Main/chap5_6.h: -------------------------------------------------------------------------------- 1 | ../Chapter5_6/main/chap5_6.h -------------------------------------------------------------------------------- /Main/fa/alg5.6: -------------------------------------------------------------------------------- 1 | d(q0, a) = q0 2 | d(q0, a) = q1 3 | d(q0, a) = q2 4 | d(q1, b) = q1 5 | d(q2, c) = q2 6 | d(q2, $) = q1 7 | 8 | F{q1} 9 | -------------------------------------------------------------------------------- /Main/fa/alg5.7: -------------------------------------------------------------------------------- 1 | d(q0, a) = q1 2 | d(q0, b) = q4 3 | d(q1, a) = q2 4 | d(q1, b) = q3 5 | d(q2, a) = q7 6 | d(q2, b) = q7 7 | d(q3, a) = q7 8 | d(q3, b) = q3 9 | d(q4, a) = q5 10 | d(q4, b) = q6 11 | d(q5, a) = q7 12 | d(q5, b) = q7 13 | d(q6, a) = q7 14 | d(q6, b) = q6 15 | d(q7, a) = q7 16 | d(q7, b) = q7 17 | 18 | F{q1,q2,q3,q4,q5,q6} 19 | -------------------------------------------------------------------------------- /Main/fa/alg6.2: -------------------------------------------------------------------------------- 1 | d(q0, a) = q1 2 | d(q0, a) = q2 3 | d(q1, a) = q1 4 | d(q1, b) = q3 5 | d(q2, a) = q3 6 | d(q3, b) = q2 7 | 8 | F{q3} 9 | -------------------------------------------------------------------------------- /Main/gram/alg4.1: -------------------------------------------------------------------------------- 1 | S -> aS | AB | AC 2 | A -> aA | $ 3 | B -> bB | bS 4 | C -> cC | $ 5 | -------------------------------------------------------------------------------- /Main/gram/alg4.2: -------------------------------------------------------------------------------- 1 | S -> ACA 2 | A -> aAa | B | C 3 | B -> bB | b 4 | C -> cC | $ 5 | -------------------------------------------------------------------------------- /Main/gram/alg4.3: -------------------------------------------------------------------------------- 1 | S -> ACA | A | C | AC | AA | CA | $ 2 | A -> aAa | B | C | aa 3 | B -> bB | b 4 | C -> cC | c 5 | -------------------------------------------------------------------------------- /Main/gram/alg4.4.2: -------------------------------------------------------------------------------- 1 | S -> AC | BS | B 2 | A -> aA | aF 3 | B -> CF | b 4 | C -> cC | D 5 | D -> aD | BD | C 6 | E -> aA | BSA 7 | F -> bB | b 8 | -------------------------------------------------------------------------------- /Main/gram/alg4.4.4: -------------------------------------------------------------------------------- 1 | S -> BS | B 2 | A -> aA | aF 3 | B -> b 4 | E -> aA | BSA 5 | F -> bB | b 6 | -------------------------------------------------------------------------------- /Main/gram/alg4.5: -------------------------------------------------------------------------------- 1 | S -> aABC | a 2 | A -> aA | a 3 | B -> bcB | bc 4 | C -> cC | c 5 | -------------------------------------------------------------------------------- /Main/gram/alg4.6: -------------------------------------------------------------------------------- 1 | S -> AT | AB 2 | T -> XB 3 | X -> AT | AB 4 | A -> a 5 | B -> b 6 | -------------------------------------------------------------------------------- /Main/gram/alg4.7: -------------------------------------------------------------------------------- 1 | S -> Sa | Sab | bb | b 2 | -------------------------------------------------------------------------------- /Main/gram/alg4.8: -------------------------------------------------------------------------------- 1 | S -> $ | AB 2 | B -> AB | b 3 | C -> c | AC 4 | A -> aZ | CBZ | a | CB 5 | Z -> BZ | B 6 | -------------------------------------------------------------------------------- /Main/library/gramIO.h: -------------------------------------------------------------------------------- 1 | ../../Chapter4/library/gramIO.h -------------------------------------------------------------------------------- /Main/library/lib.cpp: -------------------------------------------------------------------------------- 1 | 2 | //########################################## 3 | // -Author: Brandon Schaefer 4 | // -Created: 5/08/11 5 | // -File Name: lib.cpp 6 | //########################################## 7 | #include "lib.h" 8 | #include "gramIO.h" 9 | 10 | 11 | using namespace std; 12 | 13 | // Set Functions ------- Member, Union, Intersection, Difference 14 | bool member(set mySet, char* data){ 15 | 16 | set::iterator it; 17 | 18 | for( it = mySet.begin(); it != mySet.end(); it++){ 19 | if( strcmp( *it, data) == 0 ){ 20 | return 1; 21 | } 22 | } 23 | return 0; 24 | 25 | } 26 | 27 | void unionSet(set& setA, set setB){ 28 | 29 | set::iterator it; 30 | 31 | for( it = setB.begin(); it != setB.end(); it++){ 32 | setA.insert(*it); 33 | // insertIntoSet(setA, *it); 34 | } 35 | 36 | } 37 | 38 | 39 | void interSet(set& setA, set setB){ 40 | 41 | set::iterator it; 42 | set::iterator tmp; 43 | 44 | it = setA.begin(); 45 | 46 | while( it != setA.end() ){ 47 | if( !(member(setB, *it)) ){ 48 | tmp = it; 49 | ++it; 50 | setA.erase(tmp); 51 | } 52 | else{ 53 | ++it; 54 | } 55 | } 56 | } 57 | 58 | void diffSet(set& setA, set setB){ 59 | 60 | set::iterator it; 61 | set::iterator tmp; 62 | 63 | it = setA.begin(); 64 | 65 | while( it != setA.end()){ 66 | if( member( setB, *it) ){ 67 | tmp = it; 68 | ++it; 69 | setA.erase(tmp); 70 | } 71 | else{ 72 | ++it; 73 | } 74 | 75 | } 76 | } 77 | 78 | // ---- End of Set Functions 79 | 80 | 81 | 82 | // Takes a set and checks if the new data is already in the set 83 | void insertIntoSet(std::set& set, char* data){ 84 | 85 | if( !(member(set, data)) ){ 86 | set.insert(data); 87 | } 88 | else{ 89 | delete(data); 90 | } 91 | 92 | } 93 | 94 | 95 | 96 | void displaySet(set setA){ 97 | 98 | set::iterator it; 99 | 100 | for( it = setA.begin(); it != setA.end(); it++){ 101 | cout << *it << endl; 102 | } 103 | 104 | } 105 | 106 | 107 | bool compareSets( set setA, set setB ){ 108 | 109 | // check size of each first, its faster that way 110 | if( setA.size() == setB.size()){ 111 | 112 | set::iterator itA; 113 | set::iterator itB; 114 | 115 | for( itA = setA.begin(); itA != setA.end(); itA++){ 116 | if( member( setB, *itA ) == 0 ){ 117 | return false; 118 | } 119 | } 120 | return true; 121 | } 122 | return false; 123 | } 124 | 125 | 126 | 127 | 128 | bool isDigit( char digit ){ 129 | int ascii = (int)digit; 130 | if( ascii >= 48 && ascii <= 57 ) 131 | return true; 132 | return false; 133 | } 134 | 135 | 136 | bool isLowChar( char letter ){ 137 | int ascii = (int)letter; 138 | if( ascii >= 97 && ascii <= 122) 139 | return true; 140 | return false; 141 | } 142 | 143 | 144 | 145 | // return the size of the term or 0 if its false 146 | int isTerminal(char* term){ 147 | //checks if the first char is a letter 148 | int termSize = 0; 149 | if( isLowChar( *term ) || *term == *NULL_CHAR ){ 150 | term++; 151 | termSize++; 152 | while( isDigit( *term++ ) ){ 153 | termSize++; 154 | } 155 | } 156 | return termSize; 157 | } 158 | 159 | void printTextFile(char* path){ 160 | // *4 because GNF worst case produces 4n more rules 161 | char file[MAX_FILE_SIZE*4]; 162 | 163 | readFile(path, file); 164 | cout << file << endl; 165 | } 166 | -------------------------------------------------------------------------------- /Main/library/lib.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define NULL_CHAR "$" 6 | 7 | bool isDigit(char); 8 | bool isLowChar(char); 9 | int isTerminal(char*); 10 | 11 | void displaySet(std::set); 12 | 13 | bool member(std::set, char*); 14 | bool compareSets(std::set , std::set ); 15 | 16 | void insertIntoSet(std::set& setA, char* str); 17 | 18 | void unionSet(std::set& , std::set ); 19 | void interSet(std::set& , std::set ); 20 | void diffSet(std::set& , std::set ); 21 | 22 | void printTextFile(char* path); 23 | 24 | /* 25 | readFile 26 | 27 | sendStream 28 | */ 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Main/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "library/lib.h" 7 | #include "chap4.h" 8 | #include "chap5_6.h" 9 | 10 | #define BUF 80 11 | 12 | void checkCommand(char* buf); 13 | 14 | char welcome[] = "\ 15 | \t _.-'''''-._\n\ 16 | \t .' _ _ '.\n\ 17 | \t / (o) (o) \\\n\ 18 | \t | |\n\ 19 | \t | \\ / |\n\ 20 | \t \\ '. .' /\n\ 21 | \t '. `'---'` .'\n\ 22 | \t '-._____.-'\n\n\ 23 | \tWelcome, to the implemention of the Context Free and\n\ 24 | Finite State Automata algorithms. If your stuck type :h or :help\n\n\ 25 | The algorithms are based of formal lanauge algorithms from the book:\n\ 26 | Language and Machines by Thomas A. Sudkamp\n"; 27 | 28 | char helpComm[] = "\ 29 | :help - to display this\n\ 30 | :quit OR :q OR CTRL + D OR CRTL + C - to quit\n\ 31 | :ls - to list the current files in dir\n\ 32 | :vim - to edit a file using vim\n\ 33 | :cat - displays a file\n\ 34 | ----------------------------------------\n\ 35 | These are all the algorithms, anything in brackets are the arguments\n\ 36 | alg4_1 \t--remove recursive start symbol\t\t-Page 105\n\ 37 | alg4_2 \t--remove lambda rules\t\t\t-Page 108\n\ 38 | alg4_3 \t--remove chain rules\t\t\t-Page 114\n\ 39 | alg4_4_2 \t--generate rules that derive terminals\t-Page 117\n\ 40 | alg4_4_4 \t--remove un-reachable rules\t\t-Page 119\n\ 41 | alg4_5 \t--convert to Chomsky Normal Form\t-Page 122\n\ 42 | alg4_6 \t--CYK algorithm\t\t\t\t-Page 126\n\ 43 | alg4_7 \t--removable of direct left recursion\t-Page 129\n\ 44 | alg4_8 \t--convert to Greibach Normal Form\t-Page 132\n\ 45 | alg5_6 \t\t\t--remove non-determinism\t\t-Page 172\n\ 46 | alg5_7 \t\t\t--determine equivalent states\t\t-Page 179\n\ 47 | alg6_2 \t\t\t--finite state to regular expression\t-Page 194\n"; 48 | 49 | using namespace std; 50 | int main(){ 51 | 52 | char* line; 53 | char buf[BUF]; 54 | 55 | cout << welcome << endl; 56 | 57 | cout << ">> "; 58 | while( (fgets(buf, BUF, stdin)) != NULL ){ 59 | checkCommand(buf); 60 | cout << ">> "; 61 | } 62 | 63 | /* 64 | alg4_1("../Chapter4/grammers/grammerA.txt", "here.txt"); 65 | alg4_2("../Chapter4/grammers/grammerA.txt", "here1.txt"); 66 | alg4_3("../Chapter4/grammers/grammerA.txt", "here2.txt"); 67 | alg4_4_2("../Chapter4/grammers/grammerA.txt", "here32.txt"); 68 | alg4_4_4("../Chapter4/grammers/grammerA.txt", "here3.txt"); 69 | alg4_5("../Chapter4/grammers/grammerA.txt", "here4.txt"); 70 | alg4_6("../Chapter4/grammers/grammerA.txt", "here5.txt", "aabb"); 71 | alg4_7("../Chapter4/grammers/grammerA.txt", "here6.txt"); 72 | alg4_8("../Chapter4/grammers/grammerA.txt", "here7.txt"); 73 | alg5_6("../Chapter5_6/alg5_6/dfa.txt", "here8.txt"); 74 | alg5_7("../Chapter5_6/alg5_6/dfa.txt", "here9.txt"); 75 | alg6_2("../Chapter5_6/alg5_6/dfa.txt", "here0.txt"); 76 | */ 77 | } 78 | 79 | void checkCommand(char* buf){ 80 | 81 | char* ptr, *p, *tmp; 82 | char command[BUF]; 83 | bool flag = true; 84 | vector splitCommand; 85 | 86 | ptr = strtok_r(buf, " ", &p); 87 | 88 | while( ptr ){ 89 | splitCommand.push_back(ptr); 90 | ptr = strtok_r(NULL, " \n", &p); 91 | } 92 | 93 | 94 | if( strncmp( buf, ":help", 5) == 0 || strncmp(buf, ":h", 2) == 0){ 95 | cout << helpComm << endl; 96 | } 97 | else if( strncmp( splitCommand[0], "alg", 3) == 0){ 98 | ptr = (splitCommand[0]+3); 99 | 100 | if( splitCommand.size() >= 3 ){ 101 | if( strncmp(ptr, "4_1", 3) == 0 ){ 102 | alg4_1(splitCommand[1], splitCommand[2]); 103 | } 104 | else if( strncmp(ptr, "4_2", 3) == 0 ){ 105 | alg4_2(splitCommand[1], splitCommand[2]); 106 | } 107 | else if( strncmp(ptr, "4_3", 3) == 0 ){ 108 | alg4_3(splitCommand[1], splitCommand[2]); 109 | } 110 | else if( strncmp(ptr, "4_4_2", 5) == 0 ){ 111 | alg4_4_2(splitCommand[1], splitCommand[2]); 112 | } 113 | else if( strncmp(ptr, "4_4_4", 5) == 0 ){ 114 | alg4_4_4(splitCommand[1], splitCommand[2]); 115 | } 116 | else if( strncmp(ptr, "4_5", 3) == 0 ){ 117 | alg4_5(splitCommand[1], splitCommand[2]); 118 | } 119 | else if( strncmp(ptr, "4_6", 3) == 0 && splitCommand.size() == 4){ 120 | alg4_6(splitCommand[1], splitCommand[2], splitCommand[3]); 121 | } 122 | else if( strncmp(ptr, "4_7", 3) == 0 ){ 123 | alg4_7(splitCommand[1], splitCommand[2]); 124 | } 125 | else if( strncmp(ptr, "4_8", 3) == 0 ){ 126 | alg4_8(splitCommand[1], splitCommand[2]); 127 | } 128 | else if( strncmp(ptr, "5_6", 3) == 0 ){ 129 | alg5_6(splitCommand[1], splitCommand[2]); 130 | } 131 | else if( strncmp(ptr, "5_7", 3) == 0 ){ 132 | alg5_7(splitCommand[1], splitCommand[2]); 133 | } 134 | else if( strncmp(ptr, "6_2", 3) == 0 ){ 135 | alg6_2(splitCommand[1], splitCommand[2]); 136 | } 137 | else{ 138 | cout << splitCommand[0] << " is not an algorithm or you gave incorrect params, please type :help to see the list" << endl; 139 | flag = false; 140 | } 141 | 142 | if( splitCommand.size() == 3 && flag){ 143 | cout << endl; 144 | printTextFile(splitCommand[2]); 145 | } 146 | else if( splitCommand.size() == 4 && flag){ 147 | cout << "A pdf has been produced called: " << splitCommand[2] << ".pdf" << endl; 148 | } 149 | } 150 | else{ 151 | cout << "To few arguments to run an algorithm, please type :h OR :help to get the arguments" << endl; 152 | } 153 | 154 | } 155 | else if( strncmp( buf, ":quit", 5) == 0 || strncmp( buf, ":q", 2) == 0 ){ 156 | cout << "haha you want to quit" << endl; 157 | exit(1); 158 | } 159 | else if( strncmp( buf, ":ls", 3) == 0){ 160 | strncpy( command, "ls --hide=*.o ", 15); 161 | if( splitCommand.size() == 2){ 162 | strcat(command, splitCommand[1]); 163 | } 164 | system(command); 165 | } 166 | else if( strncmp( buf, ":vim", 4) == 0 && splitCommand.size() == 2){ 167 | strncpy(command, "vim ", 5); 168 | strcat(command, splitCommand[1]); 169 | system(command); 170 | } 171 | else if( strncmp( buf, ":cat", 4) == 0 && splitCommand.size() == 2){ 172 | strncpy(command, "cat ", 5); 173 | strcat(command, splitCommand[1]); 174 | cout << endl; 175 | system(command); 176 | cout << endl; 177 | } 178 | else{ 179 | cout << "command not recognize, enter :h OR :help if your lost" << endl; 180 | } 181 | 182 | } 183 | -------------------------------------------------------------------------------- /Main/makefile: -------------------------------------------------------------------------------- 1 | OBJS = $(MAIN).o alg4_1.o alg4_2.o alg4_3.o alg4_4_2.o alg4_4_4.o alg4_5.o alg4_6.o alg4_7.o alg4_8.o latexTable.o gramLib.o grammerIO.o alg5_6.o alg5_7.o alg6_2.o lib.o finLib.o finiteStateIO.o 2 | MAIN = main 3 | NAME = shell 4 | 5 | all: clean compile 6 | 7 | again: rmMain $(MAIN).o reMake 8 | 9 | compile: $(OBJS) 10 | g++ $(OBJS) -o $(NAME) 11 | 12 | reMake: 13 | g++ *.o -o $(NAME) 14 | 15 | $(MAIN).o: 16 | g++ -c $(MAIN).cpp 17 | 18 | alg4_1.o: 19 | g++ -c ../Chapter4/alg4_1/alg4_1.cpp 20 | 21 | alg4_2.o: 22 | g++ -c ../Chapter4/alg4_2/alg4_2.cpp 23 | 24 | alg4_3.o: 25 | g++ -c ../Chapter4/alg4_3/alg4_3.cpp 26 | 27 | alg4_4_2.o: 28 | g++ -c ../Chapter4/alg4_4/4_4_2/alg4_4_2.cpp 29 | 30 | alg4_4_4.o: 31 | g++ -c ../Chapter4/alg4_4/4_4_4/alg4_4_4.cpp 32 | 33 | alg4_5.o: 34 | g++ -c ../Chapter4/alg4_5/alg4_5.cpp 35 | 36 | alg4_6.o: 37 | g++ -c ../Chapter4/alg4_6/alg4_6.cpp 38 | 39 | alg4_7.o: 40 | g++ -c ../Chapter4/alg4_7/alg4_7.cpp 41 | 42 | alg4_8.o: 43 | g++ -c ../Chapter4/alg4_8/alg4_8.cpp 44 | 45 | latexTable.o: 46 | g++ -c ../Chapter4/alg4_6/latexTable.cpp 47 | 48 | gramLib.o: 49 | g++ -c ../Chapter4/library/gramLib.cpp 50 | 51 | grammerIO.o: 52 | g++ -c ../Chapter4/library/grammerIO.cpp 53 | 54 | alg5_6.o: 55 | g++ -c ../Chapter5_6/alg5_6/alg5_6.cpp 56 | 57 | alg5_7.o: 58 | g++ -c ../Chapter5_6/alg5_7/alg5_7.cpp 59 | 60 | alg6_2.o: 61 | g++ -c ../Chapter5_6/alg6_2/alg6_2.cpp 62 | 63 | lib.o: 64 | g++ -c library/lib.cpp 65 | 66 | finLib.o: 67 | g++ -c ../Chapter5_6/library/finLib.cpp 68 | 69 | finiteStateIO.o: 70 | g++ -c ../Chapter5_6/library/finiteStateIO.cpp 71 | 72 | clean: 73 | rm -rf *o 74 | 75 | rmMain: 76 | rm -rf $(MAIN).o 77 | -------------------------------------------------------------------------------- /Main/shell: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atlas-2192/Language-Algorithms/7c7c47ae661f6fed94347eacfa253395bc3a3e43/Main/shell -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Formal Langauge Algorithms 2 | 3 | **Languages and Machines: An Introduction to the Theory of Computer Science (3rd Edition)** [Amazon](http://www.amazon.com/Languages-Machines-Introduction-Computer-Science/dp/0321322215) 4 | 5 | Download, then navigate to the main folder by: 6 | 7 | cd ~/Formal-Language-Algorithms/Main 8 | 9 | Then compile: 10 | 11 | make 12 | 13 | Then to run: 14 | 15 | ./shell 16 | 17 | The Help section in the from the shell program: 18 | 19 | :help - to display this 20 | :quit OR :q OR CTRL + D OR CRTL + C - to quit 21 | :ls - to list the current files in dir 22 | :vim - to edit a file using vim 23 | :cat - displays a file 24 | ---------------------------------------- 25 | These are all the algorithms, anything in brackets are the arguments 26 | alg4_1 --remove recursive start symbol -Page 105 27 | alg4_2 --remove lambda rules -Page 108 28 | alg4_3 --remove chain rules -Page 114 29 | alg4_4_2 --generate rules that derive terminals -Page 117 30 | alg4_4_4 --remove un-reachable rules -Page 119 31 | alg4_5 --convert to Chomsky Normal Form -Page 122 32 | alg4_6 --CYK algorithm -Page 126 33 | alg4_7 --removable of direct left recursion -Page 129 34 | alg4_8 --convert to Greibach Normal Form -Page 132 35 | alg5_6 --remove non-determinism -Page 172 36 | alg5_7 --determine equivalent states -Page 179 37 | alg6_2 --finite state to regular expression -Page 194 38 | 39 | Also there are some built in grammars and finite states in: 40 | 41 | ~/Formal-Language-Algorithms/Main/gram/ 42 | ~/Formal-Language-Algorithms/Main/fa/ 43 | 44 | --------------------------------------------------------------------------------