diff --git a/lab-3/main.c b/lab-3/main.c index 59ddc86..1187003 100644 --- a/lab-3/main.c +++ b/lab-3/main.c @@ -8,7 +8,7 @@ extern char *yytext; int main(int argc, char *argv[]) { FILE *file; - const char *filename = "samples/hello-world.cbl"; // Default filename + const char *filename = "samples/quadratic_snippet.cbl"; // Default filename // Check if a filename is provided as a command-line argument if (argc > 1) { diff --git a/lab-3/main_test.c b/lab-3/main_test.c index e2aa6a9..e1075e4 100644 --- a/lab-3/main_test.c +++ b/lab-3/main_test.c @@ -49,3 +49,260 @@ UTEST(scanner, hello) { ++index; } while (t != TOKEN_EOF); } + +UTEST(scanner, quadratic) { + struct token_st tokens[] = { + {TOKEN_IDENTIFICATION, "IDENTIFICATION"}, + {TOKEN_KEYWORD_DIVISION, "DIVISION"}, + {TOKEN_DOT, "."}, + {TOKEN_PROGRAM_ID, "PROGRAM-ID"}, + {TOKEN_DOT, "."}, + {TOKEN_IDENT, "QuadraticSolver"}, + {TOKEN_DOT, "."}, + {TOKEN_KEYWORD_DATA, "DATA"}, + {TOKEN_KEYWORD_DIVISION, "DIVISION"}, + {TOKEN_DOT, "."}, + + {TOKEN_WORKING_STORAGE, "WORKING_STORAGE,"}, + {TOKEN_KEYWORD_SECTION, "SECTION"}, + {TOKEN_DOT, "."}, + + {TOKEN_LEVEL_NUM, "77"}, + {TOKEN_IDENT, "a"}, + {TOKEN_PICTURE, "PIC"}, + {TOKEN_NUMERIC, "S9"}, + {TOKEN_LEFT_PARENTHESIS, "("}, + {TOKEN_INTEGER, "5"}, + {TOKEN_RIGHT_PARENTHESIS, ")"}, + {TOKEN_NUMERIC, "V9"}, + {TOKEN_LEFT_PARENTHESIS, "("}, + {TOKEN_INTEGER, "5"}, + {TOKEN_RIGHT_PARENTHESIS, ")"}, + {TOKEN_COMPUTATION_LEVEL_3, "COMP-3"}, + {TOKEN_KEYWORD_VALUE, "VALUE"}, + {TOKEN_INTEGER, "1"}, + {TOKEN_DOT, "."}, + + {TOKEN_LEVEL_NUM, "77"}, + {TOKEN_IDENT, "b"}, + {TOKEN_PICTURE, "PIC"}, + {TOKEN_NUMERIC, "S9"}, + {TOKEN_LEFT_PARENTHESIS, "("}, + {TOKEN_INTEGER, "5"}, + {TOKEN_RIGHT_PARENTHESIS, ")"}, + {TOKEN_NUMERIC, "V9"}, + {TOKEN_LEFT_PARENTHESIS, "("}, + {TOKEN_INTEGER, "5"}, + {TOKEN_RIGHT_PARENTHESIS, ")"}, + {TOKEN_COMPUTATION_LEVEL_3, "COMP-3"}, + {TOKEN_KEYWORD_VALUE, "VALUE"}, + {TOKEN_INTEGER, "5"}, + {TOKEN_DOT, "."}, + + {TOKEN_LEVEL_NUM, "77"}, + {TOKEN_IDENT, "c"}, + {TOKEN_PICTURE, "PIC"}, + {TOKEN_NUMERIC, "S9"}, + {TOKEN_LEFT_PARENTHESIS, "("}, + {TOKEN_INTEGER, "5"}, + {TOKEN_RIGHT_PARENTHESIS, ")"}, + {TOKEN_NUMERIC, "V9"}, + {TOKEN_LEFT_PARENTHESIS, "("}, + {TOKEN_INTEGER, "5"}, + {TOKEN_RIGHT_PARENTHESIS, ")"}, + {TOKEN_COMPUTATION_LEVEL_3, "COMP-3"}, + {TOKEN_KEYWORD_VALUE, "VALUE"}, + {TOKEN_INTEGER, "6"}, + {TOKEN_DOT, "."}, + + {TOKEN_LEVEL_NUM, "77"}, + {TOKEN_IDENT, "discriminant"}, + {TOKEN_PICTURE, "PIC"}, + {TOKEN_NUMERIC, "S9"}, + {TOKEN_LEFT_PARENTHESIS, "("}, + {TOKEN_INTEGER, "5"}, + {TOKEN_RIGHT_PARENTHESIS, ")"}, + {TOKEN_NUMERIC, "V9"}, + {TOKEN_LEFT_PARENTHESIS, "("}, + {TOKEN_INTEGER, "5"}, + {TOKEN_RIGHT_PARENTHESIS, ")"}, + {TOKEN_COMPUTATION_LEVEL_3, "COMP-3"}, + {TOKEN_DOT, "."}, + + {TOKEN_LEVEL_NUM, "77"}, + {TOKEN_IDENT, "root1"}, + {TOKEN_PICTURE, "PIC"}, + {TOKEN_NUMERIC, "S9"}, + {TOKEN_LEFT_PARENTHESIS, "("}, + {TOKEN_INTEGER, "5"}, + {TOKEN_RIGHT_PARENTHESIS, ")"}, + {TOKEN_NUMERIC, "V9"}, + {TOKEN_LEFT_PARENTHESIS, "("}, + {TOKEN_INTEGER, "5"}, + {TOKEN_RIGHT_PARENTHESIS, ")"}, + {TOKEN_COMPUTATION_LEVEL_3, "COMP-3"}, + {TOKEN_DOT, "."}, + + {TOKEN_LEVEL_NUM, "77"}, + {TOKEN_IDENT, "root2"}, + {TOKEN_PICTURE, "PIC"}, + {TOKEN_NUMERIC, "S9"}, + {TOKEN_LEFT_PARENTHESIS, "("}, + {TOKEN_INTEGER, "5"}, + {TOKEN_RIGHT_PARENTHESIS, ")"}, + {TOKEN_NUMERIC, "V9"}, + {TOKEN_LEFT_PARENTHESIS, "("}, + {TOKEN_INTEGER, "5"}, + {TOKEN_RIGHT_PARENTHESIS, ")"}, + {TOKEN_COMPUTATION_LEVEL_3, "COMP-3"}, + {TOKEN_DOT, "."}, + + {TOKEN_LEVEL_NUM, "77"}, + {TOKEN_IDENT, "square-root-discriminant"}, + {TOKEN_PICTURE, "PIC"}, + {TOKEN_NUMERIC, "S9"}, + {TOKEN_LEFT_PARENTHESIS, "("}, + {TOKEN_INTEGER, "5"}, + {TOKEN_RIGHT_PARENTHESIS, ")"}, + {TOKEN_NUMERIC, "V9"}, + {TOKEN_LEFT_PARENTHESIS, "("}, + {TOKEN_INTEGER, "5"}, + {TOKEN_RIGHT_PARENTHESIS, ")"}, + {TOKEN_COMPUTATION_LEVEL_3, "COMP-3"}, + {TOKEN_DOT, "."}, + + {TOKEN_EOF, ""}, + + {TOKEN_PROCEDURE, "PROCEDURE"}, + {TOKEN_KEYWORD_DIVISION, "DIVISION"}, + {TOKEN_DOT, "."}, + {TOKEN_COMMENT, "*> program begins here"}, + {TOKEN_DISPLAY, "DISPLAY"}, + {TOKEN_STRING, "'EQUATION: (1x^2) + 5x + 6 = 0'"}, + {TOKEN_COMPUTE, "COMPUTE"}, + {TOKEN_IDENT, "discriminant"}, + {TOKEN_EQUAL, "="}, + {TOKEN_LEFT_PARENTHESIS, "("}, + {TOKEN_IDENT, "b"}, + {TOKEN_EXPONENTIAL, "**"}, + {TOKEN_INTEGER, "2"}, + {TOKEN_RIGHT_PARENTHESIS, ")"}, + {TOKEN_SUB, "-"}, + {TOKEN_LEFT_PARENTHESIS, "("}, + {TOKEN_INTEGER, "4"}, + {TOKEN_MULTIPLY, "*"}, + {TOKEN_IDENT, "a"}, + {TOKEN_MULTIPLY, "*"}, + {TOKEN_IDENT, "c"}, + {TOKEN_RIGHT_PARENTHESIS, ")"}, + + {TOKEN_EOF, ""}, + + {TOKEN_IF, "IF"}, + {TOKEN_IDENT, "discriminant"}, + {TOKEN_GREATER_THAN, ">"}, + {TOKEN_INTEGER, "0"}, + + {TOKEN_COMPUTE, "COMPUTE"}, + {TOKEN_IDENT, "square-root-discriminant"}, + {TOKEN_EQUAL, "="}, + {TOKEN_KEYWORD_FUNCTION, "FUNCTION"}, + {TOKEN_IDENT, "SQRT"}, + {TOKEN_LEFT_PARENTHESIS, "("}, + {TOKEN_IDENT, "discriminant"}, + {TOKEN_RIGHT_PARENTHESIS, ")"}, + + + {TOKEN_COMPUTE, "COMPUTE"}, + {TOKEN_IDENT, "root1"}, + {TOKEN_EQUAL, "="}, + {TOKEN_LEFT_PARENTHESIS, "("}, + {TOKEN_SIGNED_NUMERIC, "-b"}, + {TOKEN_ADD, "+"}, + {TOKEN_IDENT, "square-root-discriminant"}, + {TOKEN_RIGHT_PARENTHESIS, ")"}, + {TOKEN_DIVIDE, "/"}, + {TOKEN_LEFT_PARENTHESIS, "("}, + {TOKEN_INTEGER, "2"}, + {TOKEN_MULTIPLY, "*"}, + {TOKEN_IDENT, "a"}, + {TOKEN_RIGHT_PARENTHESIS, ")"}, + + {TOKEN_COMPUTE, "COMPUTE"}, + {TOKEN_IDENT, "root2"}, + {TOKEN_EQUAL, "="}, + {TOKEN_LEFT_PARENTHESIS, "("}, + {TOKEN_SIGNED_NUMERIC, "-b"}, + {TOKEN_SUB, "-"}, + {TOKEN_IDENT, "square-root-discriminant"}, + {TOKEN_RIGHT_PARENTHESIS, ")"}, + {TOKEN_DIVIDE, "/"}, + {TOKEN_LEFT_PARENTHESIS, "("}, + {TOKEN_INTEGER, "2"}, + {TOKEN_MULTIPLY, "*"}, + {TOKEN_IDENT, "a"}, + {TOKEN_RIGHT_PARENTHESIS, ")"}, + + {TOKEN_DISPLAY, "DISPLAY"}, + {TOKEN_STRING, "'The equation has two distinct real roots: '"}, + + {TOKEN_DISPLAY, "DISPLAY"}, + {TOKEN_STRING, "'Root 1: '"}, + {TOKEN_IDENT, "root1"}, + + {TOKEN_DISPLAY, "DISPLAY"}, + {TOKEN_STRING, "'Root 2: '"}, + {TOKEN_IDENT, "root2"}, + + {TOKEN_EOF, ""}, + + {TOKEN_ELSE, "ELSE"}, + {TOKEN_IF, "IF"}, + {TOKEN_IDENT, "discriminant"}, + {TOKEN_EQUAL, "="}, + {TOKEN_INTEGER, "0"}, + + {TOKEN_COMPUTE, "COMPUTE"}, + {TOKEN_IDENT, "root1"}, + {TOKEN_EQUAL, "="}, + {TOKEN_SIGNED_NUMERIC, "-b"}, + {TOKEN_DIVIDE, "/"}, + {TOKEN_LEFT_PARENTHESIS, "("}, + {TOKEN_INTEGER, "2"}, + {TOKEN_MULTIPLY, "*"}, + {TOKEN_IDENT, "a"}, + {TOKEN_RIGHT_PARENTHESIS, ")"}, + + + {TOKEN_DISPLAY, "DISPLAY"}, + {TOKEN_STRING, "'The equation has one real root: '"}, + + {TOKEN_DISPLAY, "DISPLAY"}, + {TOKEN_STRING, "Root:"}, + {TOKEN_IDENT, "root1"}, + + + {TOKEN_ELSE, "ELSE"}, + + {TOKEN_DISPLAY, "DISPLAY"}, + {TOKEN_STRING, "'The equation has no real roots.'"}, + + {TOKEN_EOF, ""}, + + {TOKEN_STOP, "STOP"}, + {TOKEN_RUN, "RUN"}, + {TOKEN_DOT, "."}, + {TOKEN_EOF, ""}, + }; + + yyin = fopen("samples/quadratic-snippet.cbl", "r"); + ASSERT_TRUE(yyin); + int index = 0; + token_t t; + do { + // printf("index: %d token: %d text: %s\n", index, t, yytext); + ASSERT_EQ(tokens[index].t, (t = yylex())); + ASSERT_STREQ(tokens[index].p, yytext); + ++index; + } while (t != TOKEN_EOF); +} \ No newline at end of file diff --git a/lab-3/samples/quadratic-snippet.cbl b/lab-3/samples/quadratic-snippet.cbl index ab76e40..18ba158 100644 --- a/lab-3/samples/quadratic-snippet.cbl +++ b/lab-3/samples/quadratic-snippet.cbl @@ -14,22 +14,22 @@ 77 square-root-discriminant PIC S9(5)V9(5) COMP-3. PROCEDURE DIVISION. *> program begins here - DISPLAY "EQUATION: (1x^2) + 5x + 6 = 0" + DISPLAY 'EQUATION: (1x^2) + 5x + 6 = 0' COMPUTE discriminant = (b ** 2) - (4 * a * c) IF discriminant > 0 COMPUTE square-root-discriminant = FUNCTION SQRT(discriminant) COMPUTE root1 = (-b + square-root-discriminant) / (2 * a) COMPUTE root2 = (-b - square-root-discriminant) / (2 * a) - DISPLAY "The equation has two distinct real roots: " - DISPLAY "Root 1: " root1 - DISPLAY "Root 2: " root2 + DISPLAY 'The equation has two distinct real roots: ' + DISPLAY 'Root 1: ' root1 + DISPLAY 'Root 2: ' root2 ELSE IF discriminant = 0 COMPUTE root1 = -b / (2 * a) - DISPLAY "The equation has one real root: " - DISPLAY "Root: " root1 + DISPLAY 'The equation has one real root: ' + DISPLAY 'Root: ' root1 ELSE - DISPLAY "The equation has no real roots." + DISPLAY 'The equation has no real roots.' STOP RUN. diff --git a/lab-3/token.h b/lab-3/token.h index 176d506..b77c4ac 100644 --- a/lab-3/token.h +++ b/lab-3/token.h @@ -19,6 +19,7 @@ typedef enum { TOKEN_UNTIL, TOKEN_END_PERFORM, TOKEN_IF, + TOKEN_ELSE, TOKEN_END_IF, TOKEN_SPACE, TOKEN_KEYWORD_OCCURS, @@ -33,6 +34,7 @@ typedef enum { TOKEN_NUMERIC, TOKEN_SIGNED_NUMERIC, TOKEN_IMPLIED_DECIMAL, + TOKEN_LEVEL_NUM, TOKEN_COMPUTATION_LEVEL_0, TOKEN_COMPUTATION_LEVEL_1, TOKEN_COMPUTATION_LEVEL_2,