added ability to check if token id is a lexer rule and wrote parser, still need to test

This commit is contained in:
herbglitch 2024-10-24 19:56:26 -06:00
parent 7a3495f7ae
commit d8d1a1a107
7 changed files with 211 additions and 13 deletions

View file

@ -1,7 +1,8 @@
#include "arc/std/parser.h"
#include "arc/std/bool.h"
#include "arc/std/errno.h"
#include "arc/std/lexer.h"
#include "arc/std/vector.h"
//#include "arc/std/vector.h"
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
@ -46,7 +47,7 @@ void ARC_Parser_Destroy(ARC_Parser *parser){
}
//private recusive function to parse a tag
void ARC_Parser_ParseTag(ARC_Parser *parser, uint32_t lexerIndex, uint32_t tagId){
void ARC_Parser_ParseTag(ARC_Parser *parser, uint32_t *lexerIndex, uint32_t tagId){
//get the current tag
ARC_ParserLanguageTag *tag = NULL;
for(uint32_t index = 0; index < parser->language.size; index++){
@ -67,16 +68,54 @@ void ARC_Parser_ParseTag(ARC_Parser *parser, uint32_t lexerIndex, uint32_t tagId
//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;
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;
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);
}
void ARC_Parser_Parse(ARC_Parser *parser, ARC_String *data){
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");
}
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");
}
}
void ARC_Parser_ParseFile(ARC_Parser *parser, ARC_String *path){