Merge branch 'main' of gitlab.cs.wallawalla.edu:lustje/language-interpreter-lab into josh_bison

This commit is contained in:
vel 2024-11-07 11:38:07 -08:00
commit 894feab242
Signed by: velvox
GPG Key ID: 59D9762F674151DF
23 changed files with 645 additions and 134 deletions

View File

@ -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) {

View File

@ -50,3 +50,535 @@ UTEST(scanner, hello) {
++index;
} while (t != TOKEN_EOF);
}
UTEST(scanner, quadratic) {
struct token_st tokens[] = {
{TOKEN_COMMENT, "*> Code altered from https://www.quora.com/What-is-a-COBOL-program-that-will-solve-a-quadratic-equation"},
{TOKEN_COMMENT, "*> Program finds the roots to a simple quadratic equation"},
{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_INTEGER, "77"},
{TOKEN_IDENT, "a"},
{TOKEN_PICTURE, "PIC"},
{TOKEN_SIGNED_NUMERIC, "S9"}, // Check later
{TOKEN_LEFT_PARENTHESIS, "("},
{TOKEN_INTEGER, "5"},
{TOKEN_RIGHT_PARENTHESIS, ")"},
{TOKEN_IMPLIED_DECIMAL, "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_INTEGER, "77"},
{TOKEN_IDENT, "b"},
{TOKEN_PICTURE, "PIC"},
{TOKEN_SIGNED_NUMERIC, "S9"},
{TOKEN_LEFT_PARENTHESIS, "("},
{TOKEN_INTEGER, "5"},
{TOKEN_RIGHT_PARENTHESIS, ")"},
{TOKEN_IMPLIED_DECIMAL, "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_INTEGER, "77"},
{TOKEN_IDENT, "c"},
{TOKEN_PICTURE, "PIC"},
{TOKEN_SIGNED_NUMERIC, "S9"},
{TOKEN_LEFT_PARENTHESIS, "("},
{TOKEN_INTEGER, "5"},
{TOKEN_RIGHT_PARENTHESIS, ")"},
{TOKEN_IMPLIED_DECIMAL, "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_INTEGER, "77"},
{TOKEN_IDENT, "discriminant"},
{TOKEN_PICTURE, "PIC"},
{TOKEN_SIGNED_NUMERIC, "S9"},
{TOKEN_LEFT_PARENTHESIS, "("},
{TOKEN_INTEGER, "5"},
{TOKEN_RIGHT_PARENTHESIS, ")"},
{TOKEN_IMPLIED_DECIMAL, "V9"},
{TOKEN_LEFT_PARENTHESIS, "("},
{TOKEN_INTEGER, "5"},
{TOKEN_RIGHT_PARENTHESIS, ")"},
{TOKEN_COMPUTATION_LEVEL_3, "COMP-3"},
{TOKEN_DOT, "."},
{TOKEN_INTEGER, "77"},
{TOKEN_IDENT, "root1"},
{TOKEN_PICTURE, "PIC"},
{TOKEN_SIGNED_NUMERIC, "S9"},
{TOKEN_LEFT_PARENTHESIS, "("},
{TOKEN_INTEGER, "5"},
{TOKEN_RIGHT_PARENTHESIS, ")"},
{TOKEN_IMPLIED_DECIMAL, "V9"},
{TOKEN_LEFT_PARENTHESIS, "("},
{TOKEN_INTEGER, "5"},
{TOKEN_RIGHT_PARENTHESIS, ")"},
{TOKEN_COMPUTATION_LEVEL_3, "COMP-3"},
{TOKEN_DOT, "."},
{TOKEN_INTEGER, "77"},
{TOKEN_IDENT, "root2"},
{TOKEN_PICTURE, "PIC"},
{TOKEN_SIGNED_NUMERIC, "S9"},
{TOKEN_LEFT_PARENTHESIS, "("},
{TOKEN_INTEGER, "5"},
{TOKEN_RIGHT_PARENTHESIS, ")"},
{TOKEN_IMPLIED_DECIMAL, "V9"},
{TOKEN_LEFT_PARENTHESIS, "("},
{TOKEN_INTEGER, "5"},
{TOKEN_RIGHT_PARENTHESIS, ")"},
{TOKEN_COMPUTATION_LEVEL_3, "COMP-3"},
{TOKEN_DOT, "."},
{TOKEN_INTEGER, "77"},
{TOKEN_IDENT, "square-root-discriminant"},
{TOKEN_PICTURE, "PIC"},
{TOKEN_SIGNED_NUMERIC, "S9"},
{TOKEN_LEFT_PARENTHESIS, "("},
{TOKEN_INTEGER, "5"},
{TOKEN_RIGHT_PARENTHESIS, ")"},
{TOKEN_IMPLIED_DECIMAL, "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_KEYWORD_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_KEYWORD_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_KEYWORD_COMPUTE, "COMPUTE"},
{TOKEN_IDENT, "root1"},
{TOKEN_EQUAL, "="},
{TOKEN_LEFT_PARENTHESIS, "("},
{TOKEN_SUB, "-"},
{TOKEN_IDENT, "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_KEYWORD_COMPUTE, "COMPUTE"},
{TOKEN_IDENT, "root2"},
{TOKEN_EQUAL, "="},
{TOKEN_LEFT_PARENTHESIS, "("},
{TOKEN_SUB, "-"},
{TOKEN_IDENT, "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_KEYWORD_COMPUTE, "COMPUTE"},
{TOKEN_IDENT, "root1"},
{TOKEN_EQUAL, "="},
{TOKEN_SUB, "-"},
{TOKEN_IDENT, "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);
}
UTEST(scanner, sorting) {
struct token_st tokens[] = {
{TOKEN_IDENTIFICATION, "IDENTIFICATION"},
{TOKEN_KEYWORD_DIVISION, "DIVISION"},
{TOKEN_DOT, "."},
{TOKEN_PROGRAM_ID, "PROGRAM-ID"},
{TOKEN_DOT, "."},
{TOKEN_IDENT, "sorting"},
{TOKEN_DOT, "."},
{TOKEN_KEYWORD_DATA, "DATA"},
{TOKEN_KEYWORD_DIVISION, "DIVISION"},
{TOKEN_DOT, "."},
{TOKEN_WORKING_STORAGE, "WORKING-STORAGE"},
{TOKEN_KEYWORD_SECTION, "SECTION"},
{TOKEN_DOT, "."},
{TOKEN_INTEGER, "01"},
{TOKEN_IDENT, "WS-SORT-AREA"},
{TOKEN_DOT, "."},
{TOKEN_INTEGER, "05"},
{TOKEN_IDENT, "WS-SORT-TABLE"},
{TOKEN_DOT, "."},
{TOKEN_INTEGER, "10"},
{TOKEN_IDENT, "WS-SORT-ROW"},
{TOKEN_PICTURE, "PIC"},
{TOKEN_ALPHANUMERIC, "X"},
{TOKEN_LEFT_PARENTHESIS, "("},
{TOKEN_INTEGER, "10"},
{TOKEN_RIGHT_PARENTHESIS, ")"},
{TOKEN_KEYWORD_OCCURS, "OCCURS"},
{TOKEN_INTEGER, "100"},
{TOKEN_DOT, "."},
{TOKEN_INTEGER, "05"},
{TOKEN_IDENT, "WS-TEMP-ROW"},
{TOKEN_PICTURE, "PIC"},
{TOKEN_ALPHANUMERIC, "X"},
{TOKEN_LEFT_PARENTHESIS, "("},
{TOKEN_INTEGER, "10"},
{TOKEN_RIGHT_PARENTHESIS, ")"},
{TOKEN_DOT, "."},
{TOKEN_INTEGER, "05"},
{TOKEN_IDENT, "WS-ROW-MAX"},
{TOKEN_PICTURE, "PIC"},
{TOKEN_SIGNED_NUMERIC, "S9"},
{TOKEN_LEFT_PARENTHESIS, "("},
{TOKEN_INTEGER, "4"},
{TOKEN_RIGHT_PARENTHESIS, ")"},
{TOKEN_COMPUTATION_LEVEL_0, "COMP"},
{TOKEN_KEYWORD_VALUE, "VALUE"},
{TOKEN_INTEGER, "100"},
{TOKEN_DOT, "."},
{TOKEN_INTEGER, "05"},
{TOKEN_IDENT, "WS-SORT-MAX"},
{TOKEN_PICTURE, "PIC"},
{TOKEN_SIGNED_NUMERIC, "S9"},
{TOKEN_LEFT_PARENTHESIS, "("},
{TOKEN_INTEGER, "4"},
{TOKEN_RIGHT_PARENTHESIS, ")"},
{TOKEN_COMPUTATION_LEVEL_0, "COMP"},
{TOKEN_DOT, "."},
{TOKEN_INTEGER, "05"},
{TOKEN_IDENT, "WS-I"},
{TOKEN_PICTURE, "PIC"},
{TOKEN_SIGNED_NUMERIC, "S9"},
{TOKEN_LEFT_PARENTHESIS, "("},
{TOKEN_INTEGER, "4"},
{TOKEN_RIGHT_PARENTHESIS, ")"},
{TOKEN_COMPUTATION_LEVEL_0, "COMP"},
{TOKEN_DOT, "."},
{TOKEN_INTEGER, "05"},
{TOKEN_IDENT, "WS-J"},
{TOKEN_PICTURE, "PIC"},
{TOKEN_SIGNED_NUMERIC, "S9"},
{TOKEN_LEFT_PARENTHESIS, "("},
{TOKEN_INTEGER, "4"},
{TOKEN_RIGHT_PARENTHESIS, ")"},
{TOKEN_COMPUTATION_LEVEL_0, "COMP"},
{TOKEN_DOT, "."},
{TOKEN_INTEGER, "05"},
{TOKEN_IDENT, "WS-INDEX"},
{TOKEN_PICTURE, "PIC"},
{TOKEN_SIGNED_NUMERIC, "S9"},
{TOKEN_LEFT_PARENTHESIS, "("},
{TOKEN_INTEGER, "4"},
{TOKEN_RIGHT_PARENTHESIS, ")"},
{TOKEN_COMPUTATION_LEVEL_0, "COMP"},
{TOKEN_DOT, "."},
{TOKEN_PROCEDURE, "PROCEDURE"},
{TOKEN_KEYWORD_DIVISION, "DIVISION"},
{TOKEN_DOT, "."},
{TOKEN_COMMENT, "*> Initialize test data"},
{TOKEN_MOVE, "MOVE"},
{TOKEN_STRING, "\"30\""},
{TOKEN_KEYWORD_TO, "TO"},
{TOKEN_IDENT, "WS-SORT-ROW"},
{TOKEN_LEFT_PARENTHESIS, "("},
{TOKEN_INTEGER, "1"},
{TOKEN_RIGHT_PARENTHESIS, ")"},
{TOKEN_MOVE, "MOVE"},
{TOKEN_STRING, "\"10\""},
{TOKEN_KEYWORD_TO, "TO"},
{TOKEN_IDENT, "WS-SORT-ROW"},
{TOKEN_LEFT_PARENTHESIS, "("},
{TOKEN_INTEGER, "2"},
{TOKEN_RIGHT_PARENTHESIS, ")"},
{TOKEN_MOVE, "MOVE"},
{TOKEN_STRING, "\"50\""},
{TOKEN_KEYWORD_TO, "TO"},
{TOKEN_IDENT, "WS-SORT-ROW"},
{TOKEN_LEFT_PARENTHESIS, "("},
{TOKEN_INTEGER, "3"},
{TOKEN_RIGHT_PARENTHESIS, ")"},
{TOKEN_MOVE, "MOVE"},
{TOKEN_STRING, "\"20\""},
{TOKEN_KEYWORD_TO, "TO"},
{TOKEN_IDENT, "WS-SORT-ROW"},
{TOKEN_LEFT_PARENTHESIS, "("},
{TOKEN_INTEGER, "4"},
{TOKEN_RIGHT_PARENTHESIS, ")"},
{TOKEN_MOVE, "MOVE"},
{TOKEN_STRING, "\"40\""},
{TOKEN_KEYWORD_TO, "TO"},
{TOKEN_IDENT, "WS-SORT-ROW"},
{TOKEN_LEFT_PARENTHESIS, "("},
{TOKEN_INTEGER, "5"},
{TOKEN_RIGHT_PARENTHESIS, ")"},
{TOKEN_MOVE, "MOVE"},
{TOKEN_INTEGER, "5"},
{TOKEN_KEYWORD_TO, "TO"},
{TOKEN_IDENT, "WS-SORT-MAX"},
{TOKEN_COMMENT, "*> * Display original array"},
{TOKEN_DISPLAY, "DISPLAY"},
{TOKEN_STRING, "\"Original Array Contents:\""},
{TOKEN_DISPLAY, "DISPLAY"},
{TOKEN_STRING, "\"---------------------\""},
{TOKEN_PERFORM, "PERFORM"},
{TOKEN_VARYING, "VARYING"},
{TOKEN_IDENT, "WS-INDEX"},
{TOKEN_KEYWORD_FROM, "FROM"},
{TOKEN_INTEGER, "1"},
{TOKEN_KEYWORD_BY, "BY"},
{TOKEN_INTEGER, "1"},
{TOKEN_UNTIL, "UNTIL"},
{TOKEN_IDENT, "WS-INDEX"},
{TOKEN_GREATER_THAN, ">"},
{TOKEN_IDENT, "WS-SORT-MAX"},
{TOKEN_DISPLAY, "DISPLAY"},
{TOKEN_STRING, "\"Element \""},
{TOKEN_IDENT, "WS-INDEX"},
{TOKEN_STRING, "\": \""},
{TOKEN_IDENT, "WS-SORT-ROW"},
{TOKEN_LEFT_PARENTHESIS, "("},
{TOKEN_IDENT, "WS-INDEX"},
{TOKEN_RIGHT_PARENTHESIS, ")"},
{TOKEN_END_PERFORM, "END-PERFORM"},
{TOKEN_DISPLAY, "DISPLAY"},
{TOKEN_SPACE, "SPACE"},
{TOKEN_COMMENT, "*> * Simplified bubble sort"},
{TOKEN_PERFORM, "PERFORM"},
{TOKEN_VARYING, "VARYING"},
{TOKEN_IDENT, "WS-I"},
{TOKEN_KEYWORD_FROM, "FROM"},
{TOKEN_INTEGER, "1"},
{TOKEN_KEYWORD_BY, "BY"},
{TOKEN_INTEGER, "1"},
{TOKEN_UNTIL, "UNTIL"},
{TOKEN_IDENT, "WS-I"},
{TOKEN_GREATER_THAN, ">"},
{TOKEN_IDENT, "WS-SORT-MAX"},
{TOKEN_SUB, "-"},
{TOKEN_INTEGER, "1"},
{TOKEN_PERFORM, "PERFORM"},
{TOKEN_VARYING, "VARYING"},
{TOKEN_IDENT, "WS-J"},
{TOKEN_KEYWORD_FROM, "FROM"},
{TOKEN_INTEGER, "1"},
{TOKEN_KEYWORD_BY, "BY"},
{TOKEN_INTEGER, "1"},
{TOKEN_UNTIL, "UNTIL"},
{TOKEN_IDENT, "WS-J"},
{TOKEN_GREATER_THAN, ">"},
{TOKEN_IDENT, "WS-SORT-MAX"},
{TOKEN_SUB, "-"},
{TOKEN_IDENT, "WS-I"},
{TOKEN_IF, "IF"},
{TOKEN_IDENT, "WS-SORT-ROW"},
{TOKEN_LEFT_PARENTHESIS, "("},
{TOKEN_IDENT, "WS-J"},
{TOKEN_RIGHT_PARENTHESIS, ")"},
{TOKEN_GREATER_THAN, ">"},
{TOKEN_IDENT, "WS-SORT-ROW"},
{TOKEN_LEFT_PARENTHESIS, "("},
{TOKEN_IDENT, "WS-J"},
{TOKEN_ADD, "+"},
{TOKEN_INTEGER, "1"},
{TOKEN_RIGHT_PARENTHESIS, ")"},
{TOKEN_MOVE, "MOVE"},
{TOKEN_IDENT, "WS-SORT-ROW"},
{TOKEN_LEFT_PARENTHESIS, "("},
{TOKEN_IDENT, "WS-J"},
{TOKEN_RIGHT_PARENTHESIS, ")"},
{TOKEN_KEYWORD_TO, "TO"},
{TOKEN_IDENT, "WS-TEMP-ROW"},
{TOKEN_MOVE, "MOVE"},
{TOKEN_IDENT, "WS-SORT-ROW"},
{TOKEN_LEFT_PARENTHESIS, "("},
{TOKEN_IDENT, "WS-J"},
{TOKEN_ADD, "+"},
{TOKEN_INTEGER, "1"},
{TOKEN_RIGHT_PARENTHESIS, ")"},
{TOKEN_KEYWORD_TO, "TO"},
{TOKEN_IDENT, "WS-SORT-ROW"},
{TOKEN_LEFT_PARENTHESIS, "("},
{TOKEN_IDENT, "WS-J"},
{TOKEN_RIGHT_PARENTHESIS, ")"},
{TOKEN_MOVE, "MOVE"},
{TOKEN_IDENT, "WS-TEMP-ROW"},
{TOKEN_KEYWORD_TO, "TO"},
{TOKEN_IDENT, "WS-SORT-ROW"},
{TOKEN_LEFT_PARENTHESIS, "("},
{TOKEN_IDENT, "WS-J"},
{TOKEN_ADD, "+"},
{TOKEN_INTEGER, "1"},
{TOKEN_RIGHT_PARENTHESIS, ")"},
{TOKEN_END_IF, "END-IF"},
{TOKEN_END_PERFORM, "END-PERFORM"},
{TOKEN_END_PERFORM, "END-PERFORM"},
{TOKEN_COMMENT, "*> * Display sorted array"},
{TOKEN_DISPLAY, "DISPLAY"},
{TOKEN_STRING, "\"Sorted Array Contents:\""},
{TOKEN_DISPLAY, "DISPLAY"},
{TOKEN_STRING, "\"--------------------\""},
{TOKEN_PERFORM, "PERFORM"},
{TOKEN_VARYING, "VARYING"},
{TOKEN_IDENT, "WS-INDEX"},
{TOKEN_KEYWORD_FROM, "FROM"},
{TOKEN_INTEGER, "1"},
{TOKEN_KEYWORD_BY, "BY"},
{TOKEN_INTEGER, "1"},
{TOKEN_UNTIL, "UNTIL"},
{TOKEN_IDENT, "WS-INDEX"},
{TOKEN_GREATER_THAN, ">"},
{TOKEN_IDENT, "WS-SORT-MAX"},
{TOKEN_DISPLAY, "DISPLAY"},
{TOKEN_STRING, "\"Element \""},
{TOKEN_IDENT, "WS-INDEX"},
{TOKEN_STRING, "\": \""},
{TOKEN_IDENT, "WS-SORT-ROW"},
{TOKEN_LEFT_PARENTHESIS, "("},
{TOKEN_IDENT, "WS-INDEX"},
{TOKEN_RIGHT_PARENTHESIS, ")"},
{TOKEN_END_PERFORM, "END-PERFORM"},
{TOKEN_DOT, "."},
{TOKEN_STOP, "STOP"},
{TOKEN_RUN, "RUN"},
{TOKEN_DOT, "."},
{TOKEN_EOF, ""},
};
yyin = fopen("samples/sorting-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);
}

View File

@ -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.

View File

@ -27,6 +27,7 @@ PERFORM { return TOKEN_PERFORM; }
END-PERFORM { return TOKEN_END_PERFORM; }
IF { return TOKEN_IF; }
END-IF { return TOKEN_END_IF; }
ELSE { return TOKEN_ELSE; }
SPACE { return TOKEN_SPACE; }
PIC { return TOKEN_PICTURE; }
OCCURS { return TOKEN_KEYWORD_OCCURS; }
@ -42,6 +43,7 @@ COMP-1 { return TOKEN_COMPUTATION_LEVEL_1; }
COMP-2 { return TOKEN_COMPUTATION_LEVEL_2; }
COMP-3 { return TOKEN_COMPUTATION_LEVEL_3; }
{DIGIT} { return TOKEN_INTEGER; }
{NAME} { return TOKEN_IDENT; }
\+ { return TOKEN_ADD; }
@ -53,6 +55,7 @@ COMP-3 { return TOKEN_COMPUTATION_LEVEL_3; }
\< { return TOKEN_LESS_THAN; }
\= { return TOKEN_EQUAL;}
"\""[^"]*"\"" { return TOKEN_STRING; }
"\'"[^']*"\'" { return TOKEN_STRING; }
"(" { return TOKEN_LEFT_PARENTHESIS; }

View File

@ -19,6 +19,7 @@ typedef enum {
TOKEN_UNTIL,
TOKEN_END_PERFORM,
TOKEN_IF,
TOKEN_ELSE,
TOKEN_END_IF,
TOKEN_SPACE,
TOKEN_KEYWORD_OCCURS,
@ -28,11 +29,13 @@ typedef enum {
TOKEN_IDENT,
TOKEN_STRING,
TOKEN_INTEGER,
TOKEN_NEGATIVE_INTEGER,
TOKEN_PICTURE,
TOKEN_ALPHANUMERIC,
TOKEN_NUMERIC,
TOKEN_SIGNED_NUMERIC,
TOKEN_IMPLIED_DECIMAL,
TOKEN_LEVEL_NUM,
TOKEN_COMPUTATION_LEVEL_0,
TOKEN_COMPUTATION_LEVEL_1,
TOKEN_COMPUTATION_LEVEL_2,

View File

@ -83,3 +83,42 @@ UTEST(parser, branching) {
// Assert the result to test correctness
ASSERT_EQ(result, 0);
}
UTEST(parser, assignment) {
char string[] = "MOVE 1 TO A\0";
YY_BUFFER_STATE buffer = yy_scan_buffer(string, sizeof(string));
yylineno = 1;
int result = yyparse();
yy_delete_buffer(buffer);
// Assert the result to test correctness
ASSERT_EQ(result, 0);
}
UTEST(parser, looping) {
char string[] = "PERFORM VARYING I FROM 1 BY 1 UNTIL I > 10 MOVE I TO A(I)\0";
YY_BUFFER_STATE buffer = yy_scan_buffer(string, sizeof(string));
yylineno = 1;
int result = yyparse();
yy_delete_buffer(buffer);
// Assert the result to test correctness
ASSERT_EQ(result, 0);
}
UTEST(parser, sorting) {
// Read sample file as input
yyin = fopen("samples/sorting-snippet.cbl", "r");
yyrestart(yyin);
ASSERT_TRUE(yyin);
yylineno = 1;
int result = yyparse();
// Assert the result to test correctness
ASSERT_EQ(result, 0);
}

View File

@ -28,8 +28,6 @@ int yylex();
%token TOKEN_UNTIL
%token TOKEN_END_PERFORM
%token TOKEN_IF
%token TOKEN_ELSE
%token TOKEN_ELSE_IF
%token TOKEN_END_IF
%token TOKEN_SPACE
%token TOKEN_KEYWORD_OCCURS

View File

@ -27,8 +27,6 @@ PERFORM { return TOKEN_PERFORM; }
END-PERFORM { return TOKEN_END_PERFORM; }
IF { return TOKEN_IF; }
END-IF { return TOKEN_END_IF; }
ELSE { return TOKEN_ELSE; }
ELSE-IF { return TOKEN_ELSE_IF; }
SPACE { return TOKEN_SPACE; }
PIC { return TOKEN_PICTURE; }
OCCURS { return TOKEN_KEYWORD_OCCURS; }

View File

@ -5,23 +5,24 @@ See the [example lab for Python](https://gitlab.cs.wallawalla.edu/cptr354/langua
In this lab, you will focus on basic operations that support your sample code.
- Arithmetic operations - Jenessy
- add
- subtract
- multiple
- divide
- Functions (but implemented directly in the language)
- Printing - Josh
- Square root - Jenessy
- Variable for numbers - Riley
- Variable for lists (or arrays) - Riley
- Branching statements - Josh
- Looping statements - Riley
* Arithmetic operations
* add
* subtract
* multiple
* divide
* Functions (but implemented directly in the language)
* Printing
* Square root
* Variable for numbers
* Variable for lists (or arrays)
* Branching statements
* Looping statements
Notice you will find a new file `expr.c`.
The file is used to implement the parser rule.
Inside these functions, you will create the runtime code that is the interpreter.
## Build Process
The process is similar to prior labs.
@ -74,30 +75,31 @@ To remove the build files, use make clean.
make clean
```
## Assignment Steps
1. Start by confirming these commands work for the sample code provided.
1. Next copy over your `scanner.flex`, `parser.bison` and sample programs from lab 5.
1. Next copy over your `scanner.flex`, `parser.bison` and sample programs from lab 5.
1. Start working on your bison `parser.bison` and `expr.c` files to implement the interpreter part of your parser.
## Grading Rubric
The grading will be over the following categories.
Points Description
Points Description
----------- ------------------------------------
30 points Ability to interpret — Hello world
30 points Ability to interpret — Quadratic equation
30 points Ability to interpret — Arithmetic operations
30 points Ability to interpret — Integer Sort example
20 points Ability to interpret — Looping operations
20 points Ability to interpret — Branching operations
20 points Ability to interpret — Array variables
10 points Report formatting and readability
---
30 points Ability to interpret — Hello world
30 points Ability to interpret — Quadratic equation
30 points Ability to interpret — Arithmetic operations
30 points Ability to interpret — Integer Sort example
20 points Ability to interpret — Looping operations
20 points Ability to interpret — Branching operations
20 points Ability to interpret — Array variables
10 points Report formatting and readability
## Turn In

View File

@ -0,0 +1 @@
a = [ 4, 8, 12 ];

View File

@ -0,0 +1,2 @@
a = [ 3, 5 ];
print a[0];

View File

@ -0,0 +1,4 @@
a = [ 3, 5, 7, 9, 11];
print a[1];
a[1] = 6;
print a[1];

View File

@ -0,0 +1 @@
a = 5;

View File

@ -1,5 +0,0 @@
IDENTIFICATION DIVISION.
PROGRAM-ID. HELLO-WORLD.
PROCEDURE DIVISION.
DISPLAY 'Hello World!'
STOP RUN.

View File

@ -0,0 +1,2 @@
print 5;
print 6;

View File

@ -0,0 +1,6 @@
if 3==3 then
print 3;
endif
if 3==4 then
print 4;
endif

View File

@ -0,0 +1,5 @@
if 0 then
print 5;
print 3;
print 1;
endif

View File

@ -0,0 +1,5 @@
if 1 then
print 5;
print 3;
print 1;
endif

View File

@ -0,0 +1 @@
print 5;

View File

@ -0,0 +1,2 @@
a = 4 + 4;
print a;

2
lab-5/samples/program.c Normal file
View File

@ -0,0 +1,2 @@
a=(101*20)+4;
print(a);

View File

@ -1,35 +0,0 @@
*> Code altered from https://www.quora.com/What-is-a-COBOL-program-that-will-solve-a-quadratic-equation
*> Program finds the roots to a simple quadratic equation
IDENTIFICATION DIVISION.
PROGRAM-ID. QuadraticSolver.
DATA DIVISION.
WORKING-STORAGE SECTION.
77 a PIC S9(5)V9(5) COMP-3 VALUE 1.
77 b PIC S9(5)V9(5) COMP-3 VALUE 5.
77 c PIC S9(5)V9(5) COMP-3 VALUE 6.
77 discriminant PIC S9(5)V9(5) COMP-3.
77 root1 PIC S9(5)V9(5) COMP-3.
77 root2 PIC S9(5)V9(5) COMP-3.
77 square-root-discriminant PIC S9(5)V9(5) COMP-3.
PROCEDURE DIVISION. *> program begins here
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
ELSE IF discriminant = 0
COMPUTE root1 = -b / (2 * a)
DISPLAY "The equation has one real root: "
DISPLAY "Root: " root1
ELSE
DISPLAY "The equation has no real roots."
STOP RUN.

View File

@ -1,55 +0,0 @@
IDENTIFICATION DIVISION.
PROGRAM-ID. sorting.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-SORT-AREA.
05 WS-SORT-TABLE.
10 WS-SORT-ROW PIC X(10) OCCURS 100.
05 WS-TEMP-ROW PIC X(10).
05 WS-ROW-MAX PIC S9(4) COMP VALUE 100.
05 WS-SORT-MAX PIC S9(4) COMP.
05 WS-I PIC S9(4) COMP.
05 WS-J PIC S9(4) COMP.
05 WS-INDEX PIC S9(4) COMP.
PROCEDURE DIVISION.
*> Initialize test data
MOVE "30" TO WS-SORT-ROW(1)
MOVE "10" TO WS-SORT-ROW(2)
MOVE "50" TO WS-SORT-ROW(3)
MOVE "20" TO WS-SORT-ROW(4)
MOVE "40" TO WS-SORT-ROW(5)
MOVE 5 TO WS-SORT-MAX
*> * Display original array
DISPLAY "Original Array Contents:"
DISPLAY "---------------------"
PERFORM VARYING WS-INDEX FROM 1 BY 1
UNTIL WS-INDEX > WS-SORT-MAX
DISPLAY "Element " WS-INDEX ": " WS-SORT-ROW(WS-INDEX)
END-PERFORM
DISPLAY SPACE
*> * Simplified bubble sort
PERFORM VARYING WS-I FROM 1 BY 1
UNTIL WS-I > WS-SORT-MAX - 1
PERFORM VARYING WS-J FROM 1 BY 1
UNTIL WS-J > WS-SORT-MAX - WS-I
IF WS-SORT-ROW(WS-J) > WS-SORT-ROW(WS-J + 1)
MOVE WS-SORT-ROW(WS-J) TO WS-TEMP-ROW
MOVE WS-SORT-ROW(WS-J + 1) TO WS-SORT-ROW(WS-J)
MOVE WS-TEMP-ROW TO WS-SORT-ROW(WS-J + 1)
END-IF
END-PERFORM
END-PERFORM
*> * Display sorted array
DISPLAY "Sorted Array Contents:"
DISPLAY "--------------------"
PERFORM VARYING WS-INDEX FROM 1 BY 1
UNTIL WS-INDEX > WS-SORT-MAX
DISPLAY "Element " WS-INDEX ": " WS-SORT-ROW(WS-INDEX)
END-PERFORM.
STOP RUN.