From 84566c4ff6aa4ad14e5904a82a55deed75650992 Mon Sep 17 00:00:00 2001 From: Nathan Braswell Date: Wed, 3 Jul 2013 23:40:36 -0400 Subject: [PATCH] Extended the Regular Expression class to now support * and ? as well as +. Next up, perens and alternation --- src/RegEx.cpp | 61 ++++++++++++++++++++++++++++++++++++++++++---- src/RegExState.cpp | 15 +++++++++--- 2 files changed, 68 insertions(+), 8 deletions(-) diff --git a/src/RegEx.cpp b/src/RegEx.cpp index 42dda9a..47a1e56 100644 --- a/src/RegEx.cpp +++ b/src/RegEx.cpp @@ -2,14 +2,65 @@ RegEx::RegEx(std::string inPattern) { pattern = inPattern; - RegExState* current; + std::vector previousStates; + std::vector currentStates; begin = new RegExState(); - current = begin; + currentStates.push_back(begin); for (int i = 0; i < pattern.length(); i++) { - RegExState* next = new RegExState(pattern[i]); - current->addNext(next); - current = next; + switch (pattern[i]) { + case '*': + { + std::cout << "Star at " << i << " in " << pattern << std::endl; + for (std::vector::size_type j = 0; j < currentStates.size(); j++) + for (std::vector::size_type k = 0; k < currentStates.size(); k++) + currentStates[j]->addNext(currentStates[k]); + //add all previous states to current states to enable skipping over the starred item + currentStates.insert(currentStates.end(), previousStates.begin(), previousStates.end()); + } + break; + case '+': + { + std::cout << "Plus at " << i << " in " << pattern << std::endl; + //OtherThingy + //current->addNext(current); + for (std::vector::size_type j = 0; j < currentStates.size(); j++) + for (std::vector::size_type k = 0; k < currentStates.size(); k++) + currentStates[j]->addNext(currentStates[k]); + } + break; + case '?': + { + std::cout << "Question at " << i << " in " << pattern << std::endl; + //add all previous states to current states to enable skipping over the questioned item + currentStates.insert(currentStates.end(), previousStates.begin(), previousStates.end()); + } + break; + case '|': + std::cout << "Alternation at " << i << " in " << pattern << std::endl; + //alternation + break; + case '(': + std::cout << "Begin peren at " << i << " in " << pattern << std::endl; + //perentheses + break; + default: + { + std::cout << "Regular" << std::endl; + //Ahh, it's regular + RegExState* next = new RegExState(pattern[i]); + for (std::vector::size_type j = 0; j < currentStates.size(); j++) + currentStates[j]->addNext(next); + + previousStates.clear(); + previousStates.insert(previousStates.begin(), currentStates.begin(), currentStates.end()); + currentStates.clear(); + currentStates.push_back(next); + } + } } + //last one is goal state + for (std::vector::size_type i = 0; i < currentStates.size(); i++) + currentStates[i]->addNext(NULL); } RegEx::~RegEx() { diff --git a/src/RegExState.cpp b/src/RegExState.cpp index 2d8b86b..677063f 100644 --- a/src/RegExState.cpp +++ b/src/RegExState.cpp @@ -29,21 +29,30 @@ bool RegExState::characterIs(char inCharacter) { std::vector* RegExState::advance(char advanceCharacter) { std::vector* advanceStates = new std::vector(); for (std::vector::size_type i = 0; i < nextStates.size(); i++) { - if (nextStates[i]->characterIs(advanceCharacter)) + if (nextStates[i] != NULL && nextStates[i]->characterIs(advanceCharacter)) advanceStates->push_back(nextStates[i]); } return advanceStates; } bool RegExState::isGoal() { - return inner == NULL && nextStates.size() == 0; + //return inner == NULL && nextStates.size() == 0; + for (std::vector::size_type i = 0; i < nextStates.size(); i++) + if (nextStates[i] == NULL) + return true; + return false; } std::string RegExState::toString() { std::string string = ""; string += std::string("\"") + character + "\""; for (std::vector::size_type i = 0; i < nextStates.size(); i++) - string += "->" + nextStates[i]->toString() + " EC "; + if (nextStates[i] != this && nextStates[i] != NULL) + string += "->" + nextStates[i]->toString() + " EC "; + else if (nextStates[i] == NULL) + string += "-> GOAL "; + else + string += "->this"; //std::cout << "inner = " << inner << " nextStates size = " << nextStates.size() <