#ifndef ARC_STD_PARSER_H_ #define ARC_STD_PARSER_H_ #ifdef __cplusplus extern "C" { #endif #include "arc/std/array.h" #include "arc/std/lexer.h" #include "arc/std/vector.h" #include /** * @brief a type used for splitting a string up into parts and storing them in user defined types */ typedef struct ARC_Parser ARC_Parser; /** * @brief a type that stores a tag id, and a list of tokens and tags that are the rules for a tag in a language */ typedef struct ARC_ParserTag { uint32_t tagId; uint32_t **tokensOrTags; uint32_t tokensOrTagsSize; } ARC_ParserTag; /** * @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 { uint32_t id; ARC_LexerToken *token; ARC_Vector *tagTokens; } ARC_ParserTagToken; /** * @brief a callback function to initialize the lexer the parser uses with rules * * @param[in] lexer the lexer used by the parser that rules should be added to */ typedef void (* ARC_Parser_InitLexerRulesFn)(ARC_Lexer *lexer); /** * @brief a function callback the user provides to get a tag or token ID from a string * * @param[in] string the string to get an id from * * @return an id from the user, the user also can determine what id should be an error */ typedef uint32_t (* ARC_Parser_GetStringIdFn)(ARC_String *string); /** * @brief a function callback to create and store parsed data passed in * * @param[in/out] data the place to store the datatype after it is created * @param[in] parsedData the parsed data to use in creating the data * @param[in] userData the data that is passed in during parser create, can be anything this callback */ typedef void (* ARC_ParserData_CreateFn)(void **data, ARC_ParserTagToken *parsedData, void *userData); /** * @brief TODO: write this */ typedef void (* ARC_ParserData_DestroyFn)(void *data, ARC_Bool clear, void *userData); /** * @brief creates an ARC_Parser type * * @TODO: fix this documentation to reflect changes * * @TODO: probs want to move the note to another file * @note array of tokens for langauge? like * ARC_ParserTag tag = { * VARIABLE_NAME, //tagId * { * { 2, CHAR_OR_NUM, VARIABLE_NAME }, * { 1, LAMBDA }, * }, //components * 2 //componentsSize * }; * * @param[out] parser ARC_Parser to create * @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 */ void ARC_Parser_Create(ARC_Parser **parser, ARC_Array *language, ARC_Parser_InitLexerRulesFn initLexerRulesFn, ARC_ParserData_CreateFn *createDataFn, ARC_ParserData_DestroyFn *destroyDataFn, void *userData); /** * @brief creates an ARC_Parser type from an arc vector * * @param[out] parser ARC_Parser to create * @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 */ void ARC_Parser_CreateFromVector(ARC_Parser **parser, ARC_Vector *language, ARC_Parser_InitLexerRulesFn initLexerRulesFn, ARC_ParserData_CreateFn *createDataFn, ARC_ParserData_DestroyFn *destroyDataFn, void *userData); /** * @brief creates an ARC_Parser type from a string * * @TODO: probs want to move the note to another file * @note the syntax looks like: * -> CHAR EOF * -> | LAMBDA * -> CHAR | NUM * * @param[out] parser ARC_Parser to create * @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 */ 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); /** * @brief destroys an ARC_Parser type * * @param[in] parser ARC_Parser to free */ void ARC_Parser_Destroy(ARC_Parser *parser); /** * @brief * * @param[in] parser * @param[in/out] data the string to parse, will be freed and set to NULL by the end of this function */ void ARC_Parser_Parse(ARC_Parser *parser, ARC_String **data); /** * @brief * * @param[in] parser * @param[in] language */ void ARC_Parser_ParseFile(ARC_Parser *parser, ARC_String *path); /** * @brief * * @param[in] parser */ void ARC_Parser_ClearData(ARC_Parser *parser); /** * @brief * * @param[in] parser */ void *ARC_Parser_GetData(ARC_Parser *parser); /** * @brief basic tag for letting the parser know it is ok to end */ #define ARC_PARSER_TAG_LAMBDA 0 #ifdef __cplusplus } #endif #endif // !ARC_STD_PARSER_H_