diff --git a/.gitignore b/.gitignore index 13a0149..0c527d6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ */build/ build/ +.vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json index 62e3861..36d0aeb 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,6 +3,9 @@ "xstring": "cpp", "iterator": "cpp", "ostream": "cpp", - "vector": "cpp" + "vector": "cpp", + "sstream": "cpp", + "queue": "cpp", + "set": "cpp" } } \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 8f4d0b4..8a10279 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,3 +22,6 @@ add_executable(main ${SOURCES_MAIN}) # 链接静态库 target_link_libraries(main PRIVATE LL nfa) + + + diff --git a/nfa/CMakeLists.txt b/nfa/CMakeLists.txt index cfc094e..7be2418 100644 --- a/nfa/CMakeLists.txt +++ b/nfa/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.10) project(nfa) # 收集所有的cpp源文件 -file(GLOB SOURCES "*.cpp") +file(GLOB SOURCES dfa.cpp nfa.cpp tool.cpp test_main.cpp) # 设置输出目录为 bin set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) @@ -12,3 +12,9 @@ add_library(nfa STATIC ${SOURCES}) # 添加头文件目录 target_include_directories(nfa PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) + +# 添加可执行文件 +add_executable(test_nfa test_main.cpp nfa) + +# 链接目标库 +target_link_libraries(test_nfa nfa) diff --git a/nfa/nfa.cpp b/nfa/nfa.cpp index 21ac000..e70a27e 100644 --- a/nfa/nfa.cpp +++ b/nfa/nfa.cpp @@ -11,12 +11,12 @@ NFA RexToNFA() { //由于里面存在||,所以不同正则间使用空格分隔代表| l代表letter,_代表下划线,0代表数字(也可以是d,但是为了使用已经有的函数), //[lu]代表l|u - string rex = "+ - * / % = > < == <= >= != && || ( ) { } , ; [l_][l_0]* -?00*"; + string rex = "+ - * / % = > < == <= >= != && || ( ) { } , ; [l_][l_0]* -?00* -?[0-9]+\\.[0-9]+"; //下面给出正则对应的输出(终态) vector finalState = { OP_ADD, OP_SUB,OP_MUL,OP_DIV,OP_MOD,OP_ASSIGN,OP_GT,OP_LT, OP_EQ,OP_LE,OP_GE,OP_NE, OP_AND, OP_OR,SE_LBRAC, SE_RBRAC, - SE_LCBRAC,SE_RCBRAC,SE_COMMA,SE_SEMI,IDN,INT_VAL + SE_LCBRAC,SE_RCBRAC,SE_COMMA,SE_SEMI,IDN,INT_VAL,FLOAT_CONST }; stringstream ss(rex); @@ -34,6 +34,21 @@ NFA RexToNFA() { //如获得[l_][l_0]* State* currentState = startState; + cout<addTransition(input, newState); + currentState = newState; + } + currentState->setFinalState(true, finalState[endStates.size()]); + endStates.insert(currentState); + continue; + } + for (size_t i = 0; i < target.length();i++) { //创建一个新状态,startState通过输入InputCharType到达该状态 State* newState = new State(stateIndex++); @@ -86,53 +101,10 @@ NFA RexToNFA() { }//for } // 返回字符集合对应的NFA + cout<<"ok"<> stateNum >> inputNum; - - vector states(stateNum); - for (int i = 0; i < stateNum; i++) { - states[i] = new State(i); - } - - State* startState = states[0]; - set endStates; - for (int i = 0; i < stateNum; i++) { - for (int j = 0; j < inputNum; j++) { - string targetStateIDs; - ifs >> targetStateIDs; - if (targetStateIDs.compare("#") != 0) { - stringstream ss(targetStateIDs); - string targetStateIDStr; - while (getline(ss, targetStateIDStr, ',')) { - int targetStateID = stoi(targetStateIDStr); - states[i]->addTransition(static_cast(j), states[targetStateID]); - } - } - } - } - - int endStateNum; - ifs >> endStateNum; - for (int i = 0; i < endStateNum; i++) { - int endStateID, wordTypeID; - ifs >> endStateID >> wordTypeID; - states[endStateID]->setFinalState(true, static_cast(wordTypeID)); - endStates.insert(states[endStateID]); - } - - return NFA(startState, endStates, set(states.begin(), states.end())); -} void printNFA(const NFA& nfa) { cout << "Start state: " << nfa.startState->id << endl; diff --git a/nfa/nfa.h b/nfa/nfa.h index 504d39b..d0fac06 100644 --- a/nfa/nfa.h +++ b/nfa/nfa.h @@ -26,6 +26,9 @@ typedef enum WordType { KW_RETURN, // return KW_CONST, // const KW_MAIN, //main + KW_IF, + KW_ELSE, + KW_FLOAT, OP_ADD, // + OP_SUB, // - @@ -51,6 +54,7 @@ typedef enum WordType { IDN, // [a-zA-Z][a-zA-Z_0-9]* INT_VAL, // -*[0-9]+ + FLOAT_CONST, //[0-9]+'.'[0-9]+ UNKOWN }WordType; string getWordTypeName(WordType type); @@ -81,6 +85,7 @@ typedef enum InputCharType { RCBRAC, // } 17 COMMA, // , 18 SEMI, // ; 19 + POINT, // . EPSILON, // 空字符 20 }InputCharType; @@ -160,8 +165,6 @@ public: // 正则表达式构建状态机 NFA RexToNFA(); void printNFA(const NFA& nfa); -NFA buildNFA(string filename); -NFA RexToNFA(); set move(const set& states, InputCharType input); set epsilonClosure(const set& states); diff --git a/nfa/test_main.cpp b/nfa/test_main.cpp new file mode 100644 index 0000000..6e591f5 --- /dev/null +++ b/nfa/test_main.cpp @@ -0,0 +1,23 @@ +#include +#include +#include + +#include "nfa.h" +using namespace std; + +int main(int argc, char** argv) { + + NFA nfa = RexToNFA(); + //printNFA(nfa); + cout<<"OK1"; + DFA dfa = nfaToDFA(nfa); + cout<<"OK2"; + //printDFA(dfa); + DFA minimizedDFA = minimizeDFA(minimizeDFA(dfa)); + removeUnreachableStates(minimizedDFA); + //printDFA(minimizedDFA); + + + + return 0; +} \ No newline at end of file diff --git a/nfa/tool.cpp b/nfa/tool.cpp index a258ba1..76c3f34 100644 --- a/nfa/tool.cpp +++ b/nfa/tool.cpp @@ -31,6 +31,7 @@ InputCharType getInputCharType(char c) { case '}': return RCBRAC; case ',': return COMMA; case ';': return SEMI; + case '.': return POINT; default: if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) { return LETTER; @@ -88,6 +89,8 @@ string getInputChartypeName(InputCharType type) { return ","; case SEMI: return ";"; + case POINT: + return "."; case EPSILON: return "EPSILON"; default: @@ -136,6 +139,8 @@ string getWordTypeName(WordType type, string buffer) { // 整数 case INT_VAL: return "INT"; + case FLOAT_CONST: + return "FLOAT"; //default default: