parser fixed (still probably needs more testing, but current tests work), parserlang still not working
This commit is contained in:
parent
6d64a17b1d
commit
84c4dffc85
4 changed files with 153 additions and 161 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
111
src/std/parser.c
111
src/std/parser.c
|
|
@ -13,11 +13,13 @@ 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){
|
||||||
|
//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->destroyDataFn))(parser->data);
|
||||||
(*(parser->createDataFn))(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){
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
//}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue