parser fixed (still probably needs more testing, but current tests work), parserlang still not working

This commit is contained in:
herbglitch 2024-11-30 01:14:55 -07:00
parent 6d64a17b1d
commit 84c4dffc85
4 changed files with 153 additions and 161 deletions

View file

@ -15,21 +15,6 @@ extern "C" {
*/ */
typedef struct ARC_Parser ARC_Parser; typedef struct ARC_Parser ARC_Parser;
/**
* @brief TODO: write this
*/
typedef void (* ARC_ParserData_CreateFn)(void **data);
/**
* @brief TODO: write this
*/
typedef void (* ARC_ParserData_DestroyFn)(void *data);
/**
* @brief TODO: write this
*/
typedef void (* ARC_ParserTag_AddDataFn)(void **data, uint32_t tagId, uint32_t tagIndex, ARC_LexerToken *token, void *userData);
/** /**
* @brief a langue tag type for the parser //TODO: explain this better * @brief a langue tag type for the parser //TODO: explain this better
*/ */
@ -41,7 +26,11 @@ typedef struct ARC_ParserTag {
} ARC_ParserTag; } ARC_ParserTag;
/* /*
* @brief * @brief a parser type used inside of the parser data create function
*
* @note there are no public creation and destruction functions for this type as it is only ment to be used within the creation callback
* @note if the parser tag token is a token then tagTokens will be NULL
* @note if the parser tag token is a tag then token will be NULL
*/ */
typedef struct ARC_ParserTagToken { typedef struct ARC_ParserTagToken {
uint32_t id; uint32_t id;
@ -57,6 +46,16 @@ typedef struct ARC_ParserTagToken {
*/ */
typedef void (* ARC_Parser_InitLexerRulesFn)(ARC_Lexer *lexer); typedef void (* ARC_Parser_InitLexerRulesFn)(ARC_Lexer *lexer);
/**
* @brief TODO: write this
*/
typedef void (* ARC_ParserData_CreateFn)(void **data, ARC_ParserTagToken *parsedData, void *userData);
/**
* @brief TODO: write this
*/
typedef void (* ARC_ParserData_DestroyFn)(void *data);
/** /**
* @brief creates an ARC_Parser type * @brief creates an ARC_Parser type
* *
@ -77,7 +76,7 @@ typedef void (* ARC_Parser_InitLexerRulesFn)(ARC_Lexer *lexer);
* @param[in] language an arry of ARC_ParserLanguageTags defining a langauge * @param[in] language an arry of ARC_ParserLanguageTags defining a langauge
* @param[in] initLexerRulesFn a callback used to initalize the token rules the lexer within the parser will use * @param[in] initLexerRulesFn a callback used to initalize the token rules the lexer within the parser will use
*/ */
void ARC_Parser_Create(ARC_Parser **parser, ARC_Array *language, ARC_Parser_InitLexerRulesFn initLexerRulesFn, ARC_ParserData_CreateFn *createDataFn, ARC_ParserData_DestroyFn *destroyDataFn); void ARC_Parser_Create(ARC_Parser **parser, ARC_Array *language, ARC_Parser_InitLexerRulesFn initLexerRulesFn, ARC_ParserData_CreateFn *createDataFn, void *createUserData, ARC_ParserData_DestroyFn *destroyDataFn);
/** /**
* @brief creates an ARC_Parser type from an arc vector * @brief creates an ARC_Parser type from an arc vector
@ -86,7 +85,7 @@ void ARC_Parser_Create(ARC_Parser **parser, ARC_Array *language, ARC_Parser_Init
* @param[in] language an vector of ARC_ParserLanguageTags defining a langauge * @param[in] language an vector of ARC_ParserLanguageTags defining a langauge
* @param[in] initLexerRulesFn a callback used to initalize the token rules the lexer within the parser will use * @param[in] initLexerRulesFn a callback used to initalize the token rules the lexer within the parser will use
*/ */
void ARC_Parser_CreateFromVector(ARC_Parser **parser, ARC_Vector *language, ARC_Parser_InitLexerRulesFn initLexerRulesFn, ARC_ParserData_CreateFn *createDataFn, ARC_ParserData_DestroyFn *destroyDataFn); void ARC_Parser_CreateFromVector(ARC_Parser **parser, ARC_Vector *language, ARC_Parser_InitLexerRulesFn initLexerRulesFn, ARC_ParserData_CreateFn *createDataFn, void *createUserData, ARC_ParserData_DestroyFn *destroyDataFn);
/** /**
* @brief creates an ARC_Parser type from a string * @brief creates an ARC_Parser type from a string

View file

@ -12,12 +12,14 @@ struct ARC_Parser {
ARC_Lexer *lexer; ARC_Lexer *lexer;
void *data; void *data;
void *createUserData;
ARC_ParserData_CreateFn *createDataFn; ARC_ParserData_CreateFn *createDataFn;
ARC_ParserData_DestroyFn *destroyDataFn; ARC_ParserData_DestroyFn *destroyDataFn;
}; };
void ARC_Parser_Create(ARC_Parser **parser, ARC_Array *language, ARC_Parser_InitLexerRulesFn initLexerRulesFn, ARC_ParserData_CreateFn *createDataFn, ARC_ParserData_DestroyFn *destroyDataFn){ void ARC_Parser_Create(ARC_Parser **parser, ARC_Array *language, ARC_Parser_InitLexerRulesFn initLexerRulesFn, ARC_ParserData_CreateFn *createDataFn, void *createUserData, ARC_ParserData_DestroyFn *destroyDataFn){
*parser = (ARC_Parser *)malloc(sizeof(ARC_Parser)); *parser = (ARC_Parser *)malloc(sizeof(ARC_Parser));
//set the language size to 0 and data to NULL in case the language is NULL //set the language size to 0 and data to NULL in case the language is NULL
@ -63,7 +65,6 @@ void ARC_Parser_Create(ARC_Parser **parser, ARC_Array *language, ARC_Parser_Init
if(createDataFn != NULL){ if(createDataFn != NULL){
(*parser)->createDataFn = (ARC_ParserData_CreateFn *)malloc(sizeof(ARC_ParserData_CreateFn)); (*parser)->createDataFn = (ARC_ParserData_CreateFn *)malloc(sizeof(ARC_ParserData_CreateFn));
*((*parser)->createDataFn) = *createDataFn; *((*parser)->createDataFn) = *createDataFn;
(*createDataFn)(&((*parser)->data));
} }
(*parser)->destroyDataFn = NULL; (*parser)->destroyDataFn = NULL;
@ -73,7 +74,7 @@ void ARC_Parser_Create(ARC_Parser **parser, ARC_Array *language, ARC_Parser_Init
} }
} }
void ARC_Parser_CreateFromVector(ARC_Parser **parser, ARC_Vector *language, ARC_Parser_InitLexerRulesFn initLexerRulesFn, ARC_ParserData_CreateFn *createDataFn, ARC_ParserData_DestroyFn *destroyDataFn){ void ARC_Parser_CreateFromVector(ARC_Parser **parser, ARC_Vector *language, ARC_Parser_InitLexerRulesFn initLexerRulesFn, ARC_ParserData_CreateFn *createDataFn, void *createUserData, ARC_ParserData_DestroyFn *destroyDataFn){
//creates the variables to copy the vector into //creates the variables to copy the vector into
const uint32_t languageSize = ARC_Vector_GetSize(language); const uint32_t languageSize = ARC_Vector_GetSize(language);
ARC_ParserTag languageArray[languageSize]; ARC_ParserTag languageArray[languageSize];
@ -90,7 +91,7 @@ void ARC_Parser_CreateFromVector(ARC_Parser **parser, ARC_Vector *language, ARC_
}; };
//create the parser //create the parser
ARC_Parser_Create(parser, &languageAsArray, initLexerRulesFn, createDataFn, destroyDataFn); ARC_Parser_Create(parser, &languageAsArray, initLexerRulesFn, createDataFn, createUserData, destroyDataFn);
} }
void ARC_Parser_CreateFromString(ARC_Parser **parser, ARC_String *languageString, ARC_Parser_InitLexerRulesFn initLexerRulesFn){ void ARC_Parser_CreateFromString(ARC_Parser **parser, ARC_String *languageString, ARC_Parser_InitLexerRulesFn initLexerRulesFn){
@ -129,13 +130,39 @@ void ARC_Parser_Destroy(ARC_Parser *parser){
free(parser); free(parser);
} }
//private creation function for ARC_ParserTagToken type
//note: token and tagTokens will be set to null, it is safe to create tagTokens outside of this as the destructor will clean it up
void ARC_ParserTagToken_Create(ARC_ParserTagToken **tagToken, uint32_t id){
*tagToken = (ARC_ParserTagToken *)malloc(sizeof(ARC_ParserTagToken));
(*tagToken)->id = id;
(*tagToken)->token = NULL;
(*tagToken)->tagTokens = NULL;
}
//private destroy function for ARC_ParserTagToken type
void ARC_ParserTagToken_Destroy(ARC_ParserTagToken *tagToken){
//destroy the tag token vector
if(tagToken->tagTokens != NULL){
ARC_Vector_Destroy(tagToken->tagTokens);
}
free(tagToken);
}
//private function to cleanup a parser tag token from a vector
void ARC_ParserTagToken_VectorDestroyDataFn(void *data){
//we can just use the destroy function with casted data
ARC_ParserTagToken_Destroy((ARC_ParserTagToken *)data);
}
//private recusive function to parse a tag //private recusive function to parse a tag
ARC_Bool ARC_Parser_ParseTag(ARC_Parser *parser, uint32_t *lexerIndex, uint32_t tagId){ ARC_Bool ARC_Parser_ParseTag(ARC_Parser *parser, ARC_ParserTagToken *tagToken, uint32_t *lexerIndex){
//get the current tag //get the current tag
ARC_ParserTag *tag = NULL; ARC_ParserTag *tag = NULL;
for(uint32_t index = 0; index < parser->language.size; index++){ for(uint32_t index = 0; index < parser->language.size; index++){
ARC_ParserTag *foundTag = ((ARC_ParserTag *)parser->language.data) + index; ARC_ParserTag *foundTag = ((ARC_ParserTag *)parser->language.data) + index;
if(foundTag->tagId == tagId){ if(foundTag->tagId == tagToken->id){
tag = foundTag; tag = foundTag;
break; break;
} }
@ -144,43 +171,55 @@ ARC_Bool ARC_Parser_ParseTag(ARC_Parser *parser, uint32_t *lexerIndex, uint32_t
//if the tag was not found can't do much, so throw an error //if the tag was not found can't do much, so throw an error
if(tag == NULL){ if(tag == NULL){
arc_errno = ARC_ERRNO_NULL; arc_errno = ARC_ERRNO_NULL;
ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_Parser_ParseTag(parser, subdata, tagId), could not find tag with id: %u", tagId); ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_Parser_ParseTag(parser, subdata, tagId), could not find tag with id: %u", tagToken->id);
return ARC_False; return ARC_False;
} }
//create a vector of found tokens to use if a rule is validated, a comparison function is not needed as it will be iterated through, the destroy function is not needed as well because they will be pointers to lexer tokens (the lexer owns the tokens) //create a vector of tag token to use if a rule is validated, a comparison function is not needed as it will be iterated through
ARC_Vector *foundTokens; ARC_Vector_DestroyDataFn destroyTokenTagFn = ARC_ParserTagToken_VectorDestroyDataFn;
ARC_Vector_Create(&foundTokens, NULL, NULL); ARC_Vector_Create(&(tagToken->tagTokens), NULL, &destroyTokenTagFn);
//loop through each or section of the tags and tokens //loop through each or section of the tags and tokens
for(uint32_t orIndex = 0; orIndex < tag->tokensOrTagsSize; orIndex++){ for(uint32_t orIndex = 0; orIndex < tag->tokensOrTagsSize; orIndex++){
//reset the tokens for each or index //reset the tag tokens for each or index
ARC_Vector_Clear(foundTokens); ARC_Vector_Clear(tagToken->tagTokens);
//loop through each token or tag to check if the lexed data matches //loop through each token or tag to check if the lexed data matches
uint32_t lexerCheckIndex = *lexerIndex; uint32_t lexerCheckIndex = *lexerIndex;
ARC_Bool foundRule = ARC_True; ARC_Bool foundRule = ARC_True;
for(uint32_t tokenOrTagIndex = 1; tokenOrTagIndex < tag->tokensOrTags[orIndex][0] + 1; tokenOrTagIndex++){ for(uint32_t tokenOrTagIndex = 1; tokenOrTagIndex < tag->tokensOrTags[orIndex][0] + 1; tokenOrTagIndex++){
//get next tag id to check
uint32_t nextTagId = tag->tokensOrTags[orIndex][tokenOrTagIndex];
//check if it is lambda (can return safely) //check if it is lambda (can return safely)
if(tag->tokensOrTags[orIndex][tokenOrTagIndex] == ARC_PARSER_TAG_LAMBDA){ if(nextTagId == ARC_PARSER_TAG_LAMBDA){
break; break;
} }
//if the value isn't a token it is a tag, so recurs if it isn't a token //if the value isn't a token it is a tag, so recurs if it isn't a token
ARC_Bool isToken = ARC_Lexer_IsTokenId(parser->lexer, tag->tokensOrTags[orIndex][tokenOrTagIndex]); ARC_Bool isToken = ARC_Lexer_IsTokenId(parser->lexer, nextTagId);
if(isToken == ARC_False){ if(isToken == ARC_False){
//create a temporary lexer index in case the rule does not exist //create a temporary lexer index in case the rule does not exist
uint32_t tempLexerCheckIndex = lexerCheckIndex; uint32_t tempLexerCheckIndex = lexerCheckIndex;
//check if the tag works if not break to continue checking next or //create tag token for if the rule works
uint32_t nextTagId = tag->tokensOrTags[orIndex][tokenOrTagIndex]; ARC_ParserTagToken *nextTagToken;
foundRule = ARC_Parser_ParseTag(parser, &tempLexerCheckIndex, nextTagId); ARC_ParserTagToken_Create(&nextTagToken, nextTagId);
//check if the tag works if not break to continue checking next or index
foundRule = ARC_Parser_ParseTag(parser, nextTagToken, &tempLexerCheckIndex);
if(foundRule == ARC_False){ if(foundRule == ARC_False){
//clean up the tag token
ARC_ParserTagToken_Destroy(nextTagToken);
break; break;
} }
//add the tag token because rule was found
ARC_Vector_Add(tagToken->tagTokens, nextTagToken);
//increase the lexer check index as a recursed rule was found, and continue checking //increase the lexer check index as a recursed rule was found, and continue checking
lexerCheckIndex = tempLexerCheckIndex; lexerCheckIndex = tempLexerCheckIndex;
continue; continue;
} }
@ -201,24 +240,27 @@ ARC_Bool ARC_Parser_ParseTag(ARC_Parser *parser, uint32_t *lexerIndex, uint32_t
break; break;
} }
//the rule was a match so add it to the found tokens //the rule was a match so create a tag token to store the token in
ARC_Vector_Add(foundTokens, (void *)token); ARC_ParserTagToken *nextTagToken;
ARC_ParserTagToken_Create(&nextTagToken, nextTagId);
nextTagToken->token = token;
//add the token to the tag tokens
ARC_Vector_Add(tagToken->tagTokens, nextTagToken);
} }
//if the rule is found we don't need to check anymore so we can return out //if the rule is found we don't need to check anymore so we can return out
if(foundRule == ARC_True){ if(foundRule == ARC_True){
*lexerIndex = lexerCheckIndex; *lexerIndex = lexerCheckIndex;
//free the found tokens vector
ARC_Vector_Destroy(foundTokens);
//cleanup //cleanup
return ARC_True; return ARC_True;
} }
} }
//cleanup //cleanup
ARC_Vector_Destroy(foundTokens); ARC_Vector_Destroy(tagToken->tagTokens);
tagToken->tagTokens = NULL;
//no rule was found, so return false //no rule was found, so return false
return ARC_False; return ARC_False;
@ -243,11 +285,25 @@ void ARC_Parser_Parse(ARC_Parser *parser, ARC_String **data){
uint32_t lexerIndex = 0; uint32_t lexerIndex = 0;
ARC_ParserTag *startTag = parser->language.data; ARC_ParserTag *startTag = parser->language.data;
//setup a tag token that will be passed to the creation callback on success
ARC_ParserTagToken *tagToken;
ARC_ParserTagToken_Create(&tagToken, startTag->tagId);
//TODO: handle error checks for if parsing fails //TODO: handle error checks for if parsing fails
//recursivly parse from the inital start tag //recursivly parse from the inital start tag
ARC_Bool parsed = ARC_Parser_ParseTag(parser, &lexerIndex, startTag->tagId); ARC_Bool parsed = ARC_Parser_ParseTag(parser, tagToken, &lexerIndex);
ARC_Bool allTokensParsed = lexerIndex == ARC_Lexer_GetTokensSize(parser->lexer); ARC_Bool allTokensParsed = lexerIndex == ARC_Lexer_GetTokensSize(parser->lexer);
//create the data if the creation callback exists
if(parser->createDataFn != NULL){
(*(parser->createDataFn))(&(parser->data), tagToken, parser->createUserData);
}
//cleanup
ARC_ParserTagToken_Destroy(tagToken);
ARC_Lexer_Clear(parser->lexer); ARC_Lexer_Clear(parser->lexer);
//error if anything went wrong
if(parsed == ARC_False || allTokensParsed == ARC_False || arc_errno){ if(parsed == ARC_False || allTokensParsed == ARC_False || arc_errno){
arc_errno = ARC_ERRNO_DATA; arc_errno = ARC_ERRNO_DATA;
ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_Parser_Parse(parser, data), could not parse the given data at lexer index: %u", lexerIndex); ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_Parser_Parse(parser, data), could not parse the given data at lexer index: %u", lexerIndex);
@ -260,8 +316,13 @@ void ARC_Parser_ParseFile(ARC_Parser *parser, ARC_String *path){
} }
void ARC_Parser_ClearData(ARC_Parser *parser){ void ARC_Parser_ClearData(ARC_Parser *parser){
(*(parser->destroyDataFn))(parser->data); //check if that data exists and the destructor exists to make sure they can be run
(*(parser->createDataFn))(parser->data); if(parser->data != NULL && parser->destroyDataFn != NULL){
(*(parser->destroyDataFn))(parser->data);
}
//TODO: might want to error here
parser->data = NULL;
} }
void *ARC_Parser_GetData(ARC_Parser *parser){ void *ARC_Parser_GetData(ARC_Parser *parser){

View file

@ -28,23 +28,6 @@
/* /*
* @brief * @brief
*/ */
typedef struct ARC_ParserLangLineData {
ARC_Vector *body;
} ARC_ParserLangLineData;
typedef struct ARC_ParserLangBodyData {
ARC_String *tagName;
ARC_Vector *arguments;
} ARC_ParserLangBodyData;
typedef struct ARC_ParserLangArgumentData {
ARC_Vector *tagsOrConstants;
} ARC_ParserLangArgumentData;
typedef struct ARC_ParserLangVectorStringData {
ARC_String *string;
ARC_Vector *vector;
} ARC_ParserLangVectorStringData;
//private function to initalize the lexer rules for the language //private function to initalize the lexer rules for the language
void ARC_ParserLang_InitLexerRulesFn(ARC_Lexer *lexer){ void ARC_ParserLang_InitLexerRulesFn(ARC_Lexer *lexer){
@ -94,7 +77,7 @@ void ARC_ParserLang_VectorDestroyParserTagFn(void *data){
} }
//private function to create the saved data for the language //private function to create the saved data for the language
void ARC_ParserLang_CreateDataFn(void **data){ void ARC_ParserLang_CreateDataFn(void **data, ARC_ParserTagToken *parsedData, void *userData){
//function callback to cleanup added tags //function callback to cleanup added tags
ARC_Vector_DestroyDataFn destroyParserTagFn = ARC_ParserLang_VectorDestroyParserTagFn; ARC_Vector_DestroyDataFn destroyParserTagFn = ARC_ParserLang_VectorDestroyParserTagFn;
@ -107,48 +90,6 @@ void ARC_ParserLang_DestroyDataFn(void *data){
ARC_Vector_Destroy(data); ARC_Vector_Destroy(data);
} }
//private function to add char to constant name
void ARC_ParserLang_AddCharFn(void **data, uint32_t tagId, uint32_t tagIndex, ARC_LexerToken *token, void *userData){
if(userData == NULL){
return;
}
//recast the addData to make it easier to use
ARC_String **variable = (ARC_String **)userData;
if(*variable == NULL){
return;
}
//create the const string if it is null
if(variable == NULL){
//this will be freed in the main parser lang add
ARC_String_Create(variable, NULL, 0);
}
ARC_String_Append(variable, token->data);
}
//private function to get details from a constant
void ARC_ParserLang_AddFirstCharFn(void **data, uint32_t tagId, uint32_t tagIndex, ARC_LexerToken *token, void *userData){
if(userData == NULL){
return;
}
//recast the addData to make it easier to use
ARC_ParserLangVectorStringData *vectorStringData = (ARC_ParserLangVectorStringData *)userData;
//add the first character to the temp const
ARC_String *tokenData = NULL;
ARC_String_Copy(&tokenData, token->data);
ARC_String_Append(&tokenData, vectorStringData->string);
//cleanup the string as it will be added to the vector
ARC_String_Destroy(vectorStringData->string);
vectorStringData->string = NULL;
ARC_Vector_Add(vectorStringData->vector, tokenData);
}
void ARC_Parser_CreateAsParserLang(ARC_Parser **parser){ void ARC_Parser_CreateAsParserLang(ARC_Parser **parser){
//<line> -> <body> NEWLINE <line> | <body> | NEWLINE <line> | LAMBDA //<line> -> <body> NEWLINE <line> | <body> | NEWLINE <line> | LAMBDA
uint32_t *line[] = { (uint32_t[]){ 3, ARC_PARSERLANG_BODY, ARC_PARSERLANG_TOKEN_NEWLINE_ID, ARC_PARSERLANG_LINE }, (uint32_t[]){ 1, ARC_PARSERLANG_BODY }, (uint32_t[]){ 2, ARC_PARSERLANG_TOKEN_NEWLINE_ID, ARC_PARSERLANG_LINE }, (uint32_t[]){ 1, ARC_PARSERLANG_LAMBDA } }; uint32_t *line[] = { (uint32_t[]){ 3, ARC_PARSERLANG_BODY, ARC_PARSERLANG_TOKEN_NEWLINE_ID, ARC_PARSERLANG_LINE }, (uint32_t[]){ 1, ARC_PARSERLANG_BODY }, (uint32_t[]){ 2, ARC_PARSERLANG_TOKEN_NEWLINE_ID, ARC_PARSERLANG_LINE }, (uint32_t[]){ 1, ARC_PARSERLANG_LAMBDA } };
@ -214,5 +155,5 @@ void ARC_Parser_CreateAsParserLang(ARC_Parser **parser){
ARC_ParserData_DestroyFn destroyDataFn = ARC_ParserLang_DestroyDataFn; ARC_ParserData_DestroyFn destroyDataFn = ARC_ParserLang_DestroyDataFn;
//TODO: add the create, destroy, and add callbacks //TODO: add the create, destroy, and add callbacks
ARC_Parser_Create(parser, &parserLanguageArray, ARC_ParserLang_InitLexerRulesFn, &createDataFn, &destroyDataFn); ARC_Parser_Create(parser, &parserLanguageArray, ARC_ParserLang_InitLexerRulesFn, &createDataFn, NULL, &destroyDataFn);
} }

View file

@ -13,36 +13,32 @@
#define VARIABLE_NAME 24 #define VARIABLE_NAME 24
#define VARIABLE 25 #define VARIABLE 25
void TEST_ParserData_CreateStringFn(void **data){ void TEST_ParserData_RecurseStringAdd(ARC_String **data, ARC_ParserTagToken *tagToken){
if(tagToken->token != NULL){
ARC_String_Append(data, tagToken->token->data);
return;
}
//TODO: probs don't need this
if(tagToken->tagTokens == NULL){
return;
}
for(uint32_t index = 0; index < ARC_Vector_GetSize(tagToken->tagTokens); index++){
TEST_ParserData_RecurseStringAdd(data, (ARC_ParserTagToken *)ARC_Vector_Get(tagToken->tagTokens, index));
}
}
void TEST_ParserData_CreateStringFn(void **data, ARC_ParserTagToken *parsedData, void *userData){
ARC_String_Create((ARC_String **)data, NULL, 0); ARC_String_Create((ARC_String **)data, NULL, 0);
TEST_ParserData_RecurseStringAdd((ARC_String **)data, parsedData);
} }
void TEST_ParserData_DestroyStringFn(void *data){ void TEST_ParserData_DestroyStringFn(void *data){
ARC_String_Destroy((ARC_String *)data); ARC_String_Destroy((ARC_String *)data);
} }
//for this very basic example, the tagId does not matter
void TEST_ParserTag_AddFirstCharFn(void **data, uint32_t tagId, uint32_t tagIndex, ARC_LexerToken *token, void *userData){
if(*data == NULL){
return;
}
ARC_String *tokenData = NULL;
ARC_String_Copy(&tokenData, token->data);
ARC_String_Append(&tokenData, *data);
ARC_String_Destroy(*data);
*data = tokenData;
}
//for this very basic example, the tagId does not matter
void TEST_ParserTag_AddCharFn(void **data, uint32_t tagId, uint32_t tagIndex, ARC_LexerToken *token, void *userData){
if(*data == NULL){
return;
}
ARC_String_Append((ARC_String **)data, token->data);
}
uint32_t *charOrNumTokens[] = { (uint32_t[]){ 1, CHAR }, (uint32_t[]){ 1, NUM } }; uint32_t *charOrNumTokens[] = { (uint32_t[]){ 1, CHAR }, (uint32_t[]){ 1, NUM } };
uint32_t *variableNameTags[] = { (uint32_t[]){ 2, CHAR_OR_NUM, VARIABLE_NAME }, (uint32_t[]){ 1, LAMBDA } }; uint32_t *variableNameTags[] = { (uint32_t[]){ 2, CHAR_OR_NUM, VARIABLE_NAME }, (uint32_t[]){ 1, LAMBDA } };
uint32_t *variableTokensOrTags[] = { (uint32_t[]){ 2, CHAR, VARIABLE_NAME } }; uint32_t *variableTokensOrTags[] = { (uint32_t[]){ 2, CHAR, VARIABLE_NAME } };
@ -51,8 +47,6 @@ uint32_t *variableTokensOrTags[] = { (uint32_t[]){ 2, CHAR, VARIABLE_NAME } };
ARC_ParserData_CreateFn createStringFn = TEST_ParserData_CreateStringFn; ARC_ParserData_CreateFn createStringFn = TEST_ParserData_CreateStringFn;
ARC_ParserData_DestroyFn destroyStringFn = TEST_ParserData_DestroyStringFn; ARC_ParserData_DestroyFn destroyStringFn = TEST_ParserData_DestroyStringFn;
ARC_ParserTag_AddDataFn addCharFn = TEST_ParserTag_AddCharFn;
ARC_ParserTag_AddDataFn addFirstCharFn = TEST_ParserTag_AddFirstCharFn;
ARC_ParserTag testTags[3] = { ARC_ParserTag testTags[3] = {
{ {
@ -83,8 +77,7 @@ void TEST_Parser_InitLexerRulesFn(ARC_Lexer *lexer){
ARC_TEST(Parser_Init){ ARC_TEST(Parser_Init){
ARC_Parser *parser; ARC_Parser *parser;
ARC_Parser_Create(&parser, &languageArray, TEST_Parser_InitLexerRulesFn, NULL, NULL, NULL);
ARC_Parser_Create(&parser, &languageArray, TEST_Parser_InitLexerRulesFn, NULL, NULL);
ARC_Parser_Destroy(parser); ARC_Parser_Destroy(parser);
@ -93,8 +86,8 @@ ARC_TEST(Parser_Init){
ARC_TEST(Parser_Basic_Parse){ ARC_TEST(Parser_Basic_Parse){
ARC_Parser *parser; ARC_Parser *parser;
ARC_Parser_Create(&parser, &languageArray, TEST_Parser_InitLexerRulesFn, NULL, NULL, NULL);
ARC_Parser_Create(&parser, &languageArray, TEST_Parser_InitLexerRulesFn, NULL, NULL);
ARC_String *tempString; ARC_String *tempString;
@ -140,8 +133,7 @@ ARC_TEST(Parser_Basic_Parse){
ARC_TEST(Parser_Basic_ParseError){ ARC_TEST(Parser_Basic_ParseError){
ARC_Parser *parser; ARC_Parser *parser;
ARC_Parser_Create(&parser, &languageArray, TEST_Parser_InitLexerRulesFn, NULL, NULL, NULL);
ARC_Parser_Create(&parser, &languageArray, TEST_Parser_InitLexerRulesFn, NULL, NULL);
ARC_String *tempString; ARC_String *tempString;
@ -186,8 +178,7 @@ ARC_TEST(Parser_Basic_ParseError){
ARC_TEST(Parser_Basic_GetParsedValue){ ARC_TEST(Parser_Basic_GetParsedValue){
ARC_Parser *parser; ARC_Parser *parser;
ARC_Parser_Create(&parser, &languageArray, TEST_Parser_InitLexerRulesFn, &createStringFn, NULL, &destroyStringFn);
ARC_Parser_Create(&parser, &languageArray, TEST_Parser_InitLexerRulesFn, &createStringFn, &destroyStringFn);
ARC_String *tempString; ARC_String *tempString;
@ -223,26 +214,26 @@ ARC_TEST(Parser_ParserLang_BasicTest){
ARC_CHECK(arc_errno == 0); ARC_CHECK(arc_errno == 0);
} }
ARC_TEST(Parser_ParserLang_BasicVector){ //ARC_TEST(Parser_ParserLang_BasicVector){
ARC_Vector *testLanguage; // ARC_Vector *testLanguage;
ARC_Vector_Create(&testLanguage, NULL, NULL); // ARC_Vector_Create(&testLanguage, NULL, NULL);
//
ARC_Vector_Add(testLanguage, testTags + 0); // ARC_Vector_Add(testLanguage, testTags + 0);
ARC_Vector_Add(testLanguage, testTags + 1); // ARC_Vector_Add(testLanguage, testTags + 1);
ARC_Vector_Add(testLanguage, testTags + 2); // ARC_Vector_Add(testLanguage, testTags + 2);
//
ARC_Parser *parser; // ARC_Parser *parser;
ARC_Parser_CreateFromVector(&parser, testLanguage, TEST_Parser_InitLexerRulesFn, NULL, NULL); // ARC_Parser_CreateFromVector(&parser, testLanguage, TEST_Parser_InitLexerRulesFn, NULL, NULL);
//
ARC_String *tempString; // ARC_String *tempString;
ARC_String_CreateWithStrlen(&tempString, "variablename"); // ARC_String_CreateWithStrlen(&tempString, "variablename");
//
//this destroys string, so no need for cleanup // //this destroys string, so no need for cleanup
ARC_Parser_Parse(parser, &tempString); // ARC_Parser_Parse(parser, &tempString);
//
//cleanup // //cleanup
ARC_Parser_Destroy(parser); // ARC_Parser_Destroy(parser);
ARC_Vector_Destroy(testLanguage); // ARC_Vector_Destroy(testLanguage);
//
ARC_CHECK(arc_errno == 0); // ARC_CHECK(arc_errno == 0);
} //}