archeus/src/std/parser.c

127 lines
4.5 KiB
C
Raw Normal View History

#include "arc/std/parser.h"
#include "arc/std/bool.h"
2024-10-16 23:46:16 -06:00
#include "arc/std/errno.h"
#include "arc/std/lexer.h"
//#include "arc/std/vector.h"
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
struct ARC_Parser {
ARC_Array language;
ARC_Lexer *lexer;
};
void ARC_Parser_Create(ARC_Parser **parser, ARC_Array *language, ARC_Parser_InitLexerRulesFn initLexerRulesFn){
*parser = (ARC_Parser *)malloc(sizeof(ARC_Parser));
//set the language size to 0 and data to NULL in case the language is NULL
(*parser)->language.size = 0;
(*parser)->language.data = NULL;
//if the language exists, copy the language
if(language != NULL){
(*parser)->language.size = language->size;
(*parser)->language.data = malloc(sizeof(ARC_ParserLanguageTag) * language->size);
memcpy((*parser)->language.data, language->data, language->size);
}
//create the lexer
ARC_Lexer_Create(&((*parser)->lexer));
//register instructions to the lexer
initLexerRulesFn(((*parser)->lexer));
}
void ARC_Parser_CreateFromString(ARC_Parser **parser, ARC_String *languageString, ARC_Parser_InitLexerRulesFn initLexerRulesFn){
}
void ARC_Parser_Destroy(ARC_Parser *parser){
free(parser->language.data);
ARC_Lexer_Destroy(parser->lexer);
free(parser);
}
2024-10-16 23:46:16 -06:00
//private recusive function to parse a tag
void ARC_Parser_ParseTag(ARC_Parser *parser, uint32_t *lexerIndex, uint32_t tagId){
2024-10-16 23:46:16 -06:00
//get the current tag
ARC_ParserLanguageTag *tag = NULL;
for(uint32_t index = 0; index < parser->language.size; index++){
ARC_ParserLanguageTag *foundTag = ((ARC_ParserLanguageTag *)parser->language.data) + index;
if(foundTag->tagId == tagId){
tag = foundTag;
break;
}
}
//if the tag was not found can't do much, so throw an error
if(tag == 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);
return;
}
//loop through each or section of the tags and tokens
for(uint32_t orIndex = 0; orIndex < tag->tokensOrTagsSize; orIndex++){
//loop through each token or tag to check if the lexed data matches
uint32_t lexerCheckIndex = *lexerIndex;
ARC_Bool foundRule = ARC_True;
for(uint32_t tokenOrTagIndex = 1; tokenOrTagIndex < tag->tokensOrTags[orIndex][0] + 1; tokenOrTagIndex++){
//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]);
if(isToken == ARC_False){
ARC_Parser_ParseTag(parser, lexerIndex, tag->tokensOrTags[orIndex][tokenOrTagIndex]);
return;
}
//get the next token in the lexer and increment the lexers index
ARC_LexerToken token = ARC_Lexer_GetToken(parser->lexer, lexerCheckIndex);
lexerCheckIndex++;
//if the token rule does not match the current token in the current or statement the token rule could not be found for the current or index so break
if(token.rule != tag->tokensOrTags[orIndex][tokenOrTagIndex]){
foundRule = ARC_False;
break;
}
}
//if the rule is found we don't need to check anymore so we can return out
if(foundRule == ARC_True){
*lexerIndex = lexerCheckIndex;
2024-10-28 21:00:48 -06:00
//TODO: set tag into datastructure
return;
}
}
//no rule was found, so set an error and log
arc_errno = ARC_ERRNO_DATA;
ARC_DEBUG_LOG_ERROR_WITH_VARIABLES("ARC_Parser_ParseTag(parser, lexerIndex, tagId), tag id: %u could not find a matching rule at token index %u", tagId, *lexerIndex);
2024-10-16 23:46:16 -06:00
}
void ARC_Parser_Parse(ARC_Parser *parser, ARC_String **data){
//lex the subdata
ARC_Lexer_LexString(parser->lexer, data);
if(arc_errno){
ARC_DEBUG_LOG_ERROR("ARC_Parser_Parse(parser, data), could not lex the given data");
2024-10-28 21:00:48 -06:00
return;
}
uint32_t lexerIndex = 0;
ARC_ParserLanguageTag startTag = ((ARC_ParserLanguageTag *)parser->language.data)[0];
//recursivly parse from the inital start tag
ARC_Parser_ParseTag(parser, &lexerIndex, startTag.tagId);
if(arc_errno){
ARC_DEBUG_LOG_ERROR("ARC_Parser_Parse(parser, data), could not parse the given data");
2024-10-28 21:00:48 -06:00
return;
}
2024-10-16 23:46:16 -06:00
}
void ARC_Parser_ParseFile(ARC_Parser *parser, ARC_String *path){
}