From 92ab2d11b02cc730b8c8552f84831e54030612e3 Mon Sep 17 00:00:00 2001 From: wilyJ80 Date: Tue, 10 Dec 2024 10:23:10 -0300 Subject: [PATCH 01/27] fix: terminal color output --- test/parser_integration_tests.c | 5 +++++ test/parser_integration_tests.h | 2 ++ test/test.c | 10 +++++++--- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/test/parser_integration_tests.c b/test/parser_integration_tests.c index 4b55e15..61d3250 100644 --- a/test/parser_integration_tests.c +++ b/test/parser_integration_tests.c @@ -156,3 +156,8 @@ void declDefProcProtoTwoProts() { enum SYNTAX_ERROR error = setupError("prot j(int) prot k(2(\n"); assert(error == INVALID_PROTO_PARAM_TYPE); } + +void declDefProcDefDefWorksToo() { + enum SYNTAX_ERROR error = setupError("def init\n"); + assert(error == NO_ERROR); +} diff --git a/test/parser_integration_tests.h b/test/parser_integration_tests.h index 15b908b..42c2123 100644 --- a/test/parser_integration_tests.h +++ b/test/parser_integration_tests.h @@ -37,4 +37,6 @@ void declDefProcProtoMultiParams(); void declDefProcProtoNoParenClose(); void declDefProcProtoTwoProts(); +void declDefProcDefDefWorksToo(); + #endif // !PARSER_INTEGRATION_TESTS_H diff --git a/test/test.c b/test/test.c index 03165d9..a612d3b 100644 --- a/test/test.c +++ b/test/test.c @@ -14,7 +14,7 @@ int main(void) { lexerCharconTest(); lexerCharconTest2(); - printf(GREEN "--- Lexer tests passed\n" RESET); + printf("--- Lexer tests passed\n"); opRelTest(); opRelTest2(); @@ -27,7 +27,7 @@ int main(void) { declVarArrayBadInitCurly(); // fatorArrayMultTest(); - printf(GREEN "--- Parser unit tests passed\n" RESET); + printf("--- Parser unit tests passed\n"); progStartKeyword(); @@ -57,7 +57,11 @@ int main(void) { declDefProcProtoNoParenClose(); declDefProcProtoTwoProts(); - printf(GREEN "--- Parser integration tests passed\n" RESET); + declDefProcDefDefWorksToo(); + + printf("--- Parser integration tests passed\n"); + + printf(GREEN "All tests OK\n" RESET); return EXIT_SUCCESS; } From 43836df30df64568bce60f884f5a213331703711 Mon Sep 17 00:00:00 2001 From: wilyJ80 Date: Tue, 10 Dec 2024 10:27:48 -0300 Subject: [PATCH 02/27] test: start def --- test/parser_integration_tests.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/parser_integration_tests.c b/test/parser_integration_tests.c index 61d3250..26dff8c 100644 --- a/test/parser_integration_tests.c +++ b/test/parser_integration_tests.c @@ -160,4 +160,7 @@ void declDefProcProtoTwoProts() { void declDefProcDefDefWorksToo() { enum SYNTAX_ERROR error = setupError("def init\n"); assert(error == NO_ERROR); + + enum SYNTAX_ERROR error2 = setupError("def 8\n"); + assert(error2 == NO_DEF_ID); } From e64313727e8832bde94c9c015775462a028a1d69 Mon Sep 17 00:00:00 2001 From: wilyJ80 Date: Tue, 10 Dec 2024 10:49:44 -0300 Subject: [PATCH 03/27] test: def paren open --- parser/parser.c | 19 +++++++++++++++++-- parser/parser.h | 4 +++- parser/syntax_error.c | 10 ++++++---- parser/syntax_error.h | 2 ++ test/parser_integration_tests.c | 17 +++++++++++++---- test/parser_integration_tests.h | 1 + test/test.c | 1 + 7 files changed, 43 insertions(+), 11 deletions(-) diff --git a/parser/parser.c b/parser/parser.c index 56dee5c..23bac83 100644 --- a/parser/parser.c +++ b/parser/parser.c @@ -234,9 +234,11 @@ enum SYNTAX_ERROR declDefProc(struct Parser *parser) { } parser->token = lexerGetNextChar(parser->fd, parser->lineCount); + // is def if (isDef) { - if (!(parser->token.category == ID || parser->token.signCode == INIT)) { - return NO_DEF_ID; + enum SYNTAX_ERROR error = declDef(parser); + if (error != NO_ERROR) { + return error; } // is prot } else { @@ -249,6 +251,19 @@ enum SYNTAX_ERROR declDefProc(struct Parser *parser) { return NO_ERROR; } +enum SYNTAX_ERROR declDef(struct Parser *parser) { + if (!(parser->token.category == ID || parser->token.signCode == INIT)) { + return NO_DEF_ID; + } + + parser->token = lexerGetNextChar(parser->fd, parser->lineCount); + if (!(parser->token.category == SIGN && parser->token.signCode == OPEN_PAR)) { + return INVALID_DEF_PAREN_OPEN; + } + + return NO_ERROR; +} + enum SYNTAX_ERROR declProt(struct Parser *parser) { if (!(parser->token.category == ID)) { return NO_PROTO_ID; diff --git a/parser/parser.h b/parser/parser.h index 224294b..dc31405 100644 --- a/parser/parser.h +++ b/parser/parser.h @@ -7,7 +7,7 @@ struct Parser { struct Token token; - FILE* fd; + FILE *fd; int *lineCount; }; @@ -34,4 +34,6 @@ enum SYNTAX_ERROR declProtParam(struct Parser *parser); /*void arrayDeclaration(FILE *fd, int *lineCount, struct Token token);*/ /*void arrayInitialization(FILE *fd, int *lineCount, struct Token token);*/ +enum SYNTAX_ERROR declDef(struct Parser *parser); + #endif diff --git a/parser/syntax_error.c b/parser/syntax_error.c index d089a6a..0a79784 100644 --- a/parser/syntax_error.c +++ b/parser/syntax_error.c @@ -2,7 +2,7 @@ #include #include -#define ERROR_QTY 84 +#define ERROR_QTY 86 // ANSI escape codes #define RESET "\033[0m" @@ -46,9 +46,9 @@ void printSyntaxError(enum SYNTAX_ERROR error, int *lineCount) { {INVALID_PROTO_PAREN_CLOSE, "No closing paren in function prototype"}, {INVALID_PROTO_PARAM_TYPE, "Invalid parameter type for function prototype"}, - {NO_PROTO_VALID_TOKEN_AFTER_TYPE, - "No valid token found after function prototype type, expected bracket open " - "or comma"}, + {NO_PROTO_VALID_TOKEN_AFTER_TYPE, "No valid token found after function " + "prototype type, expected bracket open " + "or comma"}, {INVALID_ARRAY_PROTO_PARAM_BRACKET_OPEN, "No opening bracket for function prototype array parameter"}, {INVALID_ARRAY_PROTO_PARAM_BRACKET_CLOSE, @@ -59,6 +59,8 @@ void printSyntaxError(enum SYNTAX_ERROR error, int *lineCount) { "Expected valid token after bracket closing: bracket opening, comma or " "paren close"}, {NO_DEF_ID, "No valid ID for function definition"}, + {INVALID_DEF_PAREN_OPEN, "No valid paren open for function definition"}, + {INVALID_DEF_PAREN_CLOSE, "No valid paren close for function definition"}, {INVALID_DEF_PARAM_TYPE, "No valid parameter type for function definition"}, {NO_DEF_PARAM_ID, "No ID detected for function definition parameter"}, diff --git a/parser/syntax_error.h b/parser/syntax_error.h index 7d662b5..6cab88f 100644 --- a/parser/syntax_error.h +++ b/parser/syntax_error.h @@ -38,6 +38,8 @@ enum SYNTAX_ERROR { INVALID_PROTO_PARAM_LIST, NO_PROTO_VALID_TOKEN_AFTER_BRACKET_CLOSE, NO_DEF_ID, + INVALID_DEF_PAREN_OPEN, + INVALID_DEF_PAREN_CLOSE, INVALID_DEF_PARAM_TYPE, NO_DEF_PARAM_ID, INVALID_ARRAY_DEF_PARAM_SUBSCRIPT_TYPE, diff --git a/test/parser_integration_tests.c b/test/parser_integration_tests.c index 26dff8c..50b61c4 100644 --- a/test/parser_integration_tests.c +++ b/test/parser_integration_tests.c @@ -4,6 +4,9 @@ #include #include +// switch this on to output all syntax errors +#define SHOW_ERRORS false + enum SYNTAX_ERROR setupError(const char *mockData) { FILE *mockFile = fmemopen((void *)mockData, strlen(mockData), "r"); @@ -23,8 +26,9 @@ enum SYNTAX_ERROR setupError(const char *mockData) { .fd = mockFile, .lineCount = lineCount, .token = token}; enum SYNTAX_ERROR error = prog(&parser); - // example debugging: - // printSyntaxError(error); + if (SHOW_ERRORS) { + printSyntaxError(error, parser.lineCount); + } return error; } @@ -158,9 +162,14 @@ void declDefProcProtoTwoProts() { } void declDefProcDefDefWorksToo() { - enum SYNTAX_ERROR error = setupError("def init\n"); - assert(error == NO_ERROR); + enum SYNTAX_ERROR error = setupError("def init)\n"); + assert(error == INVALID_DEF_PAREN_OPEN); enum SYNTAX_ERROR error2 = setupError("def 8\n"); assert(error2 == NO_DEF_ID); } + +void declDefProcDefNoParenOpen() { + enum SYNTAX_ERROR error = setupError("def init[\n"); + assert(error == INVALID_DEF_PAREN_OPEN); +} diff --git a/test/parser_integration_tests.h b/test/parser_integration_tests.h index 42c2123..7d0fd1c 100644 --- a/test/parser_integration_tests.h +++ b/test/parser_integration_tests.h @@ -38,5 +38,6 @@ void declDefProcProtoNoParenClose(); void declDefProcProtoTwoProts(); void declDefProcDefDefWorksToo(); +void declDefProcDefNoParenOpen(); #endif // !PARSER_INTEGRATION_TESTS_H diff --git a/test/test.c b/test/test.c index a612d3b..35adfae 100644 --- a/test/test.c +++ b/test/test.c @@ -58,6 +58,7 @@ int main(void) { declDefProcProtoTwoProts(); declDefProcDefDefWorksToo(); + declDefProcDefNoParenOpen(); printf("--- Parser integration tests passed\n"); From 370375afe69b9ca7eff4b3d6ab6ca588fb2d1a46 Mon Sep 17 00:00:00 2001 From: wilyJ80 Date: Tue, 10 Dec 2024 14:28:55 +0000 Subject: [PATCH 04/27] feat: start def param function --- parser/parser.c | 11 ++++++++++- parser/parser.h | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/parser/parser.c b/parser/parser.c index 23bac83..158bf8a 100644 --- a/parser/parser.c +++ b/parser/parser.c @@ -261,6 +261,16 @@ enum SYNTAX_ERROR declDef(struct Parser *parser) { return INVALID_DEF_PAREN_OPEN; } + parser->token = lexerGetNextChar(parser->fd, parser->lineCount); + enum SYNTAX_ERROR error = declDefParam(parser); + if (error != NO_ERROR) { + return error; + } + + return NO_ERROR; +} + +enum SYNTAX_ERROR declDefParam(struct Parser *parser) { return NO_ERROR; } @@ -290,7 +300,6 @@ enum SYNTAX_ERROR declProt(struct Parser *parser) { } enum SYNTAX_ERROR declProtParam(struct Parser *parser) { - if (parser->token.category == SIGN && parser->token.signCode == REF) { parser->token = lexerGetNextChar(parser->fd, parser->lineCount); } diff --git a/parser/parser.h b/parser/parser.h index dc31405..1e5d180 100644 --- a/parser/parser.h +++ b/parser/parser.h @@ -35,5 +35,6 @@ enum SYNTAX_ERROR declProtParam(struct Parser *parser); /*void arrayInitialization(FILE *fd, int *lineCount, struct Token token);*/ enum SYNTAX_ERROR declDef(struct Parser *parser); +enum SYNTAX_ERROR declDefParam(struct Parser *parser); #endif From f21eff696dc7688fc3905654b321822ec904adc7 Mon Sep 17 00:00:00 2001 From: wilyJ80 Date: Tue, 10 Dec 2024 16:45:51 +0000 Subject: [PATCH 05/27] test: def param type valid --- parser/parser.c | 13 +++++++++++++ test/parser_integration_tests.c | 7 +++++++ test/parser_integration_tests.h | 1 + test/test.c | 1 + 4 files changed, 22 insertions(+) diff --git a/parser/parser.c b/parser/parser.c index 158bf8a..20068c1 100644 --- a/parser/parser.c +++ b/parser/parser.c @@ -271,6 +271,19 @@ enum SYNTAX_ERROR declDef(struct Parser *parser) { } enum SYNTAX_ERROR declDefParam(struct Parser *parser) { + // while it's a param, delimited by comma + do { + // & is optional + if (parser->token.category == SIGN && parser->token.signCode == REF) { + parser->token = lexerGetNextChar(parser->fd, parser->lineCount); + } + + if (!(parser->token.category == RSV && (parser->token.signCode == INTCON || parser->token.signCode == CHARCON || parser->token.signCode == REALCON || parser->token.signCode == BOOL))) { + return INVALID_DEF_PARAM_TYPE; + } + + } while (parser->token.category == SIGN && parser->token.signCode == COMMA); + return NO_ERROR; } diff --git a/test/parser_integration_tests.c b/test/parser_integration_tests.c index 50b61c4..439bdf9 100644 --- a/test/parser_integration_tests.c +++ b/test/parser_integration_tests.c @@ -173,3 +173,10 @@ void declDefProcDefNoParenOpen() { enum SYNTAX_ERROR error = setupError("def init[\n"); assert(error == INVALID_DEF_PAREN_OPEN); } + +void declDefProcDefBadParamType() { + enum SYNTAX_ERROR error = setupError("def indio(&string\n"); + assert(error == INVALID_DEF_PARAM_TYPE); +} + + diff --git a/test/parser_integration_tests.h b/test/parser_integration_tests.h index 7d0fd1c..de8ad8f 100644 --- a/test/parser_integration_tests.h +++ b/test/parser_integration_tests.h @@ -39,5 +39,6 @@ void declDefProcProtoTwoProts(); void declDefProcDefDefWorksToo(); void declDefProcDefNoParenOpen(); +void declDefProcDefBadParamType(); #endif // !PARSER_INTEGRATION_TESTS_H diff --git a/test/test.c b/test/test.c index 35adfae..6207a75 100644 --- a/test/test.c +++ b/test/test.c @@ -59,6 +59,7 @@ int main(void) { declDefProcDefDefWorksToo(); declDefProcDefNoParenOpen(); + declDefProcDefBadParamType(); printf("--- Parser integration tests passed\n"); From 828e1b3ac5b4cc540c78f6d0744f55c91855f5e3 Mon Sep 17 00:00:00 2001 From: wilyJ80 Date: Tue, 10 Dec 2024 17:58:43 +0000 Subject: [PATCH 06/27] test: no def param id --- parser/parser.c | 5 +++++ test/parser_integration_tests.c | 5 ++++- test/parser_integration_tests.h | 1 + test/test.c | 1 + 4 files changed, 11 insertions(+), 1 deletion(-) diff --git a/parser/parser.c b/parser/parser.c index 20068c1..d71440f 100644 --- a/parser/parser.c +++ b/parser/parser.c @@ -282,6 +282,11 @@ enum SYNTAX_ERROR declDefParam(struct Parser *parser) { return INVALID_DEF_PARAM_TYPE; } + parser->token = lexerGetNextChar(parser->fd, parser->lineCount); + if (!(parser->token.category == ID)) { + return NO_DEF_PARAM_ID; + } + } while (parser->token.category == SIGN && parser->token.signCode == COMMA); return NO_ERROR; diff --git a/test/parser_integration_tests.c b/test/parser_integration_tests.c index 439bdf9..42fbfa1 100644 --- a/test/parser_integration_tests.c +++ b/test/parser_integration_tests.c @@ -179,4 +179,7 @@ void declDefProcDefBadParamType() { assert(error == INVALID_DEF_PARAM_TYPE); } - +void declDefProcDefNoParamId() { + enum SYNTAX_ERROR error = setupError("def radio(int 8)"); + assert(error == NO_DEF_PARAM_ID); +} diff --git a/test/parser_integration_tests.h b/test/parser_integration_tests.h index de8ad8f..e8eea07 100644 --- a/test/parser_integration_tests.h +++ b/test/parser_integration_tests.h @@ -40,5 +40,6 @@ void declDefProcProtoTwoProts(); void declDefProcDefDefWorksToo(); void declDefProcDefNoParenOpen(); void declDefProcDefBadParamType(); +void declDefProcDefNoParamId(); #endif // !PARSER_INTEGRATION_TESTS_H diff --git a/test/test.c b/test/test.c index 6207a75..658386e 100644 --- a/test/test.c +++ b/test/test.c @@ -60,6 +60,7 @@ int main(void) { declDefProcDefDefWorksToo(); declDefProcDefNoParenOpen(); declDefProcDefBadParamType(); + declDefProcDefNoParamId(); printf("--- Parser integration tests passed\n"); From 950dcb9ab4d3998be2793c0d149a77bfea24716b Mon Sep 17 00:00:00 2001 From: wilyJ80 Date: Tue, 10 Dec 2024 20:09:32 +0000 Subject: [PATCH 07/27] test: no def valid token after id --- parser/parser.c | 8 ++++++++ parser/syntax_error.c | 4 +++- parser/syntax_error.h | 1 + test/parser_integration_tests.c | 5 +++++ test/parser_integration_tests.h | 1 + test/test.c | 1 + 6 files changed, 19 insertions(+), 1 deletion(-) diff --git a/parser/parser.c b/parser/parser.c index d71440f..d33b45e 100644 --- a/parser/parser.c +++ b/parser/parser.c @@ -278,15 +278,23 @@ enum SYNTAX_ERROR declDefParam(struct Parser *parser) { parser->token = lexerGetNextChar(parser->fd, parser->lineCount); } + // type is valid if (!(parser->token.category == RSV && (parser->token.signCode == INTCON || parser->token.signCode == CHARCON || parser->token.signCode == REALCON || parser->token.signCode == BOOL))) { return INVALID_DEF_PARAM_TYPE; } + // param id parser->token = lexerGetNextChar(parser->fd, parser->lineCount); if (!(parser->token.category == ID)) { return NO_DEF_PARAM_ID; } + // valid token after id + parser->token = lexerGetNextChar(parser->fd, parser->lineCount); + if (!(parser->token.category == SIGN && (parser->token.signCode == OPEN_BRACK || parser->token.signCode == COMMA || parser->token.signCode == CLOSE_PAR))) { + return NO_DEF_VALID_TOKEN_AFTER_ID; + } + } while (parser->token.category == SIGN && parser->token.signCode == COMMA); return NO_ERROR; diff --git a/parser/syntax_error.c b/parser/syntax_error.c index 0a79784..cf26342 100644 --- a/parser/syntax_error.c +++ b/parser/syntax_error.c @@ -2,7 +2,7 @@ #include #include -#define ERROR_QTY 86 +#define ERROR_QTY 87 // ANSI escape codes #define RESET "\033[0m" @@ -63,6 +63,8 @@ void printSyntaxError(enum SYNTAX_ERROR error, int *lineCount) { {INVALID_DEF_PAREN_CLOSE, "No valid paren close for function definition"}, {INVALID_DEF_PARAM_TYPE, "No valid parameter type for function definition"}, + {NO_DEF_VALID_TOKEN_AFTER_ID, "No valid token after def id, expected " + "open bracket, comma or paren close"}, {NO_DEF_PARAM_ID, "No ID detected for function definition parameter"}, {INVALID_ARRAY_DEF_PARAM_SUBSCRIPT_TYPE, "No valid type for subscript in array parameter of function " diff --git a/parser/syntax_error.h b/parser/syntax_error.h index 6cab88f..cd3152b 100644 --- a/parser/syntax_error.h +++ b/parser/syntax_error.h @@ -41,6 +41,7 @@ enum SYNTAX_ERROR { INVALID_DEF_PAREN_OPEN, INVALID_DEF_PAREN_CLOSE, INVALID_DEF_PARAM_TYPE, + NO_DEF_VALID_TOKEN_AFTER_ID, NO_DEF_PARAM_ID, INVALID_ARRAY_DEF_PARAM_SUBSCRIPT_TYPE, INVALID_ARRAY_DEF_PARAM_BRACKET_OPEN, diff --git a/test/parser_integration_tests.c b/test/parser_integration_tests.c index 42fbfa1..fd3e9d7 100644 --- a/test/parser_integration_tests.c +++ b/test/parser_integration_tests.c @@ -183,3 +183,8 @@ void declDefProcDefNoParamId() { enum SYNTAX_ERROR error = setupError("def radio(int 8)"); assert(error == NO_DEF_PARAM_ID); } + +void declDefProcDefNoValidTokenAfterId() { + enum SYNTAX_ERROR error = setupError("def cesio(int a("); + assert(error == NO_DEF_VALID_TOKEN_AFTER_ID); +} diff --git a/test/parser_integration_tests.h b/test/parser_integration_tests.h index e8eea07..761092f 100644 --- a/test/parser_integration_tests.h +++ b/test/parser_integration_tests.h @@ -41,5 +41,6 @@ void declDefProcDefDefWorksToo(); void declDefProcDefNoParenOpen(); void declDefProcDefBadParamType(); void declDefProcDefNoParamId(); +void declDefProcDefNoValidTokenAfterId(); #endif // !PARSER_INTEGRATION_TESTS_H diff --git a/test/test.c b/test/test.c index 658386e..abb7ab3 100644 --- a/test/test.c +++ b/test/test.c @@ -61,6 +61,7 @@ int main(void) { declDefProcDefNoParenOpen(); declDefProcDefBadParamType(); declDefProcDefNoParamId(); + declDefProcDefNoValidTokenAfterId(); printf("--- Parser integration tests passed\n"); From d7e05e658f9a06dffc4b062175727f341b8443f9 Mon Sep 17 00:00:00 2001 From: wilyJ80 Date: Tue, 10 Dec 2024 23:47:18 +0000 Subject: [PATCH 08/27] test: valid token after function def paren --- parser/parser.c | 33 +++++++++++++++++++++++++++++++-- parser/syntax_error.c | 5 ++++- parser/syntax_error.h | 1 + test/parser_integration_tests.c | 7 ++++++- test/parser_integration_tests.h | 1 + test/test.c | 1 + 6 files changed, 44 insertions(+), 4 deletions(-) diff --git a/parser/parser.c b/parser/parser.c index d33b45e..0034206 100644 --- a/parser/parser.c +++ b/parser/parser.c @@ -2,6 +2,7 @@ #include "../lexer/lexer.h" #include "../lexer/transition.h" #include "syntax_error.h" +#include #define MAX_ARRAY_DIMENSIONS 2 @@ -261,12 +262,33 @@ enum SYNTAX_ERROR declDef(struct Parser *parser) { return INVALID_DEF_PAREN_OPEN; } + // valid param loop parser->token = lexerGetNextChar(parser->fd, parser->lineCount); enum SYNTAX_ERROR error = declDefParam(parser); if (error != NO_ERROR) { return error; } + // can be endp, declListVar, or cmd + parser->token = lexerGetNextChar(parser->fd, parser->lineCount); + if (!(parser->token.category == ID || + (parser->token.category == RSV && + (parser->token.signCode == CONST || parser->token.signCode == INT || + parser->token.signCode == CHAR || parser->token.signCode == REAL || + parser->token.signCode == BOOL || parser->token.signCode == WHILE || + parser->token.signCode == VAR || parser->token.signCode == IF || + parser->token.signCode == GETOUT || + parser->token.signCode == GETINT || + parser->token.signCode == GETREAL || + parser->token.signCode == GETCHAR || + parser->token.signCode == GETSTR || + parser->token.signCode == PUTINT || + parser->token.signCode == PUTREAL || + parser->token.signCode == PUTCHAR || + parser->token.signCode == PUTSTR)))) { + return NO_DEF_VALID_TOKEN_AFTER_PAREN; + } + return NO_ERROR; } @@ -279,7 +301,9 @@ enum SYNTAX_ERROR declDefParam(struct Parser *parser) { } // type is valid - if (!(parser->token.category == RSV && (parser->token.signCode == INTCON || parser->token.signCode == CHARCON || parser->token.signCode == REALCON || parser->token.signCode == BOOL))) { + if (!(parser->token.category == RSV && + (parser->token.signCode == INT || parser->token.signCode == CHAR || + parser->token.signCode == REAL || parser->token.signCode == BOOL))) { return INVALID_DEF_PARAM_TYPE; } @@ -291,10 +315,15 @@ enum SYNTAX_ERROR declDefParam(struct Parser *parser) { // valid token after id parser->token = lexerGetNextChar(parser->fd, parser->lineCount); - if (!(parser->token.category == SIGN && (parser->token.signCode == OPEN_BRACK || parser->token.signCode == COMMA || parser->token.signCode == CLOSE_PAR))) { + if (!(parser->token.category == SIGN && + (parser->token.signCode == OPEN_BRACK || + parser->token.signCode == COMMA || + parser->token.signCode == CLOSE_PAR))) { return NO_DEF_VALID_TOKEN_AFTER_ID; } + // CLOSE_PAR simply breaks the loop and leaves + } while (parser->token.category == SIGN && parser->token.signCode == COMMA); return NO_ERROR; diff --git a/parser/syntax_error.c b/parser/syntax_error.c index cf26342..97520ff 100644 --- a/parser/syntax_error.c +++ b/parser/syntax_error.c @@ -2,7 +2,7 @@ #include #include -#define ERROR_QTY 87 +#define ERROR_QTY 88 // ANSI escape codes #define RESET "\033[0m" @@ -76,6 +76,9 @@ void printSyntaxError(enum SYNTAX_ERROR error, int *lineCount) { {INVALID_DEF_PARAM_LIST, "Invalid parameter list for function definition"}, {NO_DEF_END_KEYWORD, "End keyword for function definition not detected"}, + {NO_DEF_VALID_TOKEN_AFTER_PAREN, + "No valid token after def paren close, expected endp, variable " + "declaration, or cmd"}, {NO_FUNCTION_END_PAREN_CLOSE, "No paren close for function end"}, // cmd {INVALID_CMD_CONTENT, "Invalid command keyword or content"}, diff --git a/parser/syntax_error.h b/parser/syntax_error.h index cd3152b..ac83c21 100644 --- a/parser/syntax_error.h +++ b/parser/syntax_error.h @@ -48,6 +48,7 @@ enum SYNTAX_ERROR { INVALID_ARRAY_DEF_PARAM_BRACKET_CLOSE, INVALID_DEF_PARAM_LIST, NO_DEF_END_KEYWORD, + NO_DEF_VALID_TOKEN_AFTER_PAREN, NO_FUNCTION_END_PAREN_CLOSE, // cmd INVALID_CMD_CONTENT, diff --git a/test/parser_integration_tests.c b/test/parser_integration_tests.c index fd3e9d7..0ebc7cf 100644 --- a/test/parser_integration_tests.c +++ b/test/parser_integration_tests.c @@ -5,7 +5,7 @@ #include // switch this on to output all syntax errors -#define SHOW_ERRORS false +#define SHOW_ERRORS true enum SYNTAX_ERROR setupError(const char *mockData) { FILE *mockFile = fmemopen((void *)mockData, strlen(mockData), "r"); @@ -188,3 +188,8 @@ void declDefProcDefNoValidTokenAfterId() { enum SYNTAX_ERROR error = setupError("def cesio(int a("); assert(error == NO_DEF_VALID_TOKEN_AFTER_ID); } + +void declDefProcDefValidTokenAfterClosePar() { +enum SYNTAX_ERROR error = setupError("def carbono(char ch) 8"); + assert(error == NO_DEF_VALID_TOKEN_AFTER_PAREN); +} diff --git a/test/parser_integration_tests.h b/test/parser_integration_tests.h index 761092f..710336a 100644 --- a/test/parser_integration_tests.h +++ b/test/parser_integration_tests.h @@ -42,5 +42,6 @@ void declDefProcDefNoParenOpen(); void declDefProcDefBadParamType(); void declDefProcDefNoParamId(); void declDefProcDefNoValidTokenAfterId(); +void declDefProcDefValidTokenAfterClosePar(); #endif // !PARSER_INTEGRATION_TESTS_H diff --git a/test/test.c b/test/test.c index abb7ab3..266f308 100644 --- a/test/test.c +++ b/test/test.c @@ -62,6 +62,7 @@ int main(void) { declDefProcDefBadParamType(); declDefProcDefNoParamId(); declDefProcDefNoValidTokenAfterId(); + declDefProcDefValidTokenAfterClosePar(); printf("--- Parser integration tests passed\n"); From 2c603b2411769a60e97fa2cdd07b5abd2e4efdd2 Mon Sep 17 00:00:00 2001 From: wilyJ80 Date: Wed, 11 Dec 2024 14:16:53 -0300 Subject: [PATCH 09/27] test: ongoing multidimensional array tests --- parser/parser.c | 31 +++++++++++++++++++++++++++++-- parser/parser.h | 1 + test/parser_integration_tests.c | 19 +++++++++++++++++-- test/parser_integration_tests.h | 4 ++++ test/test.c | 3 +++ 5 files changed, 54 insertions(+), 4 deletions(-) diff --git a/parser/parser.c b/parser/parser.c index 0034206..16ee3ff 100644 --- a/parser/parser.c +++ b/parser/parser.c @@ -2,7 +2,6 @@ #include "../lexer/lexer.h" #include "../lexer/transition.h" #include "syntax_error.h" -#include #define MAX_ARRAY_DIMENSIONS 2 @@ -321,14 +320,42 @@ enum SYNTAX_ERROR declDefParam(struct Parser *parser) { parser->token.signCode == CLOSE_PAR))) { return NO_DEF_VALID_TOKEN_AFTER_ID; } + // CLOSE_PAR has no extra steps: simply breaks the loop and leaves - // CLOSE_PAR simply breaks the loop and leaves + // OPEN_BRACK defines an array param + if (parser->token.signCode == OPEN_BRACK) { + enum SYNTAX_ERROR error = declDefParamArray(parser); + if (error != NO_ERROR) { + return error; + } + } + // COMMA loops the whole thing } while (parser->token.category == SIGN && parser->token.signCode == COMMA); return NO_ERROR; } +enum SYNTAX_ERROR declDefParamArray(struct Parser *parser) { + do { + parser->token = lexerGetNextChar(parser->fd, parser->lineCount); + if (!(parser->token.category == ID || parser->token.category == INTCON)) { + return INVALID_ARRAY_DEF_PARAM_SUBSCRIPT_TYPE; + } + + parser->token = lexerGetNextChar(parser->fd, parser->lineCount); + if (!(parser->token.category == SIGN && + parser->token.signCode == CLOSE_BRACK)) { + return INVALID_ARRAY_DEF_PARAM_BRACKET_CLOSE; + } + + // consume next (should be OPEN_BRACK or COMMA) + parser->token = lexerGetNextChar(parser->fd, parser->lineCount); + } while (parser->token.signCode == OPEN_BRACK); + + return NO_ERROR; +} + enum SYNTAX_ERROR declProt(struct Parser *parser) { if (!(parser->token.category == ID)) { return NO_PROTO_ID; diff --git a/parser/parser.h b/parser/parser.h index 1e5d180..b4fd77d 100644 --- a/parser/parser.h +++ b/parser/parser.h @@ -36,5 +36,6 @@ enum SYNTAX_ERROR declProtParam(struct Parser *parser); enum SYNTAX_ERROR declDef(struct Parser *parser); enum SYNTAX_ERROR declDefParam(struct Parser *parser); +enum SYNTAX_ERROR declDefParamArray(struct Parser *parser); #endif diff --git a/test/parser_integration_tests.c b/test/parser_integration_tests.c index 0ebc7cf..eaed99c 100644 --- a/test/parser_integration_tests.c +++ b/test/parser_integration_tests.c @@ -5,7 +5,7 @@ #include // switch this on to output all syntax errors -#define SHOW_ERRORS true +#define SHOW_ERRORS false enum SYNTAX_ERROR setupError(const char *mockData) { FILE *mockFile = fmemopen((void *)mockData, strlen(mockData), "r"); @@ -190,6 +190,21 @@ void declDefProcDefNoValidTokenAfterId() { } void declDefProcDefValidTokenAfterClosePar() { -enum SYNTAX_ERROR error = setupError("def carbono(char ch) 8"); + enum SYNTAX_ERROR error = setupError("def carbono(char ch) 8"); assert(error == NO_DEF_VALID_TOKEN_AFTER_PAREN); } + +void declDefProcDefArrayBadSubscriptType() { + enum SYNTAX_ERROR error = setupError("def sodio(char ch['a'])"); + assert(error == INVALID_ARRAY_DEF_PARAM_SUBSCRIPT_TYPE); +} + +void declDefProcDefArrayUnclosedBracket() { + enum SYNTAX_ERROR error = setupError("def uranio(int z[8[)"); + assert(error == INVALID_ARRAY_DEF_PARAM_BRACKET_CLOSE); +} + +void declDefProcDefArrayMultidimension() { + enum SYNTAX_ERROR error = setupError("def galio(int j[8][8[)"); + assert(error == INVALID_ARRAY_DEF_PARAM_BRACKET_CLOSE); +} diff --git a/test/parser_integration_tests.h b/test/parser_integration_tests.h index 710336a..749a25b 100644 --- a/test/parser_integration_tests.h +++ b/test/parser_integration_tests.h @@ -44,4 +44,8 @@ void declDefProcDefNoParamId(); void declDefProcDefNoValidTokenAfterId(); void declDefProcDefValidTokenAfterClosePar(); +void declDefProcDefArrayBadSubscriptType(); +void declDefProcDefArrayUnclosedBracket(); +void declDefProcDefArrayMultidimension(); + #endif // !PARSER_INTEGRATION_TESTS_H diff --git a/test/test.c b/test/test.c index 266f308..fbc0c4d 100644 --- a/test/test.c +++ b/test/test.c @@ -63,6 +63,9 @@ int main(void) { declDefProcDefNoParamId(); declDefProcDefNoValidTokenAfterId(); declDefProcDefValidTokenAfterClosePar(); + declDefProcDefArrayBadSubscriptType(); + declDefProcDefArrayUnclosedBracket(); + declDefProcDefArrayMultidimension(); printf("--- Parser integration tests passed\n"); From 657039c976ec4ccc5491b632842bead4cc64bfdd Mon Sep 17 00:00:00 2001 From: wilyJ80 Date: Wed, 11 Dec 2024 14:32:35 -0300 Subject: [PATCH 10/27] test: finish def param --- parser/parser.c | 6 ++++++ test/parser_integration_tests.c | 7 ++++++- test/parser_integration_tests.h | 1 + test/test.c | 1 + 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/parser/parser.c b/parser/parser.c index 16ee3ff..89189ef 100644 --- a/parser/parser.c +++ b/parser/parser.c @@ -294,6 +294,11 @@ enum SYNTAX_ERROR declDef(struct Parser *parser) { enum SYNTAX_ERROR declDefParam(struct Parser *parser) { // while it's a param, delimited by comma do { + // skip the comma if it's a subsequent param + if (parser->token.category == SIGN && parser->token.signCode == COMMA) { + parser->token = lexerGetNextChar(parser->fd, parser->lineCount); + } + // & is optional if (parser->token.category == SIGN && parser->token.signCode == REF) { parser->token = lexerGetNextChar(parser->fd, parser->lineCount); @@ -353,6 +358,7 @@ enum SYNTAX_ERROR declDefParamArray(struct Parser *parser) { parser->token = lexerGetNextChar(parser->fd, parser->lineCount); } while (parser->token.signCode == OPEN_BRACK); + // is COMMA return NO_ERROR; } diff --git a/test/parser_integration_tests.c b/test/parser_integration_tests.c index eaed99c..eb1f2b9 100644 --- a/test/parser_integration_tests.c +++ b/test/parser_integration_tests.c @@ -5,7 +5,7 @@ #include // switch this on to output all syntax errors -#define SHOW_ERRORS false +#define SHOW_ERRORS true enum SYNTAX_ERROR setupError(const char *mockData) { FILE *mockFile = fmemopen((void *)mockData, strlen(mockData), "r"); @@ -208,3 +208,8 @@ void declDefProcDefArrayMultidimension() { enum SYNTAX_ERROR error = setupError("def galio(int j[8][8[)"); assert(error == INVALID_ARRAY_DEF_PARAM_BRACKET_CLOSE); } + +void declDefProcDefArrayMultiParamMultiDimension() { + enum SYNTAX_ERROR error = setupError("def galio(int j[8][8], char x[4][3[)"); + assert(error == INVALID_ARRAY_DEF_PARAM_BRACKET_CLOSE); +} diff --git a/test/parser_integration_tests.h b/test/parser_integration_tests.h index 749a25b..dd708ef 100644 --- a/test/parser_integration_tests.h +++ b/test/parser_integration_tests.h @@ -47,5 +47,6 @@ void declDefProcDefValidTokenAfterClosePar(); void declDefProcDefArrayBadSubscriptType(); void declDefProcDefArrayUnclosedBracket(); void declDefProcDefArrayMultidimension(); +void declDefProcDefArrayMultiParamMultiDimension(); #endif // !PARSER_INTEGRATION_TESTS_H diff --git a/test/test.c b/test/test.c index fbc0c4d..650ebb0 100644 --- a/test/test.c +++ b/test/test.c @@ -66,6 +66,7 @@ int main(void) { declDefProcDefArrayBadSubscriptType(); declDefProcDefArrayUnclosedBracket(); declDefProcDefArrayMultidimension(); + declDefProcDefArrayMultiParamMultiDimension(); printf("--- Parser integration tests passed\n"); From 01b02e302739202ec608c2a75523938f5f773f4b Mon Sep 17 00:00:00 2001 From: wilyJ80 Date: Wed, 11 Dec 2024 14:52:01 -0300 Subject: [PATCH 11/27] test: test for cmd --- parser/parser.c | 41 +++++++++++++++++++++++++++++++++ parser/parser.h | 3 +++ test/parser_integration_tests.c | 21 +++++++++++++++++ test/parser_integration_tests.h | 3 +++ test/test.c | 3 +++ 5 files changed, 71 insertions(+) diff --git a/parser/parser.c b/parser/parser.c index 89189ef..9997adc 100644 --- a/parser/parser.c +++ b/parser/parser.c @@ -288,6 +288,47 @@ enum SYNTAX_ERROR declDef(struct Parser *parser) { return NO_DEF_VALID_TOKEN_AFTER_PAREN; } + // is decl_list_var + if (parser->token.signCode == CONST || parser->token.signCode == CHAR || + parser->token.signCode == INT || parser->token.signCode == REAL || + parser->token.signCode == BOOL) { + enum SYNTAX_ERROR error = declListVar(parser); + if (error != NO_ERROR) { + return error; + } + } + + // is cmd + if (parser->token.category == RSV && + (parser->token.signCode == DO || parser->token.signCode == WHILE || + parser->token.signCode == VAR || parser->token.signCode == IF || + parser->token.signCode == GETOUT || + parser->token.signCode == GETINT || + parser->token.signCode == GETREAL || + parser->token.signCode == GETCHAR || + parser->token.signCode == GETSTR || + parser->token.signCode == PUTINT || + parser->token.signCode == PUTREAL || + parser->token.signCode == PUTCHAR || + parser->token.signCode == PUTSTR) || + parser->token.category == ID) { + enum SYNTAX_ERROR error = cmd(parser); + if (error != NO_ERROR) { + return error; + } + } + + return NO_ERROR; +} + +enum SYNTAX_ERROR cmd(struct Parser *parser) { + if (parser->token.signCode == GETINT) { + parser->token = lexerGetNextChar(parser->fd, parser->lineCount); + if (!(parser->token.category == ID)) { + return NO_GETINT_ID; + } + } + return NO_ERROR; } diff --git a/parser/parser.h b/parser/parser.h index b4fd77d..a8b356e 100644 --- a/parser/parser.h +++ b/parser/parser.h @@ -38,4 +38,7 @@ enum SYNTAX_ERROR declDef(struct Parser *parser); enum SYNTAX_ERROR declDefParam(struct Parser *parser); enum SYNTAX_ERROR declDefParamArray(struct Parser *parser); +enum SYNTAX_ERROR cmd(struct Parser *parser); +enum SYNTAX_ERROR getint(struct Parser *parser); + #endif diff --git a/test/parser_integration_tests.c b/test/parser_integration_tests.c index eb1f2b9..091a90b 100644 --- a/test/parser_integration_tests.c +++ b/test/parser_integration_tests.c @@ -213,3 +213,24 @@ void declDefProcDefArrayMultiParamMultiDimension() { enum SYNTAX_ERROR error = setupError("def galio(int j[8][8], char x[4][3[)"); assert(error == INVALID_ARRAY_DEF_PARAM_BRACKET_CLOSE); } + +void declDefProcDefFollowedByDeclListVarError() { + enum SYNTAX_ERROR error = setupError("def litio(int i) const string"); + assert(error == INVALID_TYPE); +} + +void declDefProcDefFollowedByCmdError() { + enum SYNTAX_ERROR error = setupError("def plutonio(int i) getint 1"); + assert(error == NO_GETINT_ID); +} + + +// test for cmd error after valid def and decl_list_var + +// test for no endp error + +// a perfectly valid variable declaration-only program + +// a perfectly valid function prototype declaration-only program + +// a perfectly valid function definition-only program diff --git a/test/parser_integration_tests.h b/test/parser_integration_tests.h index dd708ef..244b9ba 100644 --- a/test/parser_integration_tests.h +++ b/test/parser_integration_tests.h @@ -49,4 +49,7 @@ void declDefProcDefArrayUnclosedBracket(); void declDefProcDefArrayMultidimension(); void declDefProcDefArrayMultiParamMultiDimension(); +void declDefProcDefFollowedByDeclListVarError(); +void declDefProcDefFollowedByCmdError(); + #endif // !PARSER_INTEGRATION_TESTS_H diff --git a/test/test.c b/test/test.c index 650ebb0..db578d4 100644 --- a/test/test.c +++ b/test/test.c @@ -68,6 +68,9 @@ int main(void) { declDefProcDefArrayMultidimension(); declDefProcDefArrayMultiParamMultiDimension(); + declDefProcDefFollowedByDeclListVarError(); + declDefProcDefFollowedByCmdError(); + printf("--- Parser integration tests passed\n"); printf(GREEN "All tests OK\n" RESET); From 7e333604fd20be0cb188d6c73054427343af1c68 Mon Sep 17 00:00:00 2001 From: wilyJ80 Date: Wed, 11 Dec 2024 15:02:37 -0300 Subject: [PATCH 12/27] test: declListVar and cmd correctly repeats after def --- test/parser_integration_tests.c | 18 +++++++++++++++++- test/parser_integration_tests.h | 3 +++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/test/parser_integration_tests.c b/test/parser_integration_tests.c index 091a90b..ba9b6b7 100644 --- a/test/parser_integration_tests.c +++ b/test/parser_integration_tests.c @@ -224,8 +224,24 @@ void declDefProcDefFollowedByCmdError() { assert(error == NO_GETINT_ID); } - // test for cmd error after valid def and decl_list_var +void declDefProcDefFollowedByDeclListVarFollowedByCmdError() { + enum SYNTAX_ERROR error = setupError("def plutonio(int i) const int n getint 1"); + assert(error == NO_GETINT_ID); +} + +// test for cmd error after valid def and multiple decl_list_var +void declDefProcDefFollowedByMultipleDeclListVarFollowedByCmdError() { + enum SYNTAX_ERROR error = setupError("def plutonio(int i) const int n const int g getint 1"); + assert(error == NO_GETINT_ID); +} + +// multiple cmds +void declDefProcDefFollowedByMultipleCmdError() { + enum SYNTAX_ERROR error = setupError("def plutonio(int i, int j) getint i getint 44"); + assert(error == NO_GETINT_ID); +} +// more exhaustive tests could be made, but I have work to do // test for no endp error diff --git a/test/parser_integration_tests.h b/test/parser_integration_tests.h index 244b9ba..e8957eb 100644 --- a/test/parser_integration_tests.h +++ b/test/parser_integration_tests.h @@ -51,5 +51,8 @@ void declDefProcDefArrayMultiParamMultiDimension(); void declDefProcDefFollowedByDeclListVarError(); void declDefProcDefFollowedByCmdError(); +void declDefProcDefFollowedByDeclListVarFollowedByCmdError(); +void declDefProcDefFollowedByMultipleDeclListVarFollowedByCmdError(); +void declDefProcDefFollowedByMultipleCmdError(); #endif // !PARSER_INTEGRATION_TESTS_H From c89a23cd959084f0f5eaca8fb33defa27efc412f Mon Sep 17 00:00:00 2001 From: wilyJ80 Date: Wed, 11 Dec 2024 15:28:36 -0300 Subject: [PATCH 13/27] despair: tests failing --- test/parser_integration_tests.c | 6 ++++++ test/parser_integration_tests.h | 1 + test/test.c | 1 + 3 files changed, 8 insertions(+) diff --git a/test/parser_integration_tests.c b/test/parser_integration_tests.c index ba9b6b7..67d3ae9 100644 --- a/test/parser_integration_tests.c +++ b/test/parser_integration_tests.c @@ -224,6 +224,8 @@ void declDefProcDefFollowedByCmdError() { assert(error == NO_GETINT_ID); } +// TODO: + // test for cmd error after valid def and decl_list_var void declDefProcDefFollowedByDeclListVarFollowedByCmdError() { enum SYNTAX_ERROR error = setupError("def plutonio(int i) const int n getint 1"); @@ -244,6 +246,10 @@ void declDefProcDefFollowedByMultipleCmdError() { // more exhaustive tests could be made, but I have work to do // test for no endp error +void declDefProcDefFollowedByABunchOfStuffButNotFinishingWithEndp() { + enum SYNTAX_ERROR error = setupError("def galibdenio(int i) const int n getint n prot"); + assert(error == NO_DEF_END_KEYWORD); +} // a perfectly valid variable declaration-only program diff --git a/test/parser_integration_tests.h b/test/parser_integration_tests.h index e8957eb..2d72a55 100644 --- a/test/parser_integration_tests.h +++ b/test/parser_integration_tests.h @@ -54,5 +54,6 @@ void declDefProcDefFollowedByCmdError(); void declDefProcDefFollowedByDeclListVarFollowedByCmdError(); void declDefProcDefFollowedByMultipleDeclListVarFollowedByCmdError(); void declDefProcDefFollowedByMultipleCmdError(); +void declDefProcDefFollowedByABunchOfStuffButNotFinishingWithEndp(); #endif // !PARSER_INTEGRATION_TESTS_H diff --git a/test/test.c b/test/test.c index db578d4..bb4eb87 100644 --- a/test/test.c +++ b/test/test.c @@ -70,6 +70,7 @@ int main(void) { declDefProcDefFollowedByDeclListVarError(); declDefProcDefFollowedByCmdError(); + declDefProcDefFollowedByDeclListVarFollowedByCmdError(); printf("--- Parser integration tests passed\n"); From bf912c351971b970ad543811b3611055b1ee1a85 Mon Sep 17 00:00:00 2001 From: wilyJ80 Date: Wed, 11 Dec 2024 17:27:30 -0300 Subject: [PATCH 14/27] fix: WORKING failed tests. Hack. --- parser/parser.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/parser/parser.c b/parser/parser.c index 9997adc..918316e 100644 --- a/parser/parser.c +++ b/parser/parser.c @@ -137,8 +137,8 @@ enum SYNTAX_ERROR declListVar(struct Parser *parser) { if (error != NO_ERROR) { return error; } - // TODO: handle multiple variable declarations here - parser->token = lexerGetNextChar(parser->fd, parser->lineCount); + // handle multiple variable declarations here + // parser->token = lexerGetNextChar(parser->fd, parser->lineCount); while (parser->token.category == SIGN && parser->token.signCode == COMMA) { parser->token = lexerGetNextChar(parser->fd, parser->lineCount); enum SYNTAX_ERROR error = declVar(parser); @@ -149,6 +149,7 @@ enum SYNTAX_ERROR declListVar(struct Parser *parser) { return NO_ERROR; } +// HACK: This looks BAD !!! enum SYNTAX_ERROR declVar(struct Parser *parser) { if (parser->token.category != ID) { return NO_VAR_ID; @@ -156,6 +157,7 @@ enum SYNTAX_ERROR declVar(struct Parser *parser) { parser->token = lexerGetNextChar(parser->fd, parser->lineCount); bool isArray = false; + bool isAssignment = false; int arrayDimensions = 0; // is array if (parser->token.category == SIGN && parser->token.signCode == OPEN_BRACK) { @@ -184,6 +186,7 @@ enum SYNTAX_ERROR declVar(struct Parser *parser) { // assignment if (parser->token.category == SIGN && parser->token.signCode == ASSIGN) { + isAssignment = true; if (isArray) { parser->token = lexerGetNextChar(parser->fd, parser->lineCount); if (!(parser->token.category == SIGN && @@ -224,6 +227,10 @@ enum SYNTAX_ERROR declVar(struct Parser *parser) { } } + if (isArray || isAssignment) { + parser->token = lexerGetNextChar(parser->fd, parser->lineCount); + } + return NO_ERROR; } From 7b27e22ab3515567a3dfd5868eb052a052b0c104 Mon Sep 17 00:00:00 2001 From: wilyJ80 Date: Wed, 11 Dec 2024 17:47:40 -0300 Subject: [PATCH 15/27] test: further tests, forgot \n --- test/parser_integration_tests.c | 25 +++++++++++++++++++------ test/parser_integration_tests.h | 2 ++ test/test.c | 2 ++ 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/test/parser_integration_tests.c b/test/parser_integration_tests.c index 67d3ae9..e3d74b2 100644 --- a/test/parser_integration_tests.c +++ b/test/parser_integration_tests.c @@ -7,6 +7,9 @@ // switch this on to output all syntax errors #define SHOW_ERRORS true +// Mock a file with a `const char*` and return an error. +// NOTE: A valid argument must have a newline in the end otherwise it doesn't +// work. enum SYNTAX_ERROR setupError(const char *mockData) { FILE *mockFile = fmemopen((void *)mockData, strlen(mockData), "r"); @@ -224,35 +227,45 @@ void declDefProcDefFollowedByCmdError() { assert(error == NO_GETINT_ID); } -// TODO: - // test for cmd error after valid def and decl_list_var void declDefProcDefFollowedByDeclListVarFollowedByCmdError() { - enum SYNTAX_ERROR error = setupError("def plutonio(int i) const int n getint 1"); + enum SYNTAX_ERROR error = + setupError("def plutonio(int i) const int n getint 1"); assert(error == NO_GETINT_ID); } // test for cmd error after valid def and multiple decl_list_var void declDefProcDefFollowedByMultipleDeclListVarFollowedByCmdError() { - enum SYNTAX_ERROR error = setupError("def plutonio(int i) const int n const int g getint 1"); + enum SYNTAX_ERROR error = + setupError("def plutonio(int i) const int n const int g getint 1"); assert(error == NO_GETINT_ID); } // multiple cmds void declDefProcDefFollowedByMultipleCmdError() { - enum SYNTAX_ERROR error = setupError("def plutonio(int i, int j) getint i getint 44"); + enum SYNTAX_ERROR error = + setupError("def plutonio(int i, int j) getint i getint 44"); assert(error == NO_GETINT_ID); } // more exhaustive tests could be made, but I have work to do // test for no endp error void declDefProcDefFollowedByABunchOfStuffButNotFinishingWithEndp() { - enum SYNTAX_ERROR error = setupError("def galibdenio(int i) const int n getint n prot"); + enum SYNTAX_ERROR error = + setupError("def galibdenio(int i) const int n getint n prot"); assert(error == NO_DEF_END_KEYWORD); } // a perfectly valid variable declaration-only program +void perfectlyValidVariableDeclarationOnlyProgram() { + enum SYNTAX_ERROR error = + setupError("const int a const int b char ch, chz\n"); + assert(error == NO_ERROR); +} // a perfectly valid function prototype declaration-only program // a perfectly valid function definition-only program + +// a perfectly valid program with variable list declaration, then prototype, +// then definition then variable list declaration then cmd then endp diff --git a/test/parser_integration_tests.h b/test/parser_integration_tests.h index 2d72a55..37ef21f 100644 --- a/test/parser_integration_tests.h +++ b/test/parser_integration_tests.h @@ -56,4 +56,6 @@ void declDefProcDefFollowedByMultipleDeclListVarFollowedByCmdError(); void declDefProcDefFollowedByMultipleCmdError(); void declDefProcDefFollowedByABunchOfStuffButNotFinishingWithEndp(); +void perfectlyValidVariableDeclarationOnlyProgram(); + #endif // !PARSER_INTEGRATION_TESTS_H diff --git a/test/test.c b/test/test.c index bb4eb87..15a67b5 100644 --- a/test/test.c +++ b/test/test.c @@ -72,6 +72,8 @@ int main(void) { declDefProcDefFollowedByCmdError(); declDefProcDefFollowedByDeclListVarFollowedByCmdError(); + perfectlyValidVariableDeclarationOnlyProgram(); + printf("--- Parser integration tests passed\n"); printf(GREEN "All tests OK\n" RESET); From da576119dff27926bc4f23debce326585f0b2018 Mon Sep 17 00:00:00 2001 From: wilyJ80 Date: Wed, 11 Dec 2024 18:11:12 -0300 Subject: [PATCH 16/27] fix: comma problem on function prototypes --- parser/parser.c | 12 ++++++------ test/parser_integration_tests.c | 5 +++++ test/parser_integration_tests.h | 1 + test/test.c | 1 + 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/parser/parser.c b/parser/parser.c index 918316e..d5bd5ad 100644 --- a/parser/parser.c +++ b/parser/parser.c @@ -483,13 +483,13 @@ enum SYNTAX_ERROR declProtParam(struct Parser *parser) { return INVALID_ARRAY_DIMENSION_DECLARATION; } } + } - if (parser->token.category == SIGN && parser->token.signCode == COMMA) { - parser->token = lexerGetNextChar(parser->fd, parser->lineCount); - enum SYNTAX_ERROR error = declProtParam(parser); - if (error != NO_ERROR) { - return error; - } + if (parser->token.category == SIGN && parser->token.signCode == COMMA) { + parser->token = lexerGetNextChar(parser->fd, parser->lineCount); + enum SYNTAX_ERROR error = declProtParam(parser); + if (error != NO_ERROR) { + return error; } } return NO_ERROR; diff --git a/test/parser_integration_tests.c b/test/parser_integration_tests.c index e3d74b2..87bf108 100644 --- a/test/parser_integration_tests.c +++ b/test/parser_integration_tests.c @@ -264,6 +264,11 @@ void perfectlyValidVariableDeclarationOnlyProgram() { } // a perfectly valid function prototype declaration-only program +void perfectlyValidPrototypeOnlyProgram() { + enum SYNTAX_ERROR error = + setupError("prot soma(int, int) prot reduce(int[])\n"); + assert(error == NO_ERROR); +} // a perfectly valid function definition-only program diff --git a/test/parser_integration_tests.h b/test/parser_integration_tests.h index 37ef21f..0b39bb3 100644 --- a/test/parser_integration_tests.h +++ b/test/parser_integration_tests.h @@ -57,5 +57,6 @@ void declDefProcDefFollowedByMultipleCmdError(); void declDefProcDefFollowedByABunchOfStuffButNotFinishingWithEndp(); void perfectlyValidVariableDeclarationOnlyProgram(); +void perfectlyValidPrototypeOnlyProgram(); #endif // !PARSER_INTEGRATION_TESTS_H diff --git a/test/test.c b/test/test.c index 15a67b5..c71504d 100644 --- a/test/test.c +++ b/test/test.c @@ -73,6 +73,7 @@ int main(void) { declDefProcDefFollowedByDeclListVarFollowedByCmdError(); perfectlyValidVariableDeclarationOnlyProgram(); + perfectlyValidPrototypeOnlyProgram(); printf("--- Parser integration tests passed\n"); From e4d31ef090e96eb9a8180f7aaa8d2e5ab05df705 Mon Sep 17 00:00:00 2001 From: wilyJ80 Date: Wed, 11 Dec 2024 18:18:37 -0300 Subject: [PATCH 17/27] test: definition-only program --- parser/parser.c | 3 ++- test/parser_integration_tests.c | 5 +++++ test/parser_integration_tests.h | 1 + test/test.c | 1 + 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/parser/parser.c b/parser/parser.c index d5bd5ad..0f2a1b5 100644 --- a/parser/parser.c +++ b/parser/parser.c @@ -291,7 +291,8 @@ enum SYNTAX_ERROR declDef(struct Parser *parser) { parser->token.signCode == PUTINT || parser->token.signCode == PUTREAL || parser->token.signCode == PUTCHAR || - parser->token.signCode == PUTSTR)))) { + parser->token.signCode == PUTSTR || + parser->token.signCode == ENDP)))) { return NO_DEF_VALID_TOKEN_AFTER_PAREN; } diff --git a/test/parser_integration_tests.c b/test/parser_integration_tests.c index 87bf108..a84fc41 100644 --- a/test/parser_integration_tests.c +++ b/test/parser_integration_tests.c @@ -271,6 +271,11 @@ void perfectlyValidPrototypeOnlyProgram() { } // a perfectly valid function definition-only program +void perfectlyValidFunctionDefinitionOnlyProgram() { + enum SYNTAX_ERROR error = + setupError("def init (int self) endp def main (int arg) endp\n"); + assert(error == NO_ERROR); +} // a perfectly valid program with variable list declaration, then prototype, // then definition then variable list declaration then cmd then endp diff --git a/test/parser_integration_tests.h b/test/parser_integration_tests.h index 0b39bb3..611551f 100644 --- a/test/parser_integration_tests.h +++ b/test/parser_integration_tests.h @@ -58,5 +58,6 @@ void declDefProcDefFollowedByABunchOfStuffButNotFinishingWithEndp(); void perfectlyValidVariableDeclarationOnlyProgram(); void perfectlyValidPrototypeOnlyProgram(); +void perfectlyValidFunctionDefinitionOnlyProgram(); #endif // !PARSER_INTEGRATION_TESTS_H diff --git a/test/test.c b/test/test.c index c71504d..fa5808d 100644 --- a/test/test.c +++ b/test/test.c @@ -74,6 +74,7 @@ int main(void) { perfectlyValidVariableDeclarationOnlyProgram(); perfectlyValidPrototypeOnlyProgram(); + perfectlyValidFunctionDefinitionOnlyProgram(); printf("--- Parser integration tests passed\n"); From da06a8b6e5b79de96e72a878c989ac397e7dd69f Mon Sep 17 00:00:00 2001 From: wilyJ80 Date: Wed, 11 Dec 2024 18:48:37 -0300 Subject: [PATCH 18/27] test: functions seem somewhat stable --- test/parser_integration_tests.c | 5 +++++ test/parser_integration_tests.h | 1 + test/test.c | 1 + 3 files changed, 7 insertions(+) diff --git a/test/parser_integration_tests.c b/test/parser_integration_tests.c index a84fc41..ce9838b 100644 --- a/test/parser_integration_tests.c +++ b/test/parser_integration_tests.c @@ -279,3 +279,8 @@ void perfectlyValidFunctionDefinitionOnlyProgram() { // a perfectly valid program with variable list declaration, then prototype, // then definition then variable list declaration then cmd then endp +void perfectlyValidProgramWithDeclListVarThenProtThenDefThenDeclListVarThenCmdThenEndp() { + enum SYNTAX_ERROR error = + setupError("int num prot soma(int, int) def soma(int a, int b) int teste = 5 getint teste endp\n"); + assert(error == NO_ERROR); +} diff --git a/test/parser_integration_tests.h b/test/parser_integration_tests.h index 611551f..8d16eec 100644 --- a/test/parser_integration_tests.h +++ b/test/parser_integration_tests.h @@ -59,5 +59,6 @@ void declDefProcDefFollowedByABunchOfStuffButNotFinishingWithEndp(); void perfectlyValidVariableDeclarationOnlyProgram(); void perfectlyValidPrototypeOnlyProgram(); void perfectlyValidFunctionDefinitionOnlyProgram(); +void perfectlyValidProgramWithDeclListVarThenProtThenDefThenDeclListVarThenCmdThenEndp(); #endif // !PARSER_INTEGRATION_TESTS_H diff --git a/test/test.c b/test/test.c index fa5808d..423b525 100644 --- a/test/test.c +++ b/test/test.c @@ -75,6 +75,7 @@ int main(void) { perfectlyValidVariableDeclarationOnlyProgram(); perfectlyValidPrototypeOnlyProgram(); perfectlyValidFunctionDefinitionOnlyProgram(); + perfectlyValidProgramWithDeclListVarThenProtThenDefThenDeclListVarThenCmdThenEndp(); printf("--- Parser integration tests passed\n"); From f2346549127d771cec8d5eca20af8ba95e79b1c7 Mon Sep 17 00:00:00 2001 From: wilyJ80 Date: Wed, 11 Dec 2024 19:07:26 -0300 Subject: [PATCH 19/27] test: further validation of function --- parser/parser.c | 7 +++++++ test/parser_integration_tests.c | 6 ++++++ test/parser_integration_tests.h | 1 + test/test.c | 1 + 4 files changed, 15 insertions(+) diff --git a/parser/parser.c b/parser/parser.c index 0f2a1b5..1f63fe9 100644 --- a/parser/parser.c +++ b/parser/parser.c @@ -326,6 +326,11 @@ enum SYNTAX_ERROR declDef(struct Parser *parser) { } } + // is endp + if (!(parser->token.category == RSV && parser->token.signCode == ENDP)) { + return NO_DEF_END_KEYWORD; + } + return NO_ERROR; } @@ -337,6 +342,8 @@ enum SYNTAX_ERROR cmd(struct Parser *parser) { } } + // advance + parser->token = lexerGetNextChar(parser->fd, parser->lineCount); return NO_ERROR; } diff --git a/test/parser_integration_tests.c b/test/parser_integration_tests.c index ce9838b..78001f3 100644 --- a/test/parser_integration_tests.c +++ b/test/parser_integration_tests.c @@ -284,3 +284,9 @@ void perfectlyValidProgramWithDeclListVarThenProtThenDefThenDeclListVarThenCmdTh setupError("int num prot soma(int, int) def soma(int a, int b) int teste = 5 getint teste endp\n"); assert(error == NO_ERROR); } + +void butEndpWasNotThere() { + enum SYNTAX_ERROR error = + setupError("int num prot soma(int, int) def soma(int a, int b) int teste = 5 getint teste\n"); + assert(error == NO_DEF_END_KEYWORD); +} diff --git a/test/parser_integration_tests.h b/test/parser_integration_tests.h index 8d16eec..2b36624 100644 --- a/test/parser_integration_tests.h +++ b/test/parser_integration_tests.h @@ -60,5 +60,6 @@ void perfectlyValidVariableDeclarationOnlyProgram(); void perfectlyValidPrototypeOnlyProgram(); void perfectlyValidFunctionDefinitionOnlyProgram(); void perfectlyValidProgramWithDeclListVarThenProtThenDefThenDeclListVarThenCmdThenEndp(); +void butEndpWasNotThere(); #endif // !PARSER_INTEGRATION_TESTS_H diff --git a/test/test.c b/test/test.c index 423b525..91ec16d 100644 --- a/test/test.c +++ b/test/test.c @@ -76,6 +76,7 @@ int main(void) { perfectlyValidPrototypeOnlyProgram(); perfectlyValidFunctionDefinitionOnlyProgram(); perfectlyValidProgramWithDeclListVarThenProtThenDefThenDeclListVarThenCmdThenEndp(); + butEndpWasNotThere(); printf("--- Parser integration tests passed\n"); From b345a4375d263bd8d05f12b910ad58e3ab78f522 Mon Sep 17 00:00:00 2001 From: wilyJ80 Date: Wed, 11 Dec 2024 19:22:09 -0300 Subject: [PATCH 20/27] test: basic cmds --- parser/parser.c | 23 +++++++++++++++++++++++ test/parser_integration_tests.c | 29 +++++++++++++++++++++++++++-- test/parser_integration_tests.h | 5 +++++ test/test.c | 5 +++++ 4 files changed, 60 insertions(+), 2 deletions(-) diff --git a/parser/parser.c b/parser/parser.c index 1f63fe9..d98a3f8 100644 --- a/parser/parser.c +++ b/parser/parser.c @@ -342,6 +342,29 @@ enum SYNTAX_ERROR cmd(struct Parser *parser) { } } + if (parser->token.signCode == GETREAL) { + parser->token = lexerGetNextChar(parser->fd, parser->lineCount); + if (!(parser->token.category == ID)) { + return NO_GETREAL_ID; + } + } + + if (parser->token.signCode == GETCHAR) { + parser->token = lexerGetNextChar(parser->fd, parser->lineCount); + if (!(parser->token.category == ID)) { + return NO_GETCHAR_ID; + } + } + + if (parser->token.signCode == GETSTR) { + parser->token = lexerGetNextChar(parser->fd, parser->lineCount); + if (!(parser->token.category == ID)) { + return NO_GETSTR_ID; + } + } + + // getout: nothing needed? + // advance parser->token = lexerGetNextChar(parser->fd, parser->lineCount); return NO_ERROR; diff --git a/test/parser_integration_tests.c b/test/parser_integration_tests.c index 78001f3..a3b85e9 100644 --- a/test/parser_integration_tests.c +++ b/test/parser_integration_tests.c @@ -281,12 +281,37 @@ void perfectlyValidFunctionDefinitionOnlyProgram() { // then definition then variable list declaration then cmd then endp void perfectlyValidProgramWithDeclListVarThenProtThenDefThenDeclListVarThenCmdThenEndp() { enum SYNTAX_ERROR error = - setupError("int num prot soma(int, int) def soma(int a, int b) int teste = 5 getint teste endp\n"); + setupError("int num prot soma(int, int) def soma(int a, int b) int teste " + "= 5 getint teste endp\n"); assert(error == NO_ERROR); } void butEndpWasNotThere() { enum SYNTAX_ERROR error = - setupError("int num prot soma(int, int) def soma(int a, int b) int teste = 5 getint teste\n"); + setupError("int num prot soma(int, int) def soma(int a, int b) int teste " + "= 5 getint teste\n"); assert(error == NO_DEF_END_KEYWORD); } + +// from here onwards, integration tests will be a challenge. +// many routines depend on each other. + +void getoutWorks() { + enum SYNTAX_ERROR error = setupError("def calcio(char c) getout\n"); + assert(error == NO_DEF_END_KEYWORD); +} + +void getrealError() { + enum SYNTAX_ERROR error = setupError("def magnesio(char c) getreal 5\n"); + assert(error == NO_GETREAL_ID); +} + +void getcharError() { + enum SYNTAX_ERROR error = setupError("def manganes(char c) getchar 5\n"); + assert(error == NO_GETCHAR_ID); +} + +void getstrError() { + enum SYNTAX_ERROR error = setupError("def titanio(char c) getstr 5\n"); + assert(error == NO_GETSTR_ID); +} diff --git a/test/parser_integration_tests.h b/test/parser_integration_tests.h index 2b36624..d651b5f 100644 --- a/test/parser_integration_tests.h +++ b/test/parser_integration_tests.h @@ -62,4 +62,9 @@ void perfectlyValidFunctionDefinitionOnlyProgram(); void perfectlyValidProgramWithDeclListVarThenProtThenDefThenDeclListVarThenCmdThenEndp(); void butEndpWasNotThere(); +void getoutWorks(); +void getrealError(); +void getcharError(); +void getstrError(); + #endif // !PARSER_INTEGRATION_TESTS_H diff --git a/test/test.c b/test/test.c index 91ec16d..afa52da 100644 --- a/test/test.c +++ b/test/test.c @@ -78,6 +78,11 @@ int main(void) { perfectlyValidProgramWithDeclListVarThenProtThenDefThenDeclListVarThenCmdThenEndp(); butEndpWasNotThere(); + getoutWorks(); + getrealError(); + getcharError(); + getstrError(); + printf("--- Parser integration tests passed\n"); printf(GREEN "All tests OK\n" RESET); From 801bca4ff35e1ccbe990f0972e62c5d88500d3f6 Mon Sep 17 00:00:00 2001 From: wilyJ80 Date: Wed, 11 Dec 2024 21:16:24 -0300 Subject: [PATCH 21/27] test: simple test for put functions --- parser/parser.c | 28 ++++++++++++++++++++++++++++ test/parser_integration_tests.c | 20 ++++++++++++++++++++ test/parser_integration_tests.h | 4 ++++ test/test.c | 4 ++++ 4 files changed, 56 insertions(+) diff --git a/parser/parser.c b/parser/parser.c index d98a3f8..3d9a190 100644 --- a/parser/parser.c +++ b/parser/parser.c @@ -362,7 +362,35 @@ enum SYNTAX_ERROR cmd(struct Parser *parser) { return NO_GETSTR_ID; } } + + if (parser->token.signCode == PUTINT) { + parser->token = lexerGetNextChar(parser->fd, parser->lineCount); + if (!(parser->token.category == ID || parser->token.category == INTCON)) { + return INVALID_PUTINT_ELEMENT; + } + } + if (parser->token.signCode == PUTREAL) { + parser->token = lexerGetNextChar(parser->fd, parser->lineCount); + if (!(parser->token.category == ID || parser->token.category == REALCON)) { + return INVALID_PUTREAL_ELEMENT; + } + } + + if (parser->token.signCode == PUTCHAR) { + parser->token = lexerGetNextChar(parser->fd, parser->lineCount); + if (!(parser->token.category == ID || parser->token.category == CHARCON)) { + return INVALID_PUTCHAR_ELEMENT; + } + } + + if (parser->token.signCode == PUTSTR) { + parser->token = lexerGetNextChar(parser->fd, parser->lineCount); + if (!(parser->token.category == ID || parser->token.category == STRINGCON)) { + return INVALID_PUTSTR_ELEMENT; + } + } + // getout: nothing needed? // advance diff --git a/test/parser_integration_tests.c b/test/parser_integration_tests.c index a3b85e9..66dd1bb 100644 --- a/test/parser_integration_tests.c +++ b/test/parser_integration_tests.c @@ -315,3 +315,23 @@ void getstrError() { enum SYNTAX_ERROR error = setupError("def titanio(char c) getstr 5\n"); assert(error == NO_GETSTR_ID); } + +void putintError() { + enum SYNTAX_ERROR error = setupError("def titanio(char c) putint 2.2\n"); + assert(error == INVALID_PUTINT_ELEMENT); +} + +void putrealError() { + enum SYNTAX_ERROR error = setupError("def titanio(char c) putreal 'a'\n"); + assert(error == INVALID_PUTREAL_ELEMENT); +} + +void putcharError() { + enum SYNTAX_ERROR error = setupError("def titanio(char c) putchar 8\n"); + assert(error == INVALID_PUTCHAR_ELEMENT); +} + +void putstrError() { + enum SYNTAX_ERROR error = setupError("def titanio(char c) putstr 8\n"); + assert(error == INVALID_PUTSTR_ELEMENT); +} diff --git a/test/parser_integration_tests.h b/test/parser_integration_tests.h index d651b5f..297c1f0 100644 --- a/test/parser_integration_tests.h +++ b/test/parser_integration_tests.h @@ -66,5 +66,9 @@ void getoutWorks(); void getrealError(); void getcharError(); void getstrError(); +void putintError(); +void putrealError(); +void putcharError(); +void putstrError(); #endif // !PARSER_INTEGRATION_TESTS_H diff --git a/test/test.c b/test/test.c index afa52da..eb44293 100644 --- a/test/test.c +++ b/test/test.c @@ -82,6 +82,10 @@ int main(void) { getrealError(); getcharError(); getstrError(); + putintError(); + putrealError(); + putcharError(); + putstrError(); printf("--- Parser integration tests passed\n"); From 718de715626c8857035923d1f621befb5b7c8afa Mon Sep 17 00:00:00 2001 From: wilyJ80 Date: Wed, 11 Dec 2024 21:34:45 -0300 Subject: [PATCH 22/27] test: start do cmd tests --- parser/parser.c | 24 ++++++++++++++++++++---- parser/parser.h | 2 ++ test/parser_integration_tests.c | 10 ++++++++++ test/parser_integration_tests.h | 2 ++ test/test.c | 2 ++ 5 files changed, 36 insertions(+), 4 deletions(-) diff --git a/parser/parser.c b/parser/parser.c index 3d9a190..7895046 100644 --- a/parser/parser.c +++ b/parser/parser.c @@ -291,8 +291,8 @@ enum SYNTAX_ERROR declDef(struct Parser *parser) { parser->token.signCode == PUTINT || parser->token.signCode == PUTREAL || parser->token.signCode == PUTCHAR || - parser->token.signCode == PUTSTR || - parser->token.signCode == ENDP)))) { + parser->token.signCode == PUTSTR || parser->token.signCode == ENDP || + parser->token.signCode == DO)))) { return NO_DEF_VALID_TOKEN_AFTER_PAREN; } @@ -369,7 +369,7 @@ enum SYNTAX_ERROR cmd(struct Parser *parser) { return INVALID_PUTINT_ELEMENT; } } - + if (parser->token.signCode == PUTREAL) { parser->token = lexerGetNextChar(parser->fd, parser->lineCount); if (!(parser->token.category == ID || parser->token.category == REALCON)) { @@ -386,11 +386,19 @@ enum SYNTAX_ERROR cmd(struct Parser *parser) { if (parser->token.signCode == PUTSTR) { parser->token = lexerGetNextChar(parser->fd, parser->lineCount); - if (!(parser->token.category == ID || parser->token.category == STRINGCON)) { + if (!(parser->token.category == ID || + parser->token.category == STRINGCON)) { return INVALID_PUTSTR_ELEMENT; } } + if (parser->token.signCode == DO) { + enum SYNTAX_ERROR error = cmdDo(parser); + if (error != NO_ERROR) { + return error; + } + } + // getout: nothing needed? // advance @@ -398,6 +406,14 @@ enum SYNTAX_ERROR cmd(struct Parser *parser) { return NO_ERROR; } +enum SYNTAX_ERROR cmdDo(struct Parser *parser) { + parser->token = lexerGetNextChar(parser->fd, parser->lineCount); + if (!(parser->token.category == ID)) { + return INVALID_FUNCTION_CALL_ID; + } + return NO_ERROR; +} + enum SYNTAX_ERROR declDefParam(struct Parser *parser) { // while it's a param, delimited by comma do { diff --git a/parser/parser.h b/parser/parser.h index a8b356e..4fc3892 100644 --- a/parser/parser.h +++ b/parser/parser.h @@ -41,4 +41,6 @@ enum SYNTAX_ERROR declDefParamArray(struct Parser *parser); enum SYNTAX_ERROR cmd(struct Parser *parser); enum SYNTAX_ERROR getint(struct Parser *parser); +enum SYNTAX_ERROR cmdDo(struct Parser *parser); + #endif diff --git a/test/parser_integration_tests.c b/test/parser_integration_tests.c index 66dd1bb..3a4d18b 100644 --- a/test/parser_integration_tests.c +++ b/test/parser_integration_tests.c @@ -335,3 +335,13 @@ void putstrError() { enum SYNTAX_ERROR error = setupError("def titanio(char c) putstr 8\n"); assert(error == INVALID_PUTSTR_ELEMENT); } + +// do no idproc error +void doButNotIdproc() { + enum SYNTAX_ERROR error = setupError("def adamantio(int i) do 8\n"); + assert(error == INVALID_FUNCTION_CALL_ID); +} + +// do idproc paren error + +// do idproc expr (start tests for expr in context of idproc) diff --git a/test/parser_integration_tests.h b/test/parser_integration_tests.h index 297c1f0..45dcd06 100644 --- a/test/parser_integration_tests.h +++ b/test/parser_integration_tests.h @@ -71,4 +71,6 @@ void putrealError(); void putcharError(); void putstrError(); +void doButNotIdproc(); + #endif // !PARSER_INTEGRATION_TESTS_H diff --git a/test/test.c b/test/test.c index eb44293..e5384bd 100644 --- a/test/test.c +++ b/test/test.c @@ -87,6 +87,8 @@ int main(void) { putcharError(); putstrError(); + doButNotIdproc(); + printf("--- Parser integration tests passed\n"); printf(GREEN "All tests OK\n" RESET); From a41446e90c09215e1c03b6a1e735f7b4aed79fe8 Mon Sep 17 00:00:00 2001 From: wilyJ80 Date: Wed, 11 Dec 2024 21:41:39 -0300 Subject: [PATCH 23/27] test: continue do, we are about to go to expr, get ready --- parser/parser.c | 7 +++++++ test/parser_integration_tests.c | 4 ++++ test/parser_integration_tests.h | 1 + test/test.c | 1 + 4 files changed, 13 insertions(+) diff --git a/parser/parser.c b/parser/parser.c index 7895046..bda2b44 100644 --- a/parser/parser.c +++ b/parser/parser.c @@ -411,6 +411,13 @@ enum SYNTAX_ERROR cmdDo(struct Parser *parser) { if (!(parser->token.category == ID)) { return INVALID_FUNCTION_CALL_ID; } + + // is id, ok... then it should open a paren + parser->token = lexerGetNextChar(parser->fd, parser->lineCount); + if (!(parser->token.category == SIGN && parser->token.signCode == OPEN_PAR)) { + return INVALID_FUNCTION_CALL_PAREN_OPEN; + } + return NO_ERROR; } diff --git a/test/parser_integration_tests.c b/test/parser_integration_tests.c index 3a4d18b..b0a7fa8 100644 --- a/test/parser_integration_tests.c +++ b/test/parser_integration_tests.c @@ -343,5 +343,9 @@ void doButNotIdproc() { } // do idproc paren error +void doButNoParenOpen() { + enum SYNTAX_ERROR error = setupError("def tritio(int i) do tritio)\n"); + assert(error == INVALID_FUNCTION_CALL_PAREN_OPEN); +} // do idproc expr (start tests for expr in context of idproc) diff --git a/test/parser_integration_tests.h b/test/parser_integration_tests.h index 45dcd06..398a69b 100644 --- a/test/parser_integration_tests.h +++ b/test/parser_integration_tests.h @@ -72,5 +72,6 @@ void putcharError(); void putstrError(); void doButNotIdproc(); +void doButNoParenOpen(); #endif // !PARSER_INTEGRATION_TESTS_H diff --git a/test/test.c b/test/test.c index e5384bd..46b0218 100644 --- a/test/test.c +++ b/test/test.c @@ -88,6 +88,7 @@ int main(void) { putstrError(); doButNotIdproc(); + doButNoParenOpen(); printf("--- Parser integration tests passed\n"); From de76dbf08732d6b215bec7c3a12a9a49e944e35f Mon Sep 17 00:00:00 2001 From: wilyJ80 Date: Wed, 11 Dec 2024 22:35:47 -0300 Subject: [PATCH 24/27] test: starting atrib --- parser/parser.c | 36 ++++++++++++++++++++++++++++++++- parser/parser.h | 1 + parser/syntax_error.c | 5 ++++- parser/syntax_error.h | 2 ++ test/parser_integration_tests.c | 17 ++++++++++++++++ test/parser_integration_tests.h | 4 ++++ test/test.c | 3 +++ 7 files changed, 66 insertions(+), 2 deletions(-) diff --git a/parser/parser.c b/parser/parser.c index bda2b44..f25f7d5 100644 --- a/parser/parser.c +++ b/parser/parser.c @@ -20,6 +20,7 @@ enum SYNTAX_ERROR op_rel(struct Parser *parser) { } enum SYNTAX_ERROR fator(struct Parser *parser) { + // this makes no damn sense: keeping it for unit tests, I guess if (!(parser->token.category == ID || parser->token.category == INTCON || parser->token.category == REALCON || parser->token.category == CHARCON || @@ -340,6 +341,7 @@ enum SYNTAX_ERROR cmd(struct Parser *parser) { if (!(parser->token.category == ID)) { return NO_GETINT_ID; } + parser->token = lexerGetNextChar(parser->fd, parser->lineCount); } if (parser->token.signCode == GETREAL) { @@ -347,6 +349,7 @@ enum SYNTAX_ERROR cmd(struct Parser *parser) { if (!(parser->token.category == ID)) { return NO_GETREAL_ID; } + parser->token = lexerGetNextChar(parser->fd, parser->lineCount); } if (parser->token.signCode == GETCHAR) { @@ -354,6 +357,7 @@ enum SYNTAX_ERROR cmd(struct Parser *parser) { if (!(parser->token.category == ID)) { return NO_GETCHAR_ID; } + parser->token = lexerGetNextChar(parser->fd, parser->lineCount); } if (parser->token.signCode == GETSTR) { @@ -361,6 +365,7 @@ enum SYNTAX_ERROR cmd(struct Parser *parser) { if (!(parser->token.category == ID)) { return NO_GETSTR_ID; } + parser->token = lexerGetNextChar(parser->fd, parser->lineCount); } if (parser->token.signCode == PUTINT) { @@ -368,6 +373,7 @@ enum SYNTAX_ERROR cmd(struct Parser *parser) { if (!(parser->token.category == ID || parser->token.category == INTCON)) { return INVALID_PUTINT_ELEMENT; } + parser->token = lexerGetNextChar(parser->fd, parser->lineCount); } if (parser->token.signCode == PUTREAL) { @@ -375,6 +381,7 @@ enum SYNTAX_ERROR cmd(struct Parser *parser) { if (!(parser->token.category == ID || parser->token.category == REALCON)) { return INVALID_PUTREAL_ELEMENT; } + parser->token = lexerGetNextChar(parser->fd, parser->lineCount); } if (parser->token.signCode == PUTCHAR) { @@ -382,6 +389,7 @@ enum SYNTAX_ERROR cmd(struct Parser *parser) { if (!(parser->token.category == ID || parser->token.category == CHARCON)) { return INVALID_PUTCHAR_ELEMENT; } + parser->token = lexerGetNextChar(parser->fd, parser->lineCount); } if (parser->token.signCode == PUTSTR) { @@ -390,6 +398,7 @@ enum SYNTAX_ERROR cmd(struct Parser *parser) { parser->token.category == STRINGCON)) { return INVALID_PUTSTR_ELEMENT; } + parser->token = lexerGetNextChar(parser->fd, parser->lineCount); } if (parser->token.signCode == DO) { @@ -399,10 +408,24 @@ enum SYNTAX_ERROR cmd(struct Parser *parser) { } } + if (parser->token.category == ID) { + enum SYNTAX_ERROR error = cmdAtrib(parser); + if (error != NO_ERROR) { + return error; + } + } + // getout: nothing needed? - // advance + return NO_ERROR; +} + +enum SYNTAX_ERROR cmdAtrib(struct Parser *parser) { parser->token = lexerGetNextChar(parser->fd, parser->lineCount); + if (!(parser->token.category == SIGN && (parser->token.signCode == OPEN_BRACK || parser->token.signCode == ASSIGN))) { + return NO_ATRIB_VALID_TOKEN_AFTER_ID; + } + return NO_ERROR; } @@ -418,6 +441,17 @@ enum SYNTAX_ERROR cmdDo(struct Parser *parser) { return INVALID_FUNCTION_CALL_PAREN_OPEN; } + // if is valid fator starter, go to fator + if (parser->token.category == ID || parser->token.category == INTCON || + parser->token.category == REALCON || parser->token.category == CHARCON || + (parser->token.category == SIGN && parser->token.signCode == OPEN_PAR) || + (parser->token.category == SIGN && parser->token.signCode == NEGATION)) { + enum SYNTAX_ERROR error = fator(parser); + if (error != NO_ERROR) { + return error; + } + } + return NO_ERROR; } diff --git a/parser/parser.h b/parser/parser.h index 4fc3892..494130b 100644 --- a/parser/parser.h +++ b/parser/parser.h @@ -42,5 +42,6 @@ enum SYNTAX_ERROR cmd(struct Parser *parser); enum SYNTAX_ERROR getint(struct Parser *parser); enum SYNTAX_ERROR cmdDo(struct Parser *parser); +enum SYNTAX_ERROR cmdAtrib(struct Parser *parser); #endif diff --git a/parser/syntax_error.c b/parser/syntax_error.c index 97520ff..4353e3e 100644 --- a/parser/syntax_error.c +++ b/parser/syntax_error.c @@ -2,7 +2,7 @@ #include #include -#define ERROR_QTY 88 +#define ERROR_QTY 90 // ANSI escape codes #define RESET "\033[0m" @@ -129,6 +129,8 @@ void printSyntaxError(enum SYNTAX_ERROR error, int *lineCount) { {NO_ATRIB_ID, "No ID detected for expression assign"}, {NO_ATRIB_ASSIGN, "No assign symbol for expression assign"}, {NO_ATRIB_EXPR, "No expression assigned to expression assign"}, + {NO_ATRIB_VALID_TOKEN_AFTER_ID, + "No valid token after identifier for assignment"}, // expr {NO_EXPR_EXPR_SIMP, "No simple expression for expression"}, {NO_EXPR_EXPR_SIMP_AFTER_OP_REL, "No simple expression after operation"}, @@ -147,6 +149,7 @@ void printSyntaxError(enum SYNTAX_ERROR error, int *lineCount) { "No factor detected after valid sign in term"}, // fator {NO_FACTOR_VALID_START_SYMBOL, "No factor valid start symbol"}, + {NO_FACTOR_VALID_SYMBOL_AFTER_ID, "No factor valid symbol after id"}, {INVALID_FACTOR_ARRAY_BRACKET_OPEN, "No factor array bracket opening"}, {INVALID_FACTOR_ARRAY_BRACKET_CLOSE, "No factor array bracket closing"}, {INVALID_FACTOR_EXPR_PAREN_OPEN, "No factor expression paren opening"}, diff --git a/parser/syntax_error.h b/parser/syntax_error.h index ac83c21..90de56c 100644 --- a/parser/syntax_error.h +++ b/parser/syntax_error.h @@ -95,6 +95,7 @@ enum SYNTAX_ERROR { NO_ATRIB_ID, NO_ATRIB_ASSIGN, NO_ATRIB_EXPR, + NO_ATRIB_VALID_TOKEN_AFTER_ID, // expr NO_EXPR_EXPR_SIMP, NO_EXPR_EXPR_SIMP_AFTER_OP_REL, @@ -109,6 +110,7 @@ enum SYNTAX_ERROR { NO_TERM_FACTOR_AFTER_FACTOR_VALID_SIGN, // fator NO_FACTOR_VALID_START_SYMBOL, + NO_FACTOR_VALID_SYMBOL_AFTER_ID, INVALID_FACTOR_ARRAY_BRACKET_OPEN, INVALID_FACTOR_ARRAY_BRACKET_CLOSE, INVALID_FACTOR_EXPR_PAREN_OPEN, diff --git a/test/parser_integration_tests.c b/test/parser_integration_tests.c index b0a7fa8..ad3eb67 100644 --- a/test/parser_integration_tests.c +++ b/test/parser_integration_tests.c @@ -349,3 +349,20 @@ void doButNoParenOpen() { } // do idproc expr (start tests for expr in context of idproc) + +// WRONG: IGNORE +// do idproc expr expr_simp termo fator no valid after id (id, intcon, realcon, charcon, paren open, bang) +/*void doIdprocExprExprSimpTermoFatorNoValidTokenAfterId() {*/ +/* enum SYNTAX_ERROR error = setupError("def tungstenio(int i) do tritio(i 8)\n");*/ +/* assert(error == NO_FACTOR_VALID_SYMBOL_AFTER_ID);*/ +/*}*/ + +// atrib no valid after id + +void atribNoValidAfterId() { + enum SYNTAX_ERROR error = setupError("def potassio(int i) i 8"); + assert(error == NO_ATRIB_VALID_TOKEN_AFTER_ID); +} + +// do idproc expr expr_simp termo fator paren expr expr_simp termo fator unclosed expr + diff --git a/test/parser_integration_tests.h b/test/parser_integration_tests.h index 398a69b..eb2c27a 100644 --- a/test/parser_integration_tests.h +++ b/test/parser_integration_tests.h @@ -74,4 +74,8 @@ void putstrError(); void doButNotIdproc(); void doButNoParenOpen(); +void atribNoValidAfterId(); + +// void doIdprocExprExprSimpTermoFatorNoValidTokenAfterId(); + #endif // !PARSER_INTEGRATION_TESTS_H diff --git a/test/test.c b/test/test.c index 46b0218..4ac58c6 100644 --- a/test/test.c +++ b/test/test.c @@ -89,6 +89,9 @@ int main(void) { doButNotIdproc(); doButNoParenOpen(); + // doIdprocExprExprSimpTermoFatorNoValidTokenAfterId(); + + atribNoValidAfterId(); printf("--- Parser integration tests passed\n"); From 08e54a587c705a57940d7d2acd7b918c4161e21e Mon Sep 17 00:00:00 2001 From: wilyJ80 Date: Wed, 11 Dec 2024 23:13:17 -0300 Subject: [PATCH 25/27] test: another atrib test --- parser/parser.c | 7 +++++++ parser/syntax_error.h | 2 +- test/parser_integration_tests.c | 16 ++++++---------- test/parser_integration_tests.h | 1 + test/test.c | 1 + 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/parser/parser.c b/parser/parser.c index f25f7d5..72a1c16 100644 --- a/parser/parser.c +++ b/parser/parser.c @@ -426,6 +426,13 @@ enum SYNTAX_ERROR cmdAtrib(struct Parser *parser) { return NO_ATRIB_VALID_TOKEN_AFTER_ID; } + if (parser->token.category == SIGN && parser->token.signCode == ASSIGN) { + enum SYNTAX_ERROR error = fator(parser); + if (error != NO_ERROR) { + return error; + } + } + return NO_ERROR; } diff --git a/parser/syntax_error.h b/parser/syntax_error.h index 90de56c..aca410b 100644 --- a/parser/syntax_error.h +++ b/parser/syntax_error.h @@ -124,7 +124,7 @@ void printSyntaxError(enum SYNTAX_ERROR error, int *lineCount); struct ErrorMessage { enum SYNTAX_ERROR error; - const char* message; + const char *message; }; #endif // !SYNTAX_ERROR_H diff --git a/test/parser_integration_tests.c b/test/parser_integration_tests.c index ad3eb67..24819a1 100644 --- a/test/parser_integration_tests.c +++ b/test/parser_integration_tests.c @@ -348,14 +348,7 @@ void doButNoParenOpen() { assert(error == INVALID_FUNCTION_CALL_PAREN_OPEN); } -// do idproc expr (start tests for expr in context of idproc) - -// WRONG: IGNORE -// do idproc expr expr_simp termo fator no valid after id (id, intcon, realcon, charcon, paren open, bang) -/*void doIdprocExprExprSimpTermoFatorNoValidTokenAfterId() {*/ -/* enum SYNTAX_ERROR error = setupError("def tungstenio(int i) do tritio(i 8)\n");*/ -/* assert(error == NO_FACTOR_VALID_SYMBOL_AFTER_ID);*/ -/*}*/ +// tests with atrib might help developing expr... i hope ;-; // atrib no valid after id @@ -364,5 +357,8 @@ void atribNoValidAfterId() { assert(error == NO_ATRIB_VALID_TOKEN_AFTER_ID); } -// do idproc expr expr_simp termo fator paren expr expr_simp termo fator unclosed expr - +// atrib with assignment to a bad expr: a stringcon +void atribAssignedToABadExprAStringcon() { + enum SYNTAX_ERROR error = setupError("def potassio(int i) i = $"); + assert(error == NO_FACTOR_VALID_START_SYMBOL); +} diff --git a/test/parser_integration_tests.h b/test/parser_integration_tests.h index eb2c27a..00e25e8 100644 --- a/test/parser_integration_tests.h +++ b/test/parser_integration_tests.h @@ -75,6 +75,7 @@ void doButNotIdproc(); void doButNoParenOpen(); void atribNoValidAfterId(); +void atribAssignedToABadExprAStringcon(); // void doIdprocExprExprSimpTermoFatorNoValidTokenAfterId(); diff --git a/test/test.c b/test/test.c index 4ac58c6..8761f8c 100644 --- a/test/test.c +++ b/test/test.c @@ -92,6 +92,7 @@ int main(void) { // doIdprocExprExprSimpTermoFatorNoValidTokenAfterId(); atribNoValidAfterId(); + atribAssignedToABadExprAStringcon(); printf("--- Parser integration tests passed\n"); From caf56fdd4b2c260fc488ebd29098a66b8fb2d139 Mon Sep 17 00:00:00 2001 From: wilyJ80 Date: Thu, 12 Dec 2024 02:49:57 -0300 Subject: [PATCH 26/27] might be better to do do first --- parser/parser.c | 14 +++++++++++++- parser/syntax_error.c | 3 ++- parser/syntax_error.h | 1 + test/parser_integration_tests.c | 8 ++++++++ test/parser_integration_tests.h | 1 + test/test.c | 1 + 6 files changed, 26 insertions(+), 2 deletions(-) diff --git a/parser/parser.c b/parser/parser.c index 72a1c16..2d2054e 100644 --- a/parser/parser.c +++ b/parser/parser.c @@ -422,7 +422,9 @@ enum SYNTAX_ERROR cmd(struct Parser *parser) { enum SYNTAX_ERROR cmdAtrib(struct Parser *parser) { parser->token = lexerGetNextChar(parser->fd, parser->lineCount); - if (!(parser->token.category == SIGN && (parser->token.signCode == OPEN_BRACK || parser->token.signCode == ASSIGN))) { + if (!(parser->token.category == SIGN && + (parser->token.signCode == OPEN_BRACK || + parser->token.signCode == ASSIGN))) { return NO_ATRIB_VALID_TOKEN_AFTER_ID; } @@ -433,6 +435,16 @@ enum SYNTAX_ERROR cmdAtrib(struct Parser *parser) { } } + // arrayAtrib + while (parser->token.category == SIGN && + parser->token.signCode == OPEN_BRACK) { + parser->token = lexerGetNextChar(parser->fd, parser->lineCount); + enum SYNTAX_ERROR error = expr(parser); + if (error != NO_ERROR) { + return error; + } + } + return NO_ERROR; } diff --git a/parser/syntax_error.c b/parser/syntax_error.c index 4353e3e..02a85d7 100644 --- a/parser/syntax_error.c +++ b/parser/syntax_error.c @@ -2,7 +2,7 @@ #include #include -#define ERROR_QTY 90 +#define ERROR_QTY 91 // ANSI escape codes #define RESET "\033[0m" @@ -131,6 +131,7 @@ void printSyntaxError(enum SYNTAX_ERROR error, int *lineCount) { {NO_ATRIB_EXPR, "No expression assigned to expression assign"}, {NO_ATRIB_VALID_TOKEN_AFTER_ID, "No valid token after identifier for assignment"}, + {NO_ATRIB_BRACKET_CLOSE, "Expected bracket closing at array assignment"}, // expr {NO_EXPR_EXPR_SIMP, "No simple expression for expression"}, {NO_EXPR_EXPR_SIMP_AFTER_OP_REL, "No simple expression after operation"}, diff --git a/parser/syntax_error.h b/parser/syntax_error.h index aca410b..782bd58 100644 --- a/parser/syntax_error.h +++ b/parser/syntax_error.h @@ -96,6 +96,7 @@ enum SYNTAX_ERROR { NO_ATRIB_ASSIGN, NO_ATRIB_EXPR, NO_ATRIB_VALID_TOKEN_AFTER_ID, + NO_ATRIB_BRACKET_CLOSE, // expr NO_EXPR_EXPR_SIMP, NO_EXPR_EXPR_SIMP_AFTER_OP_REL, diff --git a/test/parser_integration_tests.c b/test/parser_integration_tests.c index 24819a1..de4d9d4 100644 --- a/test/parser_integration_tests.c +++ b/test/parser_integration_tests.c @@ -362,3 +362,11 @@ void atribAssignedToABadExprAStringcon() { enum SYNTAX_ERROR error = setupError("def potassio(int i) i = $"); assert(error == NO_FACTOR_VALID_START_SYMBOL); } + +// TODO: +// +// atrib with bad unclosed paren +/*void atribBadClosedParen() {*/ +/* enum SYNTAX_ERROR error = setupError("def oxigenio(int i) id[8[");*/ +/* assert(error == NO_ATRIB_BRACKET_CLOSE);*/ +/*}*/ diff --git a/test/parser_integration_tests.h b/test/parser_integration_tests.h index 00e25e8..e55aada 100644 --- a/test/parser_integration_tests.h +++ b/test/parser_integration_tests.h @@ -76,6 +76,7 @@ void doButNoParenOpen(); void atribNoValidAfterId(); void atribAssignedToABadExprAStringcon(); +void atribBadClosedParen(); // void doIdprocExprExprSimpTermoFatorNoValidTokenAfterId(); diff --git a/test/test.c b/test/test.c index 8761f8c..2ff515d 100644 --- a/test/test.c +++ b/test/test.c @@ -93,6 +93,7 @@ int main(void) { atribNoValidAfterId(); atribAssignedToABadExprAStringcon(); + // atribBadClosedParen(); printf("--- Parser integration tests passed\n"); From fbc4fbfc856c71a37282bc86f6cdf23c9d450864 Mon Sep 17 00:00:00 2001 From: wilyJ80 Date: Thu, 12 Dec 2024 03:12:48 -0300 Subject: [PATCH 27/27] can i even do this --- parser/parser.c | 18 ++++++++++++------ test/parser_integration_tests.c | 7 +++++++ test/parser_integration_tests.h | 2 ++ test/test.c | 2 +- 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/parser/parser.c b/parser/parser.c index 2d2054e..d6d67a1 100644 --- a/parser/parser.c +++ b/parser/parser.c @@ -85,11 +85,6 @@ enum SYNTAX_ERROR arrayFator(struct Parser *parser) { return NO_ERROR; } -enum SYNTAX_ERROR expr(struct Parser *parser) { - // TODO: - return NO_ERROR; -} - /** * prog accepts repetitions of declarations of variables (decl_list_var), or * procedures (decl_list_proc). @@ -465,12 +460,23 @@ enum SYNTAX_ERROR cmdDo(struct Parser *parser) { parser->token.category == REALCON || parser->token.category == CHARCON || (parser->token.category == SIGN && parser->token.signCode == OPEN_PAR) || (parser->token.category == SIGN && parser->token.signCode == NEGATION)) { - enum SYNTAX_ERROR error = fator(parser); + // goes from expr down to fator + enum SYNTAX_ERROR error = expr(parser); if (error != NO_ERROR) { return error; } } + parser->token = lexerGetNextChar(parser->fd, parser->lineCount); + if (!(parser->token.category == SIGN && parser->token.signCode == CLOSE_PAR)) { + return INVALID_FUNCTION_CALL_PAREN_CLOSE; + } + + return NO_ERROR; +} + +enum SYNTAX_ERROR expr(struct Parser *parser) { + // TODO: return NO_ERROR; } diff --git a/test/parser_integration_tests.c b/test/parser_integration_tests.c index de4d9d4..99e25c4 100644 --- a/test/parser_integration_tests.c +++ b/test/parser_integration_tests.c @@ -363,6 +363,12 @@ void atribAssignedToABadExprAStringcon() { assert(error == NO_FACTOR_VALID_START_SYMBOL); } +void doButNoClosingParen() { + enum SYNTAX_ERROR error = setupError("def nitrogenio(int i) do nitrogenio(8("); + assert(error == INVALID_FUNCTION_CALL_PAREN_CLOSE); +} + + // TODO: // // atrib with bad unclosed paren @@ -370,3 +376,4 @@ void atribAssignedToABadExprAStringcon() { /* enum SYNTAX_ERROR error = setupError("def oxigenio(int i) id[8[");*/ /* assert(error == NO_ATRIB_BRACKET_CLOSE);*/ /*}*/ + diff --git a/test/parser_integration_tests.h b/test/parser_integration_tests.h index e55aada..1b65a06 100644 --- a/test/parser_integration_tests.h +++ b/test/parser_integration_tests.h @@ -73,6 +73,8 @@ void putstrError(); void doButNotIdproc(); void doButNoParenOpen(); +void doButNoClosingParen(); +// test expression list too void atribNoValidAfterId(); void atribAssignedToABadExprAStringcon(); diff --git a/test/test.c b/test/test.c index 2ff515d..186bbef 100644 --- a/test/test.c +++ b/test/test.c @@ -89,7 +89,7 @@ int main(void) { doButNotIdproc(); doButNoParenOpen(); - // doIdprocExprExprSimpTermoFatorNoValidTokenAfterId(); + doButNoClosingParen(); atribNoValidAfterId(); atribAssignedToABadExprAStringcon();