From a9a26ec122df08034d17e86ea50258ff75ab1712 Mon Sep 17 00:00:00 2001 From: herbglitch Date: Fri, 28 Mar 2025 02:53:03 -0600 Subject: [PATCH] fixed a memory leak in lexer, all tests are now memory safe --- CMakeLists.txt | 16 +- doc/pages/standard/vector.md | 16 +- include/arc/std/lexer.h | 70 ----- src/std/lexer.c | 56 +--- src/std/parser/parserlang.c | 2 +- tests/std/config.c | 79 +---- tests/std/lexer.c | 86 ++++++ tests/std/parser.c | 571 ++++++++++++++++------------------- 8 files changed, 378 insertions(+), 518 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 483e9c6..3c2e1bb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -135,14 +135,14 @@ if(ARCHEUS_TESTS) add_executable(tests tests/test.c - #tests/std/config.c - #tests/std/entity.c - #tests/std/hashtable.c - #tests/std/lexer.c - #tests/std/parser.c - #tests/std/parser/csv.c - #tests/std/parser/parserlang.c - #tests/std/vector.c + tests/std/config.c + tests/std/entity.c + tests/std/hashtable.c + tests/std/lexer.c + tests/std/parser.c + tests/std/parser/csv.c + tests/std/parser/parserlang.c + tests/std/vector.c tests/std/vector/inline.c ${ARCHEUS_SOURCES} diff --git a/doc/pages/standard/vector.md b/doc/pages/standard/vector.md index 0e1a4f3..6e2c3d1 100644 --- a/doc/pages/standard/vector.md +++ b/doc/pages/standard/vector.md @@ -85,10 +85,10 @@ int main(){ //print the values within the vector for(uint32_t index = 0; index < ARC_Vector_GetSize(vector); index++){ //cast the return value back to what it initially was - valueRef = (int32_t *)ARC_Vector_Get(vector, index); + int32_t *valueRef = (int32_t *)ARC_Vector_Get(vector, index); //print out the index and value - printf("%d) %d\n", index, *value); + printf("%d) %d\n", index, *valueRef); } //remove the value @@ -97,10 +97,10 @@ int main(){ //print the values again to show that the value was removed for(uint32_t index = 0; index < ARC_Vector_GetSize(vector); index++){ //cast the return value back to what it initially was - valueRef = (int32_t *)ARC_Vector_Get(vector, index); + int32_t *valueRef = (int32_t *)ARC_Vector_Get(vector, index); //print out the index and value - printf("%d) %d\n", index, *value); + printf("%d) %d\n", index, *valueRef); } //cleanup @@ -147,10 +147,10 @@ int main(){ //print the values within the vector for(uint32_t index = 0; index < ARC_Vector_GetSize(vector); index++){ //cast the return value back to what it initially was - valueRef = (int32_t *)ARC_Vector_Get(vector, index); + int32_t *valueRef = (int32_t *)ARC_Vector_Get(vector, index); //print out the index and value - printf("%d) %d\n", index, *value); + printf("%d) %d\n", index, *valueRef); } //example to demonstrate that there is no memory leak on removal due to the destroy callback @@ -159,10 +159,10 @@ int main(){ //print the values again to show that the value was removed for(uint32_t index = 0; index < ARC_Vector_GetSize(vector); index++){ //cast the return value back to what it initially was - valueRef = (int32_t *)ARC_Vector_Get(vector, index); + int32_t valueRef = (int32_t *)ARC_Vector_Get(vector, index); //print out the index and value - printf("%d) %d\n", index, *value); + printf("%d) %d\n", index, *valueRef); } //cleanup diff --git a/include/arc/std/lexer.h b/include/arc/std/lexer.h index 111d04c..fa17bf1 100644 --- a/include/arc/std/lexer.h +++ b/include/arc/std/lexer.h @@ -242,76 +242,6 @@ ARC_LexerTokenRule ARC_LexerTokenRule_CreateAndReturnMatchStringRule(uint32_t id */ ARC_LexerTokenRule ARC_LexerTokenRule_CreateAndReturnMatchCharInStringRule(uint32_t id, ARC_String *string); -/** - * @{ - * @brief basic tokens -*/ -#define ARC_LEXER_TOKEN_NULL 0 -#define ARC_LEXER_TOKEN_NUMBER 1 -#define ARC_LEXER_TOKEN_ALPHA_LOWER_CHAR 2 -#define ARC_LEXER_TOKEN_ALPHA_UPPER_CHAR 3 -#define ARC_LEXER_TOKEN_WHITESPACE 4 -/** - * @} -*/ - -/** - * @{ - * @brief basic token type ids, chars, and tags -*/ -#define ARC_LEXER_TOKEN_NEWLINE_ID 5 -#define ARC_LEXER_TOKEN_NEWLINE_CHAR '\n' -#define ARC_LEXER_TOKEN_COLON_ID 6 -#define ARC_LEXER_TOKEN_COLON_CHAR ':' -#define ARC_LEXER_TOKEN_COLON_TAG "COLON" -#define ARC_LEXER_TOKEN_SEMICOLON_ID 7 -#define ARC_LEXER_TOKEN_SEMICOLON_CHAR ';' -#define ARC_LEXER_TOKEN_SEMICOLON_TAG "SEMICOLON" -#define ARC_LEXER_TOKEN_COMMA_ID 8 -#define ARC_LEXER_TOKEN_COMMA_CHAR ',' -#define ARC_LEXER_TOKEN_COMMA_TAG "COMMA" -#define ARC_LEXER_TOKEN_PERIOD_ID 9 -#define ARC_LEXER_TOKEN_PERIOD_CHAR '.' -#define ARC_LEXER_TOKEN_PERIOD_TAG "PERIOD" -#define ARC_LEXER_TOKEN_FORWARD_SLASH_ID 10 -#define ARC_LEXER_TOKEN_FORWARD_SLASH_CHAR '/' -#define ARC_LEXER_TOKEN_FORWARD_SLASH_TAG "FORWARD_SLASH" -#define ARC_LEXER_TOKEN_BACK_SLASH_ID 11 -#define ARC_LEXER_TOKEN_BACK_SLASH_CHAR '\\' -#define ARC_LEXER_TOKEN_BACK_SLASH_TAG "BACK_SLASH" -#define ARC_LEXER_TOKEN_LEFT_PARENTHESIS_ID 12 -#define ARC_LEXER_TOKEN_LEFT_PARENTHESIS_CHAR '(' -#define ARC_LEXER_TOKEN_LEFT_PARENTHESIS_TAG "LEFT_PARENTHESIS" -#define ARC_LEXER_TOKEN_RIGHT_PARENTHESIS_ID 13 -#define ARC_LEXER_TOKEN_RIGHT_PARENTHESIS_CHAR ')' -#define ARC_LEXER_TOKEN_RIGHT_PARENTHESIS_TAG "RIGHT_PARENTHESIS" -#define ARC_LEXER_TOKEN_LEFT_CURLY_BRACE_ID 14 -#define ARC_LEXER_TOKEN_LEFT_CURLY_BRACE_CHAR '{' -#define ARC_LEXER_TOKEN_LEFT_CURLY_BRACE_TAG "LEFT_CURLY_BRACE" -#define ARC_LEXER_TOKEN_RIGHT_CURLY_BRACE_ID 15 -#define ARC_LEXER_TOKEN_RIGHT_CURLY_BRACE_CHAR '}' -#define ARC_LEXER_TOKEN_RIGHT_CURLY_BRACE_TAG "RIGHT_CURLY_BRACE" -#define ARC_LEXER_TOKEN_BANG_ID 16 -#define ARC_LEXER_TOKEN_BANG_CHAR '!' -#define ARC_LEXER_TOKEN_BANG_TAG "BANG" -#define ARC_LEXER_TOKEN_AT_ID 17 -#define ARC_LEXER_TOKEN_AT_CHAR '!' -#define ARC_LEXER_TOKEN_AT_TAG "AT" -#define ARC_LEXER_TOKEN_HASH_ID 18 -#define ARC_LEXER_TOKEN_HASH_CHAR '#' -#define ARC_LEXER_TOKEN_HASH_TAG "HASH" -#define ARC_LEXER_TOKEN_PERCENT_ID 19 -#define ARC_LEXER_TOKEN_PERCENT_CHAR '%' -#define ARC_LEXER_TOKEN_PERCENT_TAG "PERCENT" -/** - * @} -*/ - -/** - * @brief adds a bunch of basic token rules (matching the BasicTokens above) -*/ -void ARC_Lexer_InitBasicTokenRules(ARC_Lexer *lexer); - #ifdef __cplusplus } #endif diff --git a/src/std/lexer.c b/src/std/lexer.c index e690dd6..d5f6df1 100644 --- a/src/std/lexer.c +++ b/src/std/lexer.c @@ -208,6 +208,10 @@ void ARC_Lexer_LexString(ARC_Lexer *lexer, ARC_String **data){ //check if a token was found if it wasn't continue. I'm doing this to try to cut down on the ammount of indentation if(tokenLength == 0){ + if(tokenData != NULL){ + ARC_String_Destroy(tokenData); + } + continue; } @@ -225,6 +229,12 @@ void ARC_Lexer_LexString(ARC_Lexer *lexer, ARC_String **data){ //update the last found tokenLength to the max length lastTokenLength = tokenLength; + + continue; + } + + if(tokenData != NULL){ + ARC_String_Destroy(tokenData); } } @@ -397,6 +407,11 @@ void ARC_LexerTokenRule_DestroyCharAutomataDataFn(void *automataData){ free((char *)automataData); } +//private function to free automataData stored as an ARC_String +void ARC_LexerTokenRule_DestroyStringAutomataDataFn(void *automataData){ + ARC_String_Destroy((ARC_String *)automataData); +} + ARC_LexerTokenRule ARC_LexerTokenRule_CreateAndReturnMatchCharRule(uint32_t id, char character){ //create the token rule ARC_LexerTokenRule tokenRule; @@ -442,11 +457,6 @@ ARC_LexerTokenRule ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(uint32_t return tokenRule; } -//private function to free automataData stored as an ARC_String -void ARC_LexerTokenRule_DestroyStringAutomataDataFn(void *automataData){ - ARC_String_Destroy((ARC_String *)automataData); -} - ARC_LexerTokenRule ARC_LexerTokenRule_CreateAndReturnMatchStringRule(uint32_t id, ARC_String *string){ //create the token rule ARC_LexerTokenRule tokenRule; @@ -490,39 +500,3 @@ ARC_LexerTokenRule ARC_LexerTokenRule_CreateAndReturnMatchCharInStringRule(uint3 //return the created tokenRule return tokenRule; } - -void ARC_Lexer_InitBasicTokenRules(ARC_Lexer *lexer){ - //null - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_NULL, 0)); - - //number - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(ARC_LEXER_TOKEN_NUMBER, '0', '9')); - - //alpha char - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(ARC_LEXER_TOKEN_ALPHA_LOWER_CHAR, 'a', 'z')); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(ARC_LEXER_TOKEN_ALPHA_UPPER_CHAR, 'A', 'Z')); - - //whitespace - //TODO: fix this - ARC_String *whitespaceString; - ARC_String_CreateWithStrlen(&whitespaceString, " \t"); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharInStringRule(ARC_LEXER_TOKEN_WHITESPACE, whitespaceString)); - ARC_String_Destroy(whitespaceString); - - //single char tokens - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_NEWLINE_ID , ARC_LEXER_TOKEN_NEWLINE_CHAR )); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_COLON_ID , ARC_LEXER_TOKEN_COLON_CHAR )); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_SEMICOLON_ID , ARC_LEXER_TOKEN_SEMICOLON_CHAR )); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_COMMA_ID , ARC_LEXER_TOKEN_COMMA_CHAR )); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_PERIOD_ID , ARC_LEXER_TOKEN_PERIOD_CHAR )); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_FORWARD_SLASH_ID , ARC_LEXER_TOKEN_FORWARD_SLASH_CHAR )); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_BACK_SLASH_ID , ARC_LEXER_TOKEN_BACK_SLASH_CHAR )); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_LEFT_PARENTHESIS_ID , ARC_LEXER_TOKEN_LEFT_PARENTHESIS_CHAR )); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_RIGHT_PARENTHESIS_ID, ARC_LEXER_TOKEN_RIGHT_PARENTHESIS_CHAR)); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_LEFT_CURLY_BRACE_ID , ARC_LEXER_TOKEN_LEFT_CURLY_BRACE_CHAR )); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_RIGHT_CURLY_BRACE_ID, ARC_LEXER_TOKEN_RIGHT_CURLY_BRACE_CHAR)); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_BANG_ID , ARC_LEXER_TOKEN_BANG_CHAR )); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_AT_ID , ARC_LEXER_TOKEN_AT_CHAR )); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_HASH_ID , ARC_LEXER_TOKEN_HASH_CHAR )); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_PERCENT_ID , ARC_LEXER_TOKEN_PERCENT_CHAR )); -} diff --git a/src/std/parser/parserlang.c b/src/std/parser/parserlang.c index ae4d4c4..1042fb6 100644 --- a/src/std/parser/parserlang.c +++ b/src/std/parser/parserlang.c @@ -23,7 +23,7 @@ void ARC_ParserLang_InitLexerRulesFn(ARC_Lexer *lexer){ //whitespace ARC_String *whitespaceString; ARC_String_CreateWithStrlen(&whitespaceString, " \t"); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharInStringRule(ARC_LEXER_TOKEN_WHITESPACE, whitespaceString)); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharInStringRule(ARC_PARSERLANG_TOKEN_WHITESPACE, whitespaceString)); ARC_String_Destroy(whitespaceString); //single char tokens diff --git a/tests/std/config.c b/tests/std/config.c index d565b48..21a2d74 100644 --- a/tests/std/config.c +++ b/tests/std/config.c @@ -1,92 +1,15 @@ #include "../test.h" #include "arc/std/errno.h" #include "arc/std/config.h" -#include "arc/std/parser.h" -#include "arc/std/parser/helpers.h" #include -static const char *testType = "int32"; - -void TEST_configType_CopyInt32Fn(void **type, ARC_ParserTagToken *parsedData, ARC_Config *config, void *userdata){ - //go into the tag - ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(parsedData->tagTokens, 0); - if(childTagToken->id != ARC_CONFIG_NUMBER_SIGN){ - arc_errno = ARC_ERRNO_DATA; - ARC_DEBUG_LOG_ERROR("TEST_configType_CopyInt32Fn(type, parsedData, config), parsed data was not a "); - *type = NULL; - return; - } - - //check if the first tag is a minus sign and create a string starting with that if it is - childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(childTagToken->tagTokens, 0); - ARC_String *int32String; - ARC_String_Create(&int32String, NULL, 0); - if(childTagToken->id == ARC_CONFIG_MINUS){ - ARC_String_AppendCStringWithStrlen(&int32String, "-"); - } - - ARC_ParserData_HelperRecurseStringAdd(&int32String, parsedData); - - //set the max character size 2,147,483,647 (10 characters) or -2,147,483,648 (11 characters) - uint32_t maxInt32Size = 10; - if(int32String->data[0] == '-'){ - maxInt32Size++; - } - - //if the string is bigger than the possible size return NULL and error - if(int32String->length > maxInt32Size){ - arc_errno = ARC_ERRNO_DATA; - ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("TEST_configType_CopyInt32Fn(type, parsedData, config), size \"%s\" was bigger or smaller than the max 2,147,483,647 or min -2,147,483,648", int32String->data); - *type = NULL; - ARC_String_Destroy(int32String); - return; - } - - if(int32String->length == maxInt32Size){ - char maxint32CStr[10] = "2147483647"; - - //offset starting index and last number if there is a negative - uint8_t stringIndex = 0; - if(int32String->data[0] == '-'){ - stringIndex++; - maxint32CStr[9]++; - } - - for(uint8_t index = 0; index < 10; index++, stringIndex++){ - if(int32String->data[stringIndex] > maxint32CStr[index]){ - arc_errno = ARC_ERRNO_DATA; - ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("TEST_configType_CopyInt32Fn(type, parsedData, config), size \"%s\" was bigger or smaller than the max 2,147,483,647 or min -2,147,483,648", int32String->data); - *type = NULL; - ARC_String_Destroy(int32String); - return; - } - } - } - - //copy the int32_t - *type = malloc(sizeof(int32_t)); - *(int32_t *)(*type) = (int32_t)ARC_String_ToInt64_t(int32String); - - //cleanup - ARC_String_Destroy(int32String); -} - -void TEST_configType_DestroyInt32Fn(void *type){ - free((int32_t *)type); -} - ARC_TEST(config_BasicTest){ ARC_Config *config; ARC_Config_Create(&config); ARC_CHECK(arc_errno == 0); - ARC_ConfigType int32Type = { - TEST_configType_CopyInt32Fn, - TEST_configType_DestroyInt32Fn, - NULL - }; - ARC_Config_RegisterTypeWithCStr(config, testType, int32Type); + ARC_Config_InitStd(config); char *tempCString = "tests/res/std/config/first.chemical"; ARC_String *tempString; diff --git a/tests/std/lexer.c b/tests/std/lexer.c index 30342f1..42daf2a 100644 --- a/tests/std/lexer.c +++ b/tests/std/lexer.c @@ -1,6 +1,92 @@ #include "../test.h" #include "arc/std/lexer.h" +#define ARC_LEXER_TOKEN_NULL 0 +#define ARC_LEXER_TOKEN_NUMBER 1 +#define ARC_LEXER_TOKEN_ALPHA_LOWER_CHAR 2 +#define ARC_LEXER_TOKEN_ALPHA_UPPER_CHAR 3 +#define ARC_LEXER_TOKEN_WHITESPACE 4 +#define ARC_LEXER_TOKEN_NEWLINE_ID 5 +#define ARC_LEXER_TOKEN_NEWLINE_CHAR '\n' +#define ARC_LEXER_TOKEN_COLON_ID 6 +#define ARC_LEXER_TOKEN_COLON_CHAR ':' +#define ARC_LEXER_TOKEN_COLON_TAG "COLON" +#define ARC_LEXER_TOKEN_SEMICOLON_ID 7 +#define ARC_LEXER_TOKEN_SEMICOLON_CHAR ';' +#define ARC_LEXER_TOKEN_SEMICOLON_TAG "SEMICOLON" +#define ARC_LEXER_TOKEN_COMMA_ID 8 +#define ARC_LEXER_TOKEN_COMMA_CHAR ',' +#define ARC_LEXER_TOKEN_COMMA_TAG "COMMA" +#define ARC_LEXER_TOKEN_PERIOD_ID 9 +#define ARC_LEXER_TOKEN_PERIOD_CHAR '.' +#define ARC_LEXER_TOKEN_PERIOD_TAG "PERIOD" +#define ARC_LEXER_TOKEN_FORWARD_SLASH_ID 10 +#define ARC_LEXER_TOKEN_FORWARD_SLASH_CHAR '/' +#define ARC_LEXER_TOKEN_FORWARD_SLASH_TAG "FORWARD_SLASH" +#define ARC_LEXER_TOKEN_BACK_SLASH_ID 11 +#define ARC_LEXER_TOKEN_BACK_SLASH_CHAR '\\' +#define ARC_LEXER_TOKEN_BACK_SLASH_TAG "BACK_SLASH" +#define ARC_LEXER_TOKEN_LEFT_PARENTHESIS_ID 12 +#define ARC_LEXER_TOKEN_LEFT_PARENTHESIS_CHAR '(' +#define ARC_LEXER_TOKEN_LEFT_PARENTHESIS_TAG "LEFT_PARENTHESIS" +#define ARC_LEXER_TOKEN_RIGHT_PARENTHESIS_ID 13 +#define ARC_LEXER_TOKEN_RIGHT_PARENTHESIS_CHAR ')' +#define ARC_LEXER_TOKEN_RIGHT_PARENTHESIS_TAG "RIGHT_PARENTHESIS" +#define ARC_LEXER_TOKEN_LEFT_CURLY_BRACE_ID 14 +#define ARC_LEXER_TOKEN_LEFT_CURLY_BRACE_CHAR '{' +#define ARC_LEXER_TOKEN_LEFT_CURLY_BRACE_TAG "LEFT_CURLY_BRACE" +#define ARC_LEXER_TOKEN_RIGHT_CURLY_BRACE_ID 15 +#define ARC_LEXER_TOKEN_RIGHT_CURLY_BRACE_CHAR '}' +#define ARC_LEXER_TOKEN_RIGHT_CURLY_BRACE_TAG "RIGHT_CURLY_BRACE" +#define ARC_LEXER_TOKEN_BANG_ID 16 +#define ARC_LEXER_TOKEN_BANG_CHAR '!' +#define ARC_LEXER_TOKEN_BANG_TAG "BANG" +#define ARC_LEXER_TOKEN_AT_ID 17 +#define ARC_LEXER_TOKEN_AT_CHAR '!' +#define ARC_LEXER_TOKEN_AT_TAG "AT" +#define ARC_LEXER_TOKEN_HASH_ID 18 +#define ARC_LEXER_TOKEN_HASH_CHAR '#' +#define ARC_LEXER_TOKEN_HASH_TAG "HASH" +#define ARC_LEXER_TOKEN_PERCENT_ID 19 +#define ARC_LEXER_TOKEN_PERCENT_CHAR '%' +#define ARC_LEXER_TOKEN_PERCENT_TAG "PERCENT" + +void ARC_Lexer_InitBasicTokenRules(ARC_Lexer *lexer){ + //null + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_NULL, 0)); + + //number + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(ARC_LEXER_TOKEN_NUMBER, '0', '9')); + + //alpha char + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(ARC_LEXER_TOKEN_ALPHA_LOWER_CHAR, 'a', 'z')); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(ARC_LEXER_TOKEN_ALPHA_UPPER_CHAR, 'A', 'Z')); + + //whitespace + //TODO: fix this + ARC_String *whitespaceString; + ARC_String_CreateWithStrlen(&whitespaceString, " \t"); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharInStringRule(ARC_LEXER_TOKEN_WHITESPACE, whitespaceString)); + ARC_String_Destroy(whitespaceString); + + //single char tokens + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_NEWLINE_ID , ARC_LEXER_TOKEN_NEWLINE_CHAR )); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_COLON_ID , ARC_LEXER_TOKEN_COLON_CHAR )); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_SEMICOLON_ID , ARC_LEXER_TOKEN_SEMICOLON_CHAR )); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_COMMA_ID , ARC_LEXER_TOKEN_COMMA_CHAR )); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_PERIOD_ID , ARC_LEXER_TOKEN_PERIOD_CHAR )); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_FORWARD_SLASH_ID , ARC_LEXER_TOKEN_FORWARD_SLASH_CHAR )); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_BACK_SLASH_ID , ARC_LEXER_TOKEN_BACK_SLASH_CHAR )); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_LEFT_PARENTHESIS_ID , ARC_LEXER_TOKEN_LEFT_PARENTHESIS_CHAR )); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_RIGHT_PARENTHESIS_ID, ARC_LEXER_TOKEN_RIGHT_PARENTHESIS_CHAR)); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_LEFT_CURLY_BRACE_ID , ARC_LEXER_TOKEN_LEFT_CURLY_BRACE_CHAR )); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_RIGHT_CURLY_BRACE_ID, ARC_LEXER_TOKEN_RIGHT_CURLY_BRACE_CHAR)); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_BANG_ID , ARC_LEXER_TOKEN_BANG_CHAR )); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_AT_ID , ARC_LEXER_TOKEN_AT_CHAR )); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_HASH_ID , ARC_LEXER_TOKEN_HASH_CHAR )); + ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_PERCENT_ID , ARC_LEXER_TOKEN_PERCENT_CHAR )); +} + ARC_TEST(Lexer_Char_Match){ ARC_Lexer *lexer; ARC_Lexer_Create(&lexer); diff --git a/tests/std/parser.c b/tests/std/parser.c index 60cf72a..54ef244 100644 --- a/tests/std/parser.c +++ b/tests/std/parser.c @@ -8,315 +8,262 @@ #include #include -const uint32_t TEST_PARSER_CHAR_OR_NUM = 23; -const uint32_t TEST_PARSER_VARIABLE_NAME = 24; -const uint32_t TEST_PARSER_VARIABLE = 25; - -const uint32_t TEST_PARSER_ALPHA_LOWER_CHAR = 1; -const uint32_t TEST_PARSER_ALPHA_UPPER_CHAR = 2; -const uint32_t TEST_PARSER_ALPHA_CHAR = 3; - -void TEST_ParserData_CreateStringFn(void **data, ARC_ParserTagToken *parsedData, void *userData){ - ARC_String_Create((ARC_String **)data, NULL, 0); - - ARC_ParserData_HelperRecurseStringAdd((ARC_String **)data, parsedData); -} - -void TEST_ParserData_DestroyStringFn(void *data, ARC_Bool clear, void *userData){ - if(data == NULL){ - return; - } - - ARC_String_Destroy((ARC_String *)data); -} - -uint32_t *charOrNumTokens[] = { (uint32_t[]){ 1, ARC_LEXER_TOKEN_ALPHA_LOWER_CHAR }, (uint32_t[]){ 1, ARC_LEXER_TOKEN_NUMBER } }; -uint32_t *variableNameTags[] = { (uint32_t[]){ 2, TEST_PARSER_CHAR_OR_NUM, TEST_PARSER_VARIABLE_NAME }, (uint32_t[]){ 1, ARC_PARSER_TAG_LAMBDA } }; -uint32_t *variableTokensOrTags[] = { (uint32_t[]){ 2, ARC_LEXER_TOKEN_ALPHA_LOWER_CHAR, TEST_PARSER_VARIABLE_NAME } }; - -//TODO: note how language function callbacks work, and how they use the parentData if createDataFn is NULL - -ARC_ParserTag testTags[3] = { - { - TEST_PARSER_VARIABLE, //tagId - variableTokensOrTags, //tokensOrTags - 1 //tokenOrTagsSize - }, - { - TEST_PARSER_VARIABLE_NAME, //tagId - variableNameTags, //tokensOrTags - 2 //tokenOrTagsSize - }, - { - TEST_PARSER_CHAR_OR_NUM, //tagId - charOrNumTokens, //tokensOrTags - 2 //tokenOrTagsSize - } -}; - -ARC_Array languageArray = { - 3, //size - testTags //data -}; - -void TEST_Parser_InitLexerRulesFn(ARC_Lexer *lexer){ - ARC_Lexer_InitBasicTokenRules(lexer); -} - -ARC_TEST(Parser_Init){ - ARC_Parser *parser; - ARC_Parser_Create(&parser, &languageArray, TEST_Parser_InitLexerRulesFn, NULL, NULL, NULL); - - ARC_Parser_Destroy(parser); - - ARC_CHECK(arc_errno == 0); -} - -ARC_TEST(Parser_Basic_Parse){ - ARC_Parser *parser; - ARC_Parser_Create(&parser, &languageArray, TEST_Parser_InitLexerRulesFn, NULL, NULL, NULL); - - ARC_String *tempString; - - - /* ~ first test ~ */ - ARC_String_CreateWithStrlen(&tempString, "myvar1"); - - //this destroys string, so no need for cleanup - ARC_Parser_Parse(parser, &tempString); - - ARC_CHECK(arc_errno == 0); - - - /* ~ second test ~ */ - ARC_String_CreateWithStrlen(&tempString, "z1xwvq"); - - //this destroys string, so no need for cleanup - ARC_Parser_Parse(parser, &tempString); - - ARC_CHECK(arc_errno == 0); - - - /* ~ third test ~ */ - ARC_String_CreateWithStrlen(&tempString, "z1234"); - - //this destroys string, so no need for cleanup - ARC_Parser_Parse(parser, &tempString); - - ARC_CHECK(arc_errno == 0); - - - /* ~ fourth test ~ */ - ARC_String_CreateWithStrlen(&tempString, "aaaaa"); - - //this destroys string, so no need for cleanup - ARC_Parser_Parse(parser, &tempString); - - ARC_CHECK(arc_errno == 0); - - - /* ~ cleanup ~ */ - ARC_Parser_Destroy(parser); -} - -ARC_TEST(Parser_Basic_ParseError){ - ARC_Parser *parser; - ARC_Parser_Create(&parser, &languageArray, TEST_Parser_InitLexerRulesFn, NULL, NULL, NULL); - - ARC_String *tempString; - - - /* ~ first test ~ */ - ARC_String_CreateWithStrlen(&tempString, "!myVar1"); - - //this destroys string, so no need for cleanup - ARC_Parser_Parse(parser, &tempString); - - ARC_CHECK(arc_errno == ARC_ERRNO_DATA); - - - /* ~ second test ~ */ - //check again with moved character - arc_errno = 0; - ARC_String_CreateWithStrlen(&tempString, "my!Var1"); - - //this destroys string, so no need for cleanup - ARC_Parser_Parse(parser, &tempString); - - ARC_CHECK(arc_errno == ARC_ERRNO_DATA); - - - /* ~ third test ~ */ - //check again with moved character - arc_errno = 0; - ARC_String_CreateWithStrlen(&tempString, "myVar1!"); - - //this destroys string, so no need for cleanup - ARC_Parser_Parse(parser, &tempString); - - ARC_CHECK(arc_errno == ARC_ERRNO_DATA); - - - /* ~ cleanup ~ */ - ARC_Parser_Destroy(parser); - - //reset for next test - arc_errno = 0; -} - -ARC_TEST(Parser_Basic_GetParsedValue){ - ARC_Parser *parser; - - ARC_ParserData_CreateFn createStringFn = TEST_ParserData_CreateStringFn; - ARC_ParserData_DestroyFn destroyStringFn = TEST_ParserData_DestroyStringFn; - - ARC_Parser_Create(&parser, &languageArray, TEST_Parser_InitLexerRulesFn, &createStringFn, &destroyStringFn, NULL); - - ARC_String *tempString; - - - /* ~ first test ~ */ - ARC_String_CreateWithStrlen(&tempString, "myvar1"); - - //this destroys string, so no need for cleanup - ARC_Parser_Parse(parser, &tempString); - - ARC_CHECK(arc_errno == 0); - - ARC_String *checkValue = (ARC_String *)ARC_Parser_GetData(parser); - ARC_CHECK(ARC_String_EqualsCStringWithStrlen(checkValue, "myvar1")); - - - /* ~ cleanup ~ */ - ARC_Parser_Destroy(parser); -} - -ARC_TEST(Parser_ParserLang_BasicVector){ - ARC_Vector *testLanguage; - ARC_Vector_Create(&testLanguage, NULL, NULL); - - ARC_Vector_Add(testLanguage, testTags + 0); - ARC_Vector_Add(testLanguage, testTags + 1); - ARC_Vector_Add(testLanguage, testTags + 2); - - ARC_Parser *parser; - ARC_Parser_CreateFromVector(&parser, testLanguage, TEST_Parser_InitLexerRulesFn, NULL, NULL, NULL); - - ARC_String *tempString; - ARC_String_CreateWithStrlen(&tempString, "variablename"); - - //this destroys string, so no need for cleanup - ARC_Parser_Parse(parser, &tempString); - - //cleanup - ARC_Parser_Destroy(parser); - ARC_Vector_Destroy(testLanguage); - - ARC_CHECK(arc_errno == 0); -} - -/* ~ parser tests ~ */ -void TEST_Parser_InitBasicLexerTokenRules(ARC_Lexer *lexer){ - //null - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_PARSER_TAG_LAMBDA, 0)); - - //alpha char - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(TEST_PARSER_ALPHA_LOWER_CHAR, 'a', 'z')); - ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(TEST_PARSER_ALPHA_UPPER_CHAR, 'A', 'Z')); -} - -uint32_t TEST_Parser_GetStringIdFn(ARC_String *string){ - if(ARC_String_EqualsCStringWithStrlen(string, "")){ - return TEST_PARSER_ALPHA_CHAR; - } - - if(ARC_String_EqualsCStringWithStrlen(string, "ALPHA_LOWER_CHAR")){ - return TEST_PARSER_ALPHA_LOWER_CHAR; - } - - if(ARC_String_EqualsCStringWithStrlen(string, "ALPHA_UPPER_CHAR")){ - return TEST_PARSER_ALPHA_UPPER_CHAR; - } - - return ~(uint32_t)0; -} - -void TEST_ParserData_CreateCharFn(void **data, ARC_ParserTagToken *parsedData, void *userData){ - if(parsedData == NULL){ - *data = NULL; - return; - } - - char *alphaChar = (char *)malloc(sizeof(char)); - - ARC_ParserTagToken *tagToken = (ARC_ParserTagToken *)ARC_Vector_Get(parsedData->tagTokens, 0); - *alphaChar = tagToken->token->data->data[0]; - - *data = (void *)alphaChar; -} - -void TEST_ParserData_DestroyCharFn(void *data, ARC_Bool clear, void *userData){ - if(data == NULL){ - return; - } - - free((char *)data); -} - -ARC_TEST(Parser_Parser_BasicCreateWithStringTest){ - ARC_Parser *parser; - - /* ~ create the language ~ */ - ARC_String *languageString; - ARC_String_CreateWithStrlen(&languageString, " -> ALPHA_LOWER_CHAR | ALPHA_UPPER_CHAR\n"); - - ARC_ParserData_CreateFn createCharFn = TEST_ParserData_CreateCharFn; - ARC_ParserData_DestroyFn destroyCharFn = TEST_ParserData_DestroyCharFn; - ARC_Parser_CreateFromString(&parser, languageString, TEST_Parser_InitBasicLexerTokenRules, TEST_Parser_GetStringIdFn, &createCharFn, &destroyCharFn, NULL); - - ARC_String_Destroy(languageString); - - ARC_CHECK(arc_errno == 0); - - - /* ~ check if a can be parsed ~ */ - ARC_String *tempString; - ARC_String_CreateWithStrlen(&tempString, "a"); - - ARC_Parser_Parse(parser, &tempString); - - char *data = (char *)ARC_Parser_GetData(parser); - - ARC_CHECK(*data == 'a'); - - ARC_Parser_ClearData(parser); - - - /* ~ check if Z can be parsed ~ */ - ARC_String_CreateWithStrlen(&tempString, "Z"); - - ARC_Parser_Parse(parser, &tempString); - - data = (char *)ARC_Parser_GetData(parser); - - ARC_CHECK(*data == 'Z'); - - ARC_Parser_ClearData(parser); - - - /* ~ check if 8 errors ~ */ - ARC_String_CreateWithStrlen(&tempString, "8"); - - ARC_Parser_Parse(parser, &tempString); - - data = (char *)ARC_Parser_GetData(parser); - - ARC_CHECK(arc_errno == ARC_ERRNO_DATA); - arc_errno = 0; - - ARC_Parser_ClearData(parser); - - - //cleanup - ARC_Parser_Destroy(parser); -} +//TODO: rewrite these tests. ARC_Config does use both the parser and lexer so for now (very temporary) its tests function for these ones + +//ARC_TEST(Parser_Init){ +// ARC_Parser *parser; +// ARC_Parser_Create(&parser, &languageArray, TEST_Parser_InitLexerRulesFn, NULL, NULL, NULL); +// +// ARC_Parser_Destroy(parser); +// +// ARC_CHECK(arc_errno == 0); +//} +// +//ARC_TEST(Parser_Basic_Parse){ +// ARC_Parser *parser; +// ARC_Parser_Create(&parser, &languageArray, TEST_Parser_InitLexerRulesFn, NULL, NULL, NULL); +// +// ARC_String *tempString; +// +// +// /* ~ first test ~ */ +// ARC_String_CreateWithStrlen(&tempString, "myvar1"); +// +// //this destroys string, so no need for cleanup +// ARC_Parser_Parse(parser, &tempString); +// +// ARC_CHECK(arc_errno == 0); +// +// +// /* ~ second test ~ */ +// ARC_String_CreateWithStrlen(&tempString, "z1xwvq"); +// +// //this destroys string, so no need for cleanup +// ARC_Parser_Parse(parser, &tempString); +// +// ARC_CHECK(arc_errno == 0); +// +// +// /* ~ third test ~ */ +// ARC_String_CreateWithStrlen(&tempString, "z1234"); +// +// //this destroys string, so no need for cleanup +// ARC_Parser_Parse(parser, &tempString); +// +// ARC_CHECK(arc_errno == 0); +// +// +// /* ~ fourth test ~ */ +// ARC_String_CreateWithStrlen(&tempString, "aaaaa"); +// +// //this destroys string, so no need for cleanup +// ARC_Parser_Parse(parser, &tempString); +// +// ARC_CHECK(arc_errno == 0); +// +// +// /* ~ cleanup ~ */ +// ARC_Parser_Destroy(parser); +//} +// +//ARC_TEST(Parser_Basic_ParseError){ +// ARC_Parser *parser; +// ARC_Parser_Create(&parser, &languageArray, TEST_Parser_InitLexerRulesFn, NULL, NULL, NULL); +// +// ARC_String *tempString; +// +// +// /* ~ first test ~ */ +// ARC_String_CreateWithStrlen(&tempString, "!myVar1"); +// +// //this destroys string, so no need for cleanup +// ARC_Parser_Parse(parser, &tempString); +// +// ARC_CHECK(arc_errno == ARC_ERRNO_DATA); +// +// +// /* ~ second test ~ */ +// //check again with moved character +// arc_errno = 0; +// ARC_String_CreateWithStrlen(&tempString, "my!Var1"); +// +// //this destroys string, so no need for cleanup +// ARC_Parser_Parse(parser, &tempString); +// +// ARC_CHECK(arc_errno == ARC_ERRNO_DATA); +// +// +// /* ~ third test ~ */ +// //check again with moved character +// arc_errno = 0; +// ARC_String_CreateWithStrlen(&tempString, "myVar1!"); +// +// //this destroys string, so no need for cleanup +// ARC_Parser_Parse(parser, &tempString); +// +// ARC_CHECK(arc_errno == ARC_ERRNO_DATA); +// +// +// /* ~ cleanup ~ */ +// ARC_Parser_Destroy(parser); +// +// //reset for next test +// arc_errno = 0; +//} +// +//ARC_TEST(Parser_Basic_GetParsedValue){ +// ARC_Parser *parser; +// +// ARC_ParserData_CreateFn createStringFn = TEST_ParserData_CreateStringFn; +// ARC_ParserData_DestroyFn destroyStringFn = TEST_ParserData_DestroyStringFn; +// +// ARC_Parser_Create(&parser, &languageArray, TEST_Parser_InitLexerRulesFn, &createStringFn, &destroyStringFn, NULL); +// +// ARC_String *tempString; +// +// +// /* ~ first test ~ */ +// ARC_String_CreateWithStrlen(&tempString, "myvar1"); +// +// //this destroys string, so no need for cleanup +// ARC_Parser_Parse(parser, &tempString); +// +// ARC_CHECK(arc_errno == 0); +// +// ARC_String *checkValue = (ARC_String *)ARC_Parser_GetData(parser); +// ARC_CHECK(ARC_String_EqualsCStringWithStrlen(checkValue, "myvar1")); +// +// +// /* ~ cleanup ~ */ +// ARC_Parser_Destroy(parser); +//} +// +//ARC_TEST(Parser_ParserLang_BasicVector){ +// ARC_Vector *testLanguage; +// ARC_Vector_Create(&testLanguage, NULL, NULL); +// +// ARC_Vector_Add(testLanguage, testTags + 0); +// ARC_Vector_Add(testLanguage, testTags + 1); +// ARC_Vector_Add(testLanguage, testTags + 2); +// +// ARC_Parser *parser; +// ARC_Parser_CreateFromVector(&parser, testLanguage, TEST_Parser_InitLexerRulesFn, NULL, NULL, NULL); +// +// ARC_String *tempString; +// ARC_String_CreateWithStrlen(&tempString, "variablename"); +// +// //this destroys string, so no need for cleanup +// ARC_Parser_Parse(parser, &tempString); +// +// //cleanup +// ARC_Parser_Destroy(parser); +// ARC_Vector_Destroy(testLanguage); +// +// ARC_CHECK(arc_errno == 0); +//} +// +///* ~ parser tests ~ */ +//void TEST_Parser_InitBasicLexerTokenRules(ARC_Lexer *lexer){ +// //null +// ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_PARSER_TAG_LAMBDA, 0)); +// +// //alpha char +// ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(TEST_PARSER_ALPHA_LOWER_CHAR, 'a', 'z')); +// ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharOrBetween(TEST_PARSER_ALPHA_UPPER_CHAR, 'A', 'Z')); +//} +// +//uint32_t TEST_Parser_GetStringIdFn(ARC_String *string){ +// if(ARC_String_EqualsCStringWithStrlen(string, "")){ +// return TEST_PARSER_ALPHA_CHAR; +// } +// +// if(ARC_String_EqualsCStringWithStrlen(string, "ALPHA_LOWER_CHAR")){ +// return TEST_PARSER_ALPHA_LOWER_CHAR; +// } +// +// if(ARC_String_EqualsCStringWithStrlen(string, "ALPHA_UPPER_CHAR")){ +// return TEST_PARSER_ALPHA_UPPER_CHAR; +// } +// +// return ~(uint32_t)0; +//} +// +//void TEST_ParserData_CreateCharFn(void **data, ARC_ParserTagToken *parsedData, void *userData){ +// if(parsedData == NULL){ +// *data = NULL; +// return; +// } +// +// char *alphaChar = (char *)malloc(sizeof(char)); +// +// ARC_ParserTagToken *tagToken = (ARC_ParserTagToken *)ARC_Vector_Get(parsedData->tagTokens, 0); +// *alphaChar = tagToken->token->data->data[0]; +// +// *data = (void *)alphaChar; +//} +// +//void TEST_ParserData_DestroyCharFn(void *data, ARC_Bool clear, void *userData){ +// if(data == NULL){ +// return; +// } +// +// free((char *)data); +//} +// +//ARC_TEST(Parser_Parser_BasicCreateWithStringTest){ +// ARC_Parser *parser; +// +// /* ~ create the language ~ */ +// ARC_String *languageString; +// ARC_String_CreateWithStrlen(&languageString, " -> ALPHA_LOWER_CHAR | ALPHA_UPPER_CHAR\n"); +// +// ARC_ParserData_CreateFn createCharFn = TEST_ParserData_CreateCharFn; +// ARC_ParserData_DestroyFn destroyCharFn = TEST_ParserData_DestroyCharFn; +// ARC_Parser_CreateFromString(&parser, languageString, TEST_Parser_InitBasicLexerTokenRules, TEST_Parser_GetStringIdFn, &createCharFn, &destroyCharFn, NULL); +// +// ARC_String_Destroy(languageString); +// +// ARC_CHECK(arc_errno == 0); +// +// +// /* ~ check if a can be parsed ~ */ +// ARC_String *tempString; +// ARC_String_CreateWithStrlen(&tempString, "a"); +// +// ARC_Parser_Parse(parser, &tempString); +// +// char *data = (char *)ARC_Parser_GetData(parser); +// +// ARC_CHECK(*data == 'a'); +// +// ARC_Parser_ClearData(parser); +// +// +// /* ~ check if Z can be parsed ~ */ +// ARC_String_CreateWithStrlen(&tempString, "Z"); +// +// ARC_Parser_Parse(parser, &tempString); +// +// data = (char *)ARC_Parser_GetData(parser); +// +// ARC_CHECK(*data == 'Z'); +// +// ARC_Parser_ClearData(parser); +// +// +// /* ~ check if 8 errors ~ */ +// ARC_String_CreateWithStrlen(&tempString, "8"); +// +// ARC_Parser_Parse(parser, &tempString); +// +// data = (char *)ARC_Parser_GetData(parser); +// +// ARC_CHECK(arc_errno == ARC_ERRNO_DATA); +// arc_errno = 0; +// +// ARC_Parser_ClearData(parser); +// +// +// //cleanup +// ARC_Parser_Destroy(parser); +//}