diff --git a/.vscode/settings.json b/.vscode/settings.json index a6baec2..eb82253 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -58,6 +58,7 @@ "m_dfa_struct.h": "c", "compiler.h": "c", "stdbool.h": "c", - "type_traits": "c" + "type_traits": "c", + "util_cursor.h": "c" } } \ No newline at end of file diff --git a/src/Business/B_Tokenize.c b/src/Business/B_Tokenize.c index c7a0ee3..f78ee08 100644 --- a/src/Business/B_Tokenize.c +++ b/src/Business/B_Tokenize.c @@ -10,22 +10,28 @@ void B_Tokenize_SeqMove(E_Doc *doc, const string filename, const string code, lo M_NFA_Top *nfa_top = calloc(1, sizeof(M_NFA_Top)); M_NFA_Top_Init(nfa_top); - int index = 0; - while (index < size) { + M_Cursor cursor = (M_Cursor){0}; + strcpy(cursor.file, filename); + cursor.index = 0; + cursor.line = 1; + cursor.code_size = size; + + while (cursor.index < size) { NFA_Top_Status top_status = nfa_top->status; int line = doc->line; - int start_index = index; - int end_index = index; - char c = code[index]; - bool isSplit = true; + int start_index = cursor.index; + int end_index = cursor.index; + char c = code[cursor.index]; + cursor.is_split = true; char validVar = Char_IsLetterOrNumberOrUnderline(c); + // ==== Word ==== const string word; if (validVar != 0) { - isSplit = false; + cursor.is_split = false; // 非分隔符, 读取到下个分隔符为止, 作为一个单词 for (int i = start_index + 1; i < size; i++) { char tmp = code[i]; @@ -35,15 +41,19 @@ void B_Tokenize_SeqMove(E_Doc *doc, const string filename, const string code, lo break; } } - word = TextSubtext(code, start_index, end_index - start_index); + word = String_SubString(code, start_index, end_index - start_index); } else { // 分隔符, 不读取, 直接跳过 - word = TextSubtext(code, start_index, 1); + word = String_SubString(code, start_index, 1); } - if (top_status == NFA_Top_Status_Import) { + cursor.index = end_index; + + if (top_status == NFA_Top_Status_Guess) { + D_NFA_Top_Process(nfa_top, code, word, &cursor); + } else if (top_status == NFA_Top_Status_Import) { M_DFA_Import *dfa_import = nfa_top->dfa_import; - end_index = D_DFA_Import_Process(dfa_import, filename, line, isSplit, word, end_index, code, size); + D_DFA_Import_Process(dfa_import, code, word, &cursor); if (dfa_import->is_done) { E_Doc_Import_Add(doc, dfa_import->import); D_NFA_Top_Enter(nfa_top); @@ -62,14 +72,6 @@ void B_Tokenize_SeqMove(E_Doc *doc, const string filename, const string code, lo // E_Doc_StaticFunc_Add(doc, fsm_func->function); // D_NFA_Top_Enter(nfa_top); // } - } else if (top_status == NFA_Top_Status_Guess) { - D_NFA_Top_Process(nfa_top, filename, line, isSplit, word, code, size); - } - - if (!isSplit) { - index = end_index; - } else { - index = end_index + 1; } if (c == KW_NEWLINE) { diff --git a/src/Business/B_Tokenize.h b/src/Business/B_Tokenize.h index f953c7d..36c66a3 100644 --- a/src/Business/B_Tokenize.h +++ b/src/Business/B_Tokenize.h @@ -1,7 +1,6 @@ #ifndef B_TOKENIZE_H__ #define B_TOKENIZE_H__ #include "import.h" -#include void B_Tokenize_SeqMove(E_Doc *doc, const string filename, const string code, long size); diff --git a/src/Business/D_DFA_Import.c b/src/Business/D_DFA_Import.c index 14ba2e1..4b4b2be 100644 --- a/src/Business/D_DFA_Import.c +++ b/src/Business/D_DFA_Import.c @@ -1,5 +1,6 @@ #include "D_DFA_Import.h" #include "D_NFA_Top.h" +#include "Util_Cursor.h" #include "import.h" void D_DFA_Import_Free(M_DFA_Import *fsm) { @@ -10,45 +11,40 @@ void D_DFA_Import_Enter(M_DFA_Import *fsm) { PLogNA("enter top import\r\n"); } -int D_DFA_Import_Process(M_DFA_Import *fsm, const string file, int line, bool is_split, const string word, int index, const string code, long size) { +void D_DFA_Import_Process(M_DFA_Import *fsm, const string code, const string word, M_Cursor *cursor) { - if (!is_split) { - return index; - } - - if (Char_IsEmptySymbol(word[0])) { - return index; - } - - char split = word[0]; - if (split == KW_QUOTE) { - // " - int right_index = String_CutBetweenSameChars(index, code, size, KW_QUOTE); - if (right_index != -1) { - const string value = String_SubString(code, index + 1, right_index - index - 1); // 去掉两边的引号 - fsm->import = Factory_CreateImport(value, ImportType_Quote); - index = right_index; - } else { - PLog("err word:%s\r\n", word); - PFailed(file, line, ERR_UNDIFINDED_ERR); - } - } else if (split == KW_LEFT_ANGLE_BRACKET) { - // < - int right_index = String_CutBetweenDifferentChars(index, code, size, KW_LEFT_ANGLE_BRACKET, KW_RIGHT_ANGLE_BRACKET); - if (right_index != -1) { - const string value = String_SubString(code, index + 1, right_index - index - 1); // 去掉两边的尖括号 - fsm->import = Factory_CreateImport(value, ImportType_ANGLE_BRACKET); - index = right_index; + if (cursor->is_split) { + char split = word[0]; + if (split == KW_QUOTE) { + // " + int right_index = String_CutBetweenSameChars(cursor->index, code, cursor->code_size, KW_QUOTE); + if (right_index != -1) { + const string value = String_SubString(code, cursor->index + 1, right_index - cursor->index - 1); // 去掉两边的引号 + fsm->import = Factory_CreateImport(value, ImportType_Quote); + cursor->index = right_index + 1; + } else { + PLog("err word:%s\r\n", word); + PFailed(cursor->file, cursor->line, ERR_UNDIFINDED_ERR); + } + } else if (split == KW_LEFT_ANGLE_BRACKET) { + // < + int right_index = String_CutBetweenDifferentChars(cursor->index, code, cursor->code_size, KW_LEFT_ANGLE_BRACKET, KW_RIGHT_ANGLE_BRACKET); + if (right_index != -1) { + const string value = String_SubString(code, cursor->index + 1, right_index - cursor->index - 1); // 去掉两边的尖括号 + fsm->import = Factory_CreateImport(value, ImportType_ANGLE_BRACKET); + cursor->index = right_index + 1; + } else { + PLog("err word:%s\r\n", word); + PFailed(cursor->file, cursor->line, ERR_UNDIFINDED_ERR); + } + } else if (split == KW_SEMICOLON) { + // ; + ++cursor->index; + fsm->is_done = true; } else { - PLog("err word:%s\r\n", word); - PFailed(file, line, ERR_UNDIFINDED_ERR); + Util_Cursor_DealEmpty(cursor, code, word); } + } else { + PFailed(cursor->file, cursor->line, ERR_UNDIFINDED_ERR); } - - if (split == KW_SEMICOLON) { - // ; - fsm->is_done = true; - } - - return index; } \ No newline at end of file diff --git a/src/Business/D_DFA_Import.h b/src/Business/D_DFA_Import.h index 8cc44bb..d845658 100644 --- a/src/Business/D_DFA_Import.h +++ b/src/Business/D_DFA_Import.h @@ -5,6 +5,6 @@ void D_DFA_Import_Free(M_DFA_Import *fsm); void D_DFA_Import_Enter(M_DFA_Import *fsm); -int D_DFA_Import_Process(M_DFA_Import *fsm, const string file, int line, bool is_split, const string word, int index, const string code, long size); +void D_DFA_Import_Process(M_DFA_Import *fsm, const string code, const string word, M_Cursor *cursor); #endif \ No newline at end of file diff --git a/src/Business/D_DFA_Struct.c b/src/Business/D_DFA_Struct.c index 51bc6a0..86408b4 100644 --- a/src/Business/D_DFA_Struct.c +++ b/src/Business/D_DFA_Struct.c @@ -19,7 +19,7 @@ int Phase_Name_Process(M_DFA_Struct *dfa_struct, const string file, int line, bo dfa_struct->nested_level += 1; dfa_struct->is_done = true; } else { - if (Char_IsEmptySymbol(split)) { + if (Char_IsEmptySymbolButNewLine(split)) { // ' ' '\t' '\n' '\r' return index; } diff --git a/src/Business/D_NFA_Top.c b/src/Business/D_NFA_Top.c index 7895ae6..22ff100 100644 --- a/src/Business/D_NFA_Top.c +++ b/src/Business/D_NFA_Top.c @@ -2,6 +2,7 @@ #include "D_DFA_Func.h" #include "D_DFA_Import.h" #include "D_DFA_Struct.h" +#include "Util_Cursor.h" void D_NFA_Top_Free(M_NFA_Top *nfa_top) { M_NFA_Top_Free(nfa_top); @@ -12,16 +13,13 @@ void D_NFA_Top_Enter(M_NFA_Top *nfa_top) { E_Guess_Init(&nfa_top->guess); } -void D_NFA_Top_Process(M_NFA_Top *nfa_top, const string file, int line, bool is_split, const string word, const string code, long size) { +void D_NFA_Top_Process(M_NFA_Top *nfa_top, const string code, const string word, M_Cursor *cursor) { - if (is_split) { - if (Char_IsEmptySymbol(word[0])) { - return; - } - } + // import ; + // import "raylib.h"; E_Guess *guess = &nfa_top->guess; - if (!is_split) { + if (!cursor->is_split) { if (strcmp(word, KW_IMPORT) == 0) { // import nfa_top->status = NFA_Top_Status_Import; @@ -45,17 +43,26 @@ void D_NFA_Top_Process(M_NFA_Top *nfa_top, const string file, int line, bool is_ guess->is_const = true; } else if (String_IsAccess(word)) { // access: public, private... - E_Guess_SetAccess(guess, file, line, word); + E_Guess_SetAccess(guess, cursor->file, cursor->line, word); } else { // push word - E_Guess_PushWord(guess, file, line, word); + E_Guess_PushWord(guess, cursor->file, cursor->line, word); } } else { - if (word[0] == KW_SEMICOLON) { + char split = word[0]; + if (split == KW_EQUAL) { + // = assign stm + ++cursor->index; + PLogNA("TODO assign stm\r\n"); + } else if (split == KW_SEMICOLON) { // ; field end - } else if (word[0] == KW_RIGHT_BRACE) { + ++cursor->index; + PLogNA("TODO field end\r\n"); + } else if (split == KW_RIGHT_BRACE) { // } - PFailed(file, line, ERR_FUNCTION_OR_FIELD_NOT_END); + PFailed(cursor->file, cursor->line, ERR_FUNCTION_OR_FIELD_NOT_END); + } else { + Util_Cursor_DealEmpty(cursor, code, word); } } } \ No newline at end of file diff --git a/src/Business/D_NFA_Top.h b/src/Business/D_NFA_Top.h index 9954f24..75e71ba 100644 --- a/src/Business/D_NFA_Top.h +++ b/src/Business/D_NFA_Top.h @@ -5,6 +5,6 @@ void D_NFA_Top_Free(M_NFA_Top *nfa_top); void D_NFA_Top_Enter(M_NFA_Top *nfa_top); -void D_NFA_Top_Process(M_NFA_Top *nfa_top, const string file, int line, bool is_split, const string word, const string code, long size); +void D_NFA_Top_Process(M_NFA_Top *nfa_top, const string code, const string word, M_Cursor *cursor); #endif \ No newline at end of file diff --git a/src/Business/Util_Cursor.c b/src/Business/Util_Cursor.c new file mode 100644 index 0000000..0f3c482 --- /dev/null +++ b/src/Business/Util_Cursor.c @@ -0,0 +1,26 @@ +#include "Util_Cursor.h" + +void Util_Cursor_DealEmpty(M_Cursor *cursor, const string code, const string word) { + if (!cursor->is_split) { + PFailed(cursor->file, cursor->line, ERR_UNDIFINDED_ERR); + return; + } + char split = word[0]; + if (Char_IsEmptySymbolButNewLine(split)) { + // ' ' '\t' + ++cursor->index; + } else if (split == KW_NEWLINE_R) { + // '\r' + if (code[cursor->index + 1] == KW_NEWLINE) { + // '\r\n' + ++cursor->index; + ++cursor->line; + } + } else if (split == KW_NEWLINE) { + // '\n' + ++cursor->index; + ++cursor->line; + } else { + PFailed(cursor->file, cursor->line, ERR_UNDIFINDED_ERR); + } +} \ No newline at end of file diff --git a/src/Business/Util_Cursor.h b/src/Business/Util_Cursor.h new file mode 100644 index 0000000..46e27c8 --- /dev/null +++ b/src/Business/Util_Cursor.h @@ -0,0 +1,8 @@ +#ifndef Util_Cursor_H__ +#define Util_Cursor_H__ + +#include "import.h" + +void Util_Cursor_DealEmpty(M_Cursor *cursor, const string code, const string word); + +#endif \ No newline at end of file diff --git a/src/Entities_Source/M_Cursor.c b/src/Entities_Source/M_Cursor.c new file mode 100644 index 0000000..bf18342 --- /dev/null +++ b/src/Entities_Source/M_Cursor.c @@ -0,0 +1 @@ +#include "M_Cursor.h" diff --git a/src/Entities_Source/M_Cursor.h b/src/Entities_Source/M_Cursor.h new file mode 100644 index 0000000..84ba110 --- /dev/null +++ b/src/Entities_Source/M_Cursor.h @@ -0,0 +1,15 @@ +#ifndef M_CURSOR_H__ +#define M_CURSOR_H__ + +#include "import.h" + +typedef struct M_Cursor { + char file[FILENAME_MAX]; + char word[RULE_VAR_NAME_LEN]; + bool is_split; + int line; + int index; + int code_size; // readonly +} M_Cursor; + +#endif \ No newline at end of file diff --git a/src/Entities_Source/export.h b/src/Entities_Source/export.h index 33267ec..2195fd3 100644 --- a/src/Entities_Source/export.h +++ b/src/Entities_Source/export.h @@ -5,6 +5,7 @@ #include "E_Function.h" #include "E_Guess.h" #include "E_Struct.h" +#include "M_Cursor.h" #include "M_DFA_Func.h" #include "M_DFA_Import.h" #include "M_DFA_Struct.h" diff --git a/src/Generic/StringCommon.c b/src/Generic/StringCommon.c index e58092d..be127e3 100644 --- a/src/Generic/StringCommon.c +++ b/src/Generic/StringCommon.c @@ -390,8 +390,8 @@ char Char_IsQuote(char c) { } } -char Char_IsEmptySymbol(char c) { - return c == KW_SPACE || c == KW_NEWLINE || c == KW_NEWLINE_R || c == KW_TABLE; +char Char_IsEmptySymbolButNewLine(char c) { + return c == KW_SPACE || c == KW_TABLE; } char Char_IsSplitSymbol(char c) { diff --git a/src/Generic/StringCommon.h b/src/Generic/StringCommon.h index 36d924f..a588570 100644 --- a/src/Generic/StringCommon.h +++ b/src/Generic/StringCommon.h @@ -15,7 +15,7 @@ int String_CutBetweenDifferentChars(int start_index, const string word, long siz bool String_IsAccess(const string word); char Char_IsBracket(char c); char Char_IsQuote(char c); -char Char_IsEmptySymbol(char c); +char Char_IsEmptySymbolButNewLine(char c); char Char_IsSplitSymbol(char c); char Char_IsLetter(char c); char Char_IsLetterOrUnderline(char c); diff --git a/src/win64.c b/src/win64.c index 10c14b2..663bf68 100644 --- a/src/win64.c +++ b/src/win64.c @@ -3,6 +3,7 @@ #include "Business/D_DFA_Import.c" #include "Business/D_DFA_Struct.c" #include "Business/D_NFA_Top.c" +#include "Business/Util_Cursor.c" #include "Entities_Source/E_Doc.c" #include "Entities_Source/E_Expression.c" @@ -12,6 +13,7 @@ #include "Entities_Source/E_Import.c" #include "Entities_Source/E_Statement.c" #include "Entities_Source/E_Struct.c" +#include "Entities_Source/M_Cursor.c" #include "Entities_Source/M_DFA_ConstString.c" #include "Entities_Source/M_DFA_Func.c" #include "Entities_Source/M_DFA_Import.c" @@ -22,7 +24,7 @@ #include "Helper/FileHelper.c" -#include "Context.c" #include "Compiler.c" +#include "Context.c" #include "Factory.c" #include "Generic/StringCommon.c"