From 221d575c1630129b59ded33f1e4f3d19f4a77639 Mon Sep 17 00:00:00 2001 From: Garritt McCune Date: Wed, 2 Mar 2022 21:24:58 +0000 Subject: [PATCH] Further refactoring done. The Parser runs without crashing, however it's output is still to be checked and verified. --- lox.c | 5 +++- parser.c | 71 ++++++++++++++++++++++++++++++++----------------------- parser.h | 2 ++ scanner.c | 62 +++++++++++++++++++++++------------------------- token.c | 8 +++++++ token.h | 1 + 6 files changed, 85 insertions(+), 64 deletions(-) diff --git a/lox.c b/lox.c index 0968203..993b11e 100644 --- a/lox.c +++ b/lox.c @@ -1,4 +1,6 @@ #include "scanner.h" +#include "parser.h" +#include "expr.h" #include #include #include @@ -37,7 +39,8 @@ void RunFile(const char* path) { TokenList* tokens = ScanTokens(contents); free(contents); Print(tokens); - + Expr* tree = GenerateExpressionTree(tokens); + FreeExpressionTree(tree); DestroyTokenList(tokens); } diff --git a/parser.c b/parser.c index 4914fce..03ee3b1 100644 --- a/parser.c +++ b/parser.c @@ -7,13 +7,12 @@ Expr* Term(void); Expr* Factor(void); Expr* Unary(void); Expr* Primary(void); -int SMatch(int, ...); +int Match(int, ...); int Check(TokenType); -int SIsAtEnd(void); -Token* SPeek(void); +int ParserAtEnd(void); +Token* ParserPeek(void); Token* Previous(void); -Token* SAdvance(void); -//Token* CreateToken(char*, TokenType); +Token* AdvanceParser(void); const TokenList* ListOfTokens; int Current = 0; @@ -32,7 +31,7 @@ Expr* Expression() { Expr* Equality() { Expr* expr = Comparison(); - while(SMatch(2, Bang_Equal, Equal_Equal)) { + while(Match(2, Bang_Equal, Equal_Equal)) { Token* operator = Previous(); Expr* right = Comparison(); Expr* temp = calloc(1, sizeof(Expr)); @@ -49,7 +48,7 @@ Expr* Equality() { Expr* Comparison() { Expr* expr = Term(); - while(SMatch(4, Greater, Greater_Equal, Less, Less_Equal)) { + while(Match(4, Greater, Greater_Equal, Less, Less_Equal)) { Token* operator = Previous(); Expr* right = Term(); Expr* temp = calloc(1, sizeof(Expr)); @@ -66,7 +65,7 @@ Expr* Comparison() { Expr* Term() { Expr* expr = Factor(); - while(SMatch(2, Minus, Plus)) { + while(Match(2, Minus, Plus)) { Token* operator = Previous(); Expr* right = Factor(); Expr* temp = calloc(1, sizeof(Expr)); @@ -83,7 +82,7 @@ Expr* Term() { Expr* Factor() { Expr* expr = Unary(); - while(SMatch(2, Slash, Star)) { + while(Match(2, Slash, Star)) { Token* operator = Previous(); Expr* right = Unary(); Expr* temp = calloc(1, sizeof(Expr)); @@ -98,7 +97,7 @@ Expr* Factor() { } Expr* Unary() { - if (SMatch(2, Bang, Minus)) { + if (Match(2, Bang, Minus)) { Token* operator = Previous(); Expr* right = Unary(); Expr* expr = calloc(1, sizeof(Expr)); @@ -115,8 +114,8 @@ Expr* Primary() { Expr* expr = calloc(1, sizeof(Expr)); expr->type = LITERAL; - if (SMatch(3, FALSE, TRUE, NIL)) { - expr->expression.Literal.type = SPeek();//CreateToken("false", FALSE); + if (Match(3, FALSE, TRUE, NIL)) { + expr->expression.Literal.type = ParserPeek();//CreateToken("false", FALSE); return expr; } // if (SMatch(1, TRUE)) { @@ -128,12 +127,12 @@ Expr* Primary() { // return expr; // } - if (SMatch(2, Number, String)) { + if (Match(2, Number, String)) { expr->expression.Literal.type = Previous(); return expr; } - if (SMatch(1, LParen)) { + if (Match(1, LParen)) { free(expr); expr = Expression(); //Consume(RParen, "Expect ')' after expression."); @@ -144,13 +143,13 @@ Expr* Primary() { return expr; } -int SMatch(int count, ...) { +int Match(int count, ...) { va_list list; va_start(list, count); for(int i = 0; i < count; i++) { if(Check(va_arg(list, TokenType))) { - SAdvance(); + AdvanceParser(); return 1; } } @@ -159,15 +158,15 @@ int SMatch(int count, ...) { } int Check(TokenType type) { - if (SIsAtEnd()) return 0; - return SPeek()->type == type; + if (ParserAtEnd()) return 0; + return ParserPeek()->type == type; } -int SIsAtEnd() { - return SPeek()->type == EndOF; +int ParserAtEnd() { + return ParserPeek()->type == EndOF; } -Token* SPeek() { +Token* ParserPeek() { return ListOfTokens->tokens[Current]; } @@ -175,17 +174,29 @@ Token* Previous() { return ListOfTokens->tokens[Current - 1]; } -Token* SAdvance() { - if (!SIsAtEnd()) Current++; +Token* AdvanceParser() { + if (!ParserAtEnd()) Current++; return Previous(); } -// Token* CreateToken(char* lexeme, TokenType type) { -// Token* token = calloc(1, sizeof(Token)); -// token->type = type; -// token->lexeme = lexeme; -// token->length = strlen(lexeme); +void PrintExpressionTree(const Expr* tree) { -// return token; -// } \ No newline at end of file +} + +void FreeExpressionTree(Expr* tree) { + if (!tree) return; + + if (tree->type == BINARY) { + FreeExpressionTree(tree->expression.Binary.left); + FreeExpressionTree(tree->expression.Binary.right); + //FreeToken(tree->expression.Binary.op); + } + else if (tree->type == UNARY) { + FreeExpressionTree(tree->expression.Unary.right); + //FreeToken(tree->expression.Unary.op); + } + //else if (tree->type == LITERAL) FreeToken(tree->expression.Literal.type); + + free(tree); +} \ No newline at end of file diff --git a/parser.h b/parser.h index bd87896..9cb9d80 100644 --- a/parser.h +++ b/parser.h @@ -9,5 +9,7 @@ #include Expr* GenerateExpressionTree(const TokenList* list); +void PrintExpressionTree(const Expr*); +void FreeExpressionTree(Expr*); #endif \ No newline at end of file diff --git a/scanner.c b/scanner.c index 5cac794..0793e8d 100644 --- a/scanner.c +++ b/scanner.c @@ -8,13 +8,13 @@ int current; //points to the character currently being considered. int length; int line = 1; -const char* SAdvance(void); -int SIsAtEnd(void); +const char* AdvanceScanner(void); +int ScannerAtEnd(void); void ScanToken(TokenList*); TokenList* CreateList(void); int AddToTokenList(Token*, TokenList*); -int SMatch(char); -char SPeek(void); +int ScannerMatch(char); +char ScannerPeek(void); char PeekNext(void); void ParseString(TokenList *); void ParseNumber(TokenList *); @@ -32,7 +32,7 @@ TokenList* ScanTokens(const char* source) { TokenList* tokens = CreateList(); - while(!SIsAtEnd()) { + while(!ScannerAtEnd()) { start = current; ScanToken(tokens); } @@ -68,11 +68,7 @@ void DestroyTokenList(TokenList* list) { if (!list) return; for(int i = 0; i < list->size; i++) { - //Only free objects that required allocation, i.e. not in the TokenTypeMappings - if (list->tokens[i]->type == String || list->tokens[i]->type == Number || list->tokens[i]->type == Identifier) - free((void *) list->tokens[i]->lexeme); - - free(list->tokens[i]); + FreeToken(list->tokens[i]); } free(list->tokens); @@ -102,7 +98,7 @@ int AddToTokenList(Token* token, TokenList* list) { } void ScanToken(TokenList* tokens) { - const char* c = SAdvance(); + const char* c = AdvanceScanner(); switch (*c) { case '(': @@ -136,23 +132,23 @@ void ScanToken(TokenList* tokens) { AddToTokenList(CreateToken(NULL, line, Star), tokens); break; case '!': - if (SMatch('=')) AddToTokenList(CreateToken(NULL, line, Bang_Equal), tokens); + if (ScannerMatch('=')) AddToTokenList(CreateToken(NULL, line, Bang_Equal), tokens); else AddToTokenList(CreateToken(NULL, line, Bang), tokens); break; case '=': - if (SMatch('=')) AddToTokenList(CreateToken(NULL, line, Equal_Equal), tokens); + if (ScannerMatch('=')) AddToTokenList(CreateToken(NULL, line, Equal_Equal), tokens); else AddToTokenList(CreateToken(NULL, line, Equal), tokens); break; case '<': - if (SMatch('=')) AddToTokenList(CreateToken(NULL, line, Less_Equal), tokens); + if (ScannerMatch('=')) AddToTokenList(CreateToken(NULL, line, Less_Equal), tokens); else AddToTokenList(CreateToken(NULL, line, Less), tokens); break; case '>': - if (SMatch('=')) AddToTokenList(CreateToken(NULL, line, Greater_Equal), tokens); + if (ScannerMatch('=')) AddToTokenList(CreateToken(NULL, line, Greater_Equal), tokens); else AddToTokenList(CreateToken(NULL, line, Greater), tokens); break; case '/': - if (SMatch('/')) while(SPeek() != '\n' && !SIsAtEnd()) { SAdvance(); } + if (ScannerMatch('/')) while(ScannerPeek() != '\n' && !ScannerAtEnd()) { AdvanceScanner(); } else AddToTokenList(CreateToken(NULL, line, Slash), tokens); break; @@ -180,16 +176,16 @@ void ScanToken(TokenList* tokens) { } } -int SIsAtEnd() { +int ScannerAtEnd() { return current >= length; } -const char* SAdvance() { +const char* AdvanceScanner() { return &source_code[current++]; } -int SMatch(char expected) { - if (SIsAtEnd()) return 0; +int ScannerMatch(char expected) { + if (ScannerAtEnd()) return 0; if (source_code[current] != expected) return 0; current++; @@ -197,8 +193,8 @@ int SMatch(char expected) { return 1; } -char SPeek() { - if (SIsAtEnd()) return '\0'; +char ScannerPeek() { + if (ScannerAtEnd()) return '\0'; return source_code[current]; } @@ -206,12 +202,12 @@ char SPeek() { void ParseString(TokenList *list) { start = current; //The start is currently pointing to the first double quote so we need to move it //to the next (first character) of the string literal. - while(SPeek() != '"' && !SIsAtEnd()) { - if (SPeek() == '\n') line++; - SAdvance(); + while(ScannerPeek() != '"' && !ScannerAtEnd()) { + if (ScannerPeek() == '\n') line++; + AdvanceScanner(); } - if (SIsAtEnd()) { + if (ScannerAtEnd()) { fprintf(stderr, "Unterminated string.\n"); return; } @@ -227,16 +223,16 @@ void ParseString(TokenList *list) { AddToTokenList(CreateToken(lexeme, line, String), list); - SAdvance(); // The closing ". + AdvanceScanner(); // The closing ". } void ParseNumber(TokenList* list) { - while(isdigit(SPeek())) SAdvance(); + while(isdigit(ScannerPeek())) AdvanceScanner(); - if (SPeek() == '.' && isdigit(PeekNext())) { - SAdvance(); + if (ScannerPeek() == '.' && isdigit(PeekNext())) { + AdvanceScanner(); - while(isdigit(SPeek())) SAdvance(); + while(isdigit(ScannerPeek())) AdvanceScanner(); } char* lexeme = calloc(current - start + 2, sizeof(char)); @@ -258,12 +254,12 @@ char PeekNext() { } void ParseIdentifier(TokenList * list) { - while(IsAlpha(SPeek())) SAdvance(); + while(IsAlpha(ScannerPeek())) AdvanceScanner(); char* lexeme = calloc(current - start + 2, sizeof(char)); snprintf(lexeme, current - start + 1, "%s", &source_code[start]); - printf("%s\n", lexeme); + KeyValuePair* result = Get(lexeme); if (result) { diff --git a/token.c b/token.c index 8e3afb9..a09922d 100644 --- a/token.c +++ b/token.c @@ -48,4 +48,12 @@ const char* GetLexemeMapping(TokenType type) { } return NULL; +} + +void FreeToken(Token* token) { + if (!token) return; + + if (token->type == String || token->type == Number || token->type == Identifier) free((void *) token->lexeme); + + free(token); } \ No newline at end of file diff --git a/token.h b/token.h index ea114c6..059872f 100644 --- a/token.h +++ b/token.h @@ -50,5 +50,6 @@ extern KeyValuePair TokenTypeMappings[TOKENTYPE_MAPPINGS_COUNT]; //If the first parameter is NULL, the token creation will attempt to infer the lexeme from the TokenType. Token* CreateToken(const char*, int, TokenType); +void FreeToken(Token*); #endif \ No newline at end of file