fixed double free of vector and parserlang and creating a parser by string should work now

This commit is contained in:
herbglitch 2024-12-04 00:54:24 -07:00
parent 5a5eaabc14
commit 4c3d357cb9
12 changed files with 298 additions and 82 deletions

View file

@ -486,8 +486,6 @@ void ARC_Lexer_InitBasicTokenRules(ARC_Lexer *lexer){
ARC_String_CreateWithStrlen(&whitespaceString, " \t");
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharInStringRule(ARC_LEXER_TOKEN_WHITESPACE, whitespaceString));
ARC_String_Destroy(whitespaceString);
//TEMP FIX:
//ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_WHITESPACE, ' '));
//single char tokens
ARC_Lexer_RegisterTokenRule(lexer, ARC_LexerTokenRule_CreateAndReturnMatchCharRule(ARC_LEXER_TOKEN_NEWLINE_ID , ARC_LEXER_TOKEN_NEWLINE_CHAR ));

View file

@ -1,3 +1,4 @@
#include "arc/std/parser/parserlang.h"
#include "arc/std/parser.h"
#include "arc/std/bool.h"
#include "arc/std/errno.h"
@ -100,7 +101,26 @@ void ARC_Parser_CreateFromVector(ARC_Parser **parser, ARC_Vector *language, ARC_
ARC_Parser_Create(parser, &languageAsArray, initLexerRulesFn, createDataFn, destroyDataFn, userData);
}
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, ARC_Parser_GetStringIdFn getStringIdFn, ARC_ParserData_CreateFn *createDataFn, ARC_ParserData_DestroyFn *destroyDataFn, void *userData){
//create the language from the string
ARC_Parser *parserlangParser;
ARC_ParserLang_CreateAsParser(&parserlangParser, getStringIdFn);
if(arc_errno){
ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_Parser_CreateFromString(parser, languageString, initLexerRulesFn, getStringIdFn, createDataFn, destroyDataFn, userData), failed to create language from: %s", languageString->data);
return;
}
//copy the string because parse will destroy the string that is passed in
ARC_String *parserLangString;
ARC_String_Copy(&parserLangString, languageString);
ARC_Parser_Parse(parserlangParser, &parserLangString);
//create the parser from the parsed language
ARC_Vector *language = (ARC_Vector *)ARC_Parser_GetData(parserlangParser);
ARC_Parser_CreateFromVector(parser, language, initLexerRulesFn, createDataFn, destroyDataFn, userData);
//cleanup
ARC_Parser_Destroy(parserlangParser);
}
void ARC_Parser_Destroy(ARC_Parser *parser){
@ -122,7 +142,7 @@ void ARC_Parser_Destroy(ARC_Parser *parser){
free(parser->createDataFn);
}
//free the data and the deletion function callback
//do the same thing as clear but this time pass in the userData as well to clean that up
if(parser->destroyDataFn != NULL){
(*(parser->destroyDataFn))(parser->data, parser->userData);
free(parser->destroyDataFn);
@ -326,7 +346,7 @@ void ARC_Parser_ParseFile(ARC_Parser *parser, ARC_String *path){
void ARC_Parser_ClearData(ARC_Parser *parser){
//check if that data exists and the destructor exists to make sure they can be run
if(parser->data != NULL && parser->destroyDataFn != NULL){
(*(parser->destroyDataFn))(parser->data, parser->userData);
(*(parser->destroyDataFn))(parser->data, NULL);
}
//TODO: might want to error here

0
src/std/parser/csv.c Normal file
View file

0
src/std/parser/helpers.c Normal file
View file

View file

@ -113,7 +113,7 @@ void ARC_ParserLangParsedData_CreateTagString(ARC_String **tagString, ARC_Parser
/*
<argument> -> <tagOrConstant> WHITESPACE <argument> | <tagOrConstant>
*/
void ARC_ParserLangParsedData_GetArgumentTag(ARC_Vector *orTokensOrTags, ARC_ParserTagToken *tagToken, ARC_ParserLang_GetIdFn *getIdFn){
void ARC_ParserLangParsedData_GetArgumentTag(ARC_Vector *orTokensOrTags, ARC_ParserTagToken *tagToken, ARC_Parser_GetStringIdFn *getStringIdFn){
for(uint32_t index = 0; index < ARC_Vector_GetSize(tagToken->tagTokens); index++){
ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(tagToken->tagTokens, index);
@ -124,7 +124,7 @@ void ARC_ParserLangParsedData_GetArgumentTag(ARC_Vector *orTokensOrTags, ARC_Par
switch(childTagToken->id){
case ARC_PARSERLANG_ARGUMENT:
//recurse to check all the arguments
ARC_ParserLangParsedData_GetArgumentTag(orTokensOrTags, childTagToken, getIdFn);
ARC_ParserLangParsedData_GetArgumentTag(orTokensOrTags, childTagToken, getStringIdFn);
continue;
case ARC_PARSERLANG_TAG_OR_CONSTANT:
@ -134,7 +134,7 @@ void ARC_ParserLangParsedData_GetArgumentTag(ARC_Vector *orTokensOrTags, ARC_Par
//get the id of the tag/constant
ARC_ParserLangParsedData_RecurseStringAdd(&tagOrConstantString, childTagToken);
id = (uint32_t *)malloc(sizeof(uint32_t));
*id = (*getIdFn)(tagOrConstantString);
*id = (*getStringIdFn)(tagOrConstantString);
//add the id to the matching or vector
ARC_Vector_Add(orTokensOrTags, (void *)id);
@ -153,7 +153,7 @@ void ARC_ParserLangParsedData_GetArgumentTag(ARC_Vector *orTokensOrTags, ARC_Par
/*
<arguments> -> <argument> WHITESPACE OR WHITESPACE <arguments> | <argument>
*/
void ARC_ParserLangParsedData_GetArgumentsTag(ARC_Vector *tokensOrTags, ARC_ParserTagToken *tagToken, ARC_ParserLang_GetIdFn *getIdFn){
void ARC_ParserLangParsedData_GetArgumentsTag(ARC_Vector *tokensOrTags, ARC_ParserTagToken *tagToken, ARC_Parser_GetStringIdFn *getStringIdFn){
for(uint32_t index = 0; index < ARC_Vector_GetSize(tagToken->tagTokens); index++){
ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(tagToken->tagTokens, index);
@ -169,7 +169,7 @@ void ARC_ParserLangParsedData_GetArgumentsTag(ARC_Vector *tokensOrTags, ARC_Pars
tokensOrTagsIndex = ARC_Vector_GetSize(tokensOrTags);
orTokensOrTags = (ARC_Vector *)ARC_Vector_Get(tokensOrTags, tokensOrTagsIndex - 1);
ARC_ParserLangParsedData_GetArgumentTag(orTokensOrTags, childTagToken, getIdFn);
ARC_ParserLangParsedData_GetArgumentTag(orTokensOrTags, childTagToken, getStringIdFn);
continue;
case ARC_PARSERLANG_TOKEN_OR_ID:
@ -182,7 +182,7 @@ void ARC_ParserLangParsedData_GetArgumentsTag(ARC_Vector *tokensOrTags, ARC_Pars
case ARC_PARSERLANG_ARGUMENTS:
//recurse to check all the arguments
ARC_ParserLangParsedData_GetArgumentsTag(tokensOrTags, childTagToken, getIdFn);
ARC_ParserLangParsedData_GetArgumentsTag(tokensOrTags, childTagToken, getStringIdFn);
continue;
default:
@ -192,7 +192,7 @@ void ARC_ParserLangParsedData_GetArgumentsTag(ARC_Vector *tokensOrTags, ARC_Pars
}
}
void ARC_ParserLangParsedData_CreateBodyTag(ARC_ParserTag **tag, ARC_ParserTagToken *tagToken, ARC_ParserLang_GetIdFn *getIdFn){
void ARC_ParserLangParsedData_CreateBodyTag(ARC_ParserTag **tag, ARC_ParserTagToken *tagToken, ARC_Parser_GetStringIdFn *getStringIdFn){
//create the tag to store the body in
ARC_ParserTag *bodyTag = (ARC_ParserTag *)malloc(sizeof(ARC_ParserTag));
@ -205,7 +205,7 @@ void ARC_ParserLangParsedData_CreateBodyTag(ARC_ParserTag **tag, ARC_ParserTagTo
ARC_ParserLangParsedData_CreateTagString(&tagIdString, tagIdToken);
//get the tag id as a uint32_t
bodyTag->tagId = (*getIdFn)(tagIdString);
bodyTag->tagId = (*getStringIdFn)(tagIdString);
//cleanup the tagIdString
ARC_String_Destroy(tagIdString);
@ -226,7 +226,7 @@ void ARC_ParserLangParsedData_CreateBodyTag(ARC_ParserTag **tag, ARC_ParserTagTo
//skipping whitespace and arrow tokens, the arguments index starts at 4
ARC_ParserTagToken *argumentsToken = (ARC_ParserTagToken *)ARC_Vector_Get(tagToken->tagTokens, 4);
ARC_ParserLangParsedData_GetArgumentsTag(tokensOrTags, argumentsToken, getIdFn);
ARC_ParserLangParsedData_GetArgumentsTag(tokensOrTags, argumentsToken, getStringIdFn);
//initialize the tokens or tags array to the needed size
bodyTag->tokensOrTagsSize = ARC_Vector_GetSize(tokensOrTags);
@ -255,7 +255,7 @@ void ARC_ParserLangParsedData_CreateBodyTag(ARC_ParserTag **tag, ARC_ParserTagTo
ARC_Vector_Destroy(tokensOrTags);
}
void ARC_ParserLangParsedData_RunLineTag(ARC_Vector *tags, ARC_ParserTagToken *tagToken, ARC_ParserLang_GetIdFn *getIdFn){
void ARC_ParserLangParsedData_RunLineTag(ARC_Vector *tags, ARC_ParserTagToken *tagToken, ARC_Parser_GetStringIdFn *getStringIdFn){
//loop through the tags either going to the next line or the next body
for(uint32_t index = 0; index < ARC_Vector_GetSize(tagToken->tagTokens); index++){
ARC_ParserTagToken *childTagToken = (ARC_ParserTagToken *)ARC_Vector_Get(tagToken->tagTokens, index);
@ -266,12 +266,12 @@ void ARC_ParserLangParsedData_RunLineTag(ARC_Vector *tags, ARC_ParserTagToken *t
switch(childTagToken->id){
//recuse to run the next line
case ARC_PARSERLANG_LINE:
ARC_ParserLangParsedData_RunLineTag(tags, childTagToken, getIdFn);
ARC_ParserLangParsedData_RunLineTag(tags, childTagToken, getStringIdFn);
continue;
//get a tag
case ARC_PARSERLANG_BODY:
ARC_ParserLangParsedData_CreateBodyTag(&tag, childTagToken, getIdFn);
ARC_ParserLangParsedData_CreateBodyTag(&tag, childTagToken, getStringIdFn);
ARC_Vector_Add(tags, (void *)tag);
continue;
@ -283,7 +283,7 @@ void ARC_ParserLangParsedData_RunLineTag(ARC_Vector *tags, ARC_ParserTagToken *t
//private function to create the saved data for the language
void ARC_ParserLang_CreateDataFn(void **data, ARC_ParserTagToken *parsedData, void *userData){
ARC_ParserLang_GetIdFn *getIdFn = (ARC_ParserLang_GetIdFn *)userData;
ARC_Parser_GetStringIdFn *getStringIdFn = (ARC_Parser_GetStringIdFn *)userData;
//make sure there is parsed data to use
if(parsedData == NULL){
@ -304,13 +304,15 @@ void ARC_ParserLang_CreateDataFn(void **data, ARC_ParserTagToken *parsedData, vo
}
//load the language into a vector recursivly
ARC_ParserLangParsedData_RunLineTag(*((ARC_Vector **)data), parsedData, getIdFn);
ARC_ParserLangParsedData_RunLineTag(*((ARC_Vector **)data), parsedData, getStringIdFn);
}
//private function to destroy the saved data for the language
void ARC_ParserLang_DestroyDataFn(void *data, void *userData){
ARC_ParserLang_GetIdFn *getIdFn = (ARC_ParserLang_GetIdFn *)userData;
free(getIdFn);
if(userData != NULL){
ARC_Parser_GetStringIdFn *getStringIdFn = (ARC_Parser_GetStringIdFn *)userData;
free(getStringIdFn);
}
//check if there is data to free
if((ARC_Vector *)data != NULL){
@ -318,7 +320,7 @@ void ARC_ParserLang_DestroyDataFn(void *data, void *userData){
}
}
void ARC_Parser_CreateAsParserLang(ARC_Parser **parser, ARC_ParserLang_GetIdFn getIdFn){
void ARC_ParserLang_CreateAsParser(ARC_Parser **parser, ARC_Parser_GetStringIdFn getStringIdFn){
//<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 } };
@ -383,9 +385,9 @@ void ARC_Parser_CreateAsParserLang(ARC_Parser **parser, ARC_ParserLang_GetIdFn g
ARC_ParserData_DestroyFn destroyDataFn = ARC_ParserLang_DestroyDataFn;
//this will be cleaned up by the destroyDataFn
ARC_ParserLang_GetIdFn *newGetIdFn = (ARC_ParserLang_GetIdFn *)malloc(sizeof(ARC_ParserLang_GetIdFn));
*newGetIdFn = getIdFn;
ARC_Parser_GetStringIdFn *newGetStringIdFn = (ARC_Parser_GetStringIdFn *)malloc(sizeof(ARC_Parser_GetStringIdFn));
*newGetStringIdFn = getStringIdFn;
//create the parserlang
ARC_Parser_Create(parser, &parserLanguageArray, ARC_ParserLang_InitLexerRulesFn, &createDataFn, &destroyDataFn, newGetIdFn);
ARC_Parser_Create(parser, &parserLanguageArray, ARC_ParserLang_InitLexerRulesFn, &createDataFn, &destroyDataFn, (void *)newGetStringIdFn);
}