test
This commit is contained in:
commit
a43c72a7c6
|
|
@ -1,3 +1,4 @@
|
||||||
|
---
|
||||||
lab_3_tests:
|
lab_3_tests:
|
||||||
stage: test
|
stage: test
|
||||||
image: gitlab.cs.wallawalla.edu:5050/cs_department/docker-images/cpp
|
image: gitlab.cs.wallawalla.edu:5050/cs_department/docker-images/cpp
|
||||||
|
|
@ -12,3 +13,15 @@ lab_3_tests:
|
||||||
- gcc main_test.c scanner.c -o scanner_test.out
|
- gcc main_test.c scanner.c -o scanner_test.out
|
||||||
- echo "Lab 3 - Run Tests"
|
- echo "Lab 3 - Run Tests"
|
||||||
- ./scanner_test.out
|
- ./scanner_test.out
|
||||||
|
|
||||||
|
lab_4_tests:
|
||||||
|
stage: test
|
||||||
|
image: gitlab.cs.wallawalla.edu:5050/cs_department/docker-images/cpp
|
||||||
|
script:
|
||||||
|
- apt update
|
||||||
|
- apt install -y flex bison
|
||||||
|
- bison --version
|
||||||
|
- cd lab-4
|
||||||
|
- echo "Lab 4 - Bison Parser"
|
||||||
|
- make test
|
||||||
|
- ./parser_test.out
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ extern char *yytext;
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
FILE *file;
|
FILE *file;
|
||||||
const char *filename = "samples/quadratic-snippet.cbl"; // Default filename
|
const char *filename = "samples/hello-world.cbl"; // Default filename
|
||||||
|
|
||||||
// Check if a filename is provided as a command-line argument
|
// Check if a filename is provided as a command-line argument
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
|
|
|
||||||
|
|
@ -18,30 +18,6 @@ struct token_st {
|
||||||
char *p;
|
char *p;
|
||||||
};
|
};
|
||||||
|
|
||||||
// UTEST(scanner, identifier) {
|
|
||||||
// token_t t;
|
|
||||||
// // Must include the null character to terminate input
|
|
||||||
// char string[] = "test\0";
|
|
||||||
// YY_BUFFER_STATE buffer = yy_scan_buffer(string, sizeof(string));
|
|
||||||
|
|
||||||
// ASSERT_EQ(TOKEN_EOF, (t = yylex()));
|
|
||||||
// ASSERT_STREQ("", yytext);
|
|
||||||
|
|
||||||
// yy_delete_buffer(buffer);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// UTEST(scanner, assignment) {
|
|
||||||
// token_t t;
|
|
||||||
// // Must include the null character to terminate input
|
|
||||||
// char string[] = "=\0";
|
|
||||||
// YY_BUFFER_STATE buffer = yy_scan_buffer(string, sizeof(string));
|
|
||||||
|
|
||||||
// ASSERT_EQ(TOKEN_EOF, (t = yylex()));
|
|
||||||
// ASSERT_STREQ("", yytext);
|
|
||||||
|
|
||||||
// yy_delete_buffer(buffer);
|
|
||||||
// }
|
|
||||||
|
|
||||||
UTEST(scanner, hello) {
|
UTEST(scanner, hello) {
|
||||||
struct token_st tokens[] = {
|
struct token_st tokens[] = {
|
||||||
{TOKEN_IDENTIFICATION, "IDENTIFICATION"},
|
{TOKEN_IDENTIFICATION, "IDENTIFICATION"},
|
||||||
|
|
@ -64,12 +40,11 @@ UTEST(scanner, hello) {
|
||||||
|
|
||||||
|
|
||||||
yyin = fopen("samples/hello-world.cbl", "r");
|
yyin = fopen("samples/hello-world.cbl", "r");
|
||||||
yyrestart(yyin);
|
|
||||||
ASSERT_TRUE(yyin);
|
ASSERT_TRUE(yyin);
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
token_t t;
|
token_t t;
|
||||||
do {
|
do {
|
||||||
|
printf("index: %d token: %d text: %s\n", index, t, yytext);
|
||||||
ASSERT_EQ(tokens[index].t, (t = yylex()));
|
ASSERT_EQ(tokens[index].t, (t = yylex()));
|
||||||
ASSERT_STREQ(tokens[index].p, yytext);
|
ASSERT_STREQ(tokens[index].p, yytext);
|
||||||
++index;
|
++index;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
%}
|
%}
|
||||||
NAME [a-zA-Z]([a-zA-Z0-9_-]*[a-zA-Z0-9])?
|
NAME [a-zA-Z]([a-zA-Z0-9_-]*[a-zA-Z0-9])?
|
||||||
DIGIT [0-9]+
|
DIGIT [0-9]+
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
(" "|\t|\n) /* skip whitespace */
|
(" "|\t|\n) /* skip whitespace */
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TOKEN_EOF = 0,
|
TOKEN_EOF = 0,
|
||||||
// Identification Keywords
|
|
||||||
TOKEN_IDENTIFICATION,
|
TOKEN_IDENTIFICATION,
|
||||||
TOKEN_KEYWORD_DIVISION,
|
TOKEN_KEYWORD_DIVISION,
|
||||||
TOKEN_KEYWORD_DATA,
|
TOKEN_KEYWORD_DATA,
|
||||||
|
|
@ -8,8 +7,6 @@ typedef enum {
|
||||||
TOKEN_PROGRAM_ID,
|
TOKEN_PROGRAM_ID,
|
||||||
TOKEN_WORKING_STORAGE,
|
TOKEN_WORKING_STORAGE,
|
||||||
TOKEN_PROCEDURE,
|
TOKEN_PROCEDURE,
|
||||||
|
|
||||||
// Program Keywords
|
|
||||||
TOKEN_DISPLAY,
|
TOKEN_DISPLAY,
|
||||||
TOKEN_STOP,
|
TOKEN_STOP,
|
||||||
TOKEN_RUN,
|
TOKEN_RUN,
|
||||||
|
|
@ -28,10 +25,7 @@ typedef enum {
|
||||||
TOKEN_KEYWORD_VALUE,
|
TOKEN_KEYWORD_VALUE,
|
||||||
TOKEN_KEYWORD_COMPUTE,
|
TOKEN_KEYWORD_COMPUTE,
|
||||||
TOKEN_KEYWORD_FUNCTION,
|
TOKEN_KEYWORD_FUNCTION,
|
||||||
|
|
||||||
// Identifiers
|
|
||||||
TOKEN_IDENT,
|
TOKEN_IDENT,
|
||||||
// Data types
|
|
||||||
TOKEN_STRING,
|
TOKEN_STRING,
|
||||||
TOKEN_INTEGER,
|
TOKEN_INTEGER,
|
||||||
TOKEN_PICTURE,
|
TOKEN_PICTURE,
|
||||||
|
|
@ -39,19 +33,14 @@ typedef enum {
|
||||||
TOKEN_NUMERIC,
|
TOKEN_NUMERIC,
|
||||||
TOKEN_SIGNED_NUMERIC,
|
TOKEN_SIGNED_NUMERIC,
|
||||||
TOKEN_IMPLIED_DECIMAL,
|
TOKEN_IMPLIED_DECIMAL,
|
||||||
// https://ibmmainframes.com/about393.html
|
|
||||||
TOKEN_COMPUTATION_LEVEL_0,
|
TOKEN_COMPUTATION_LEVEL_0,
|
||||||
TOKEN_COMPUTATION_LEVEL_1,
|
TOKEN_COMPUTATION_LEVEL_1,
|
||||||
TOKEN_COMPUTATION_LEVEL_2,
|
TOKEN_COMPUTATION_LEVEL_2,
|
||||||
TOKEN_COMPUTATION_LEVEL_3,
|
TOKEN_COMPUTATION_LEVEL_3,
|
||||||
|
|
||||||
// Grammar
|
|
||||||
TOKEN_LEFT_PARENTHESIS,
|
TOKEN_LEFT_PARENTHESIS,
|
||||||
TOKEN_RIGHT_PARENTHESIS,
|
TOKEN_RIGHT_PARENTHESIS,
|
||||||
TOKEN_DOT,
|
TOKEN_DOT,
|
||||||
TOKEN_COMMENT,
|
TOKEN_COMMENT,
|
||||||
|
|
||||||
// Operators
|
|
||||||
TOKEN_ADD,
|
TOKEN_ADD,
|
||||||
TOKEN_SUB,
|
TOKEN_SUB,
|
||||||
TOKEN_MULTIPLY,
|
TOKEN_MULTIPLY,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
|
||||||
|
# The top level rule indicates how to link everything together into main
|
||||||
|
|
||||||
|
main: main.o scanner.o parser.o
|
||||||
|
gcc main.o scanner.o parser.o -o parser.out -lm
|
||||||
|
|
||||||
|
test: main_test.o scanner.o parser.o
|
||||||
|
gcc main_test.o scanner.o parser.o -o parser_test.out -lm
|
||||||
|
|
||||||
|
# Only the files generated by flex and bison need explicit rules.
|
||||||
|
|
||||||
|
scanner.c: scanner.flex parser.h
|
||||||
|
flex -oscanner.c scanner.flex
|
||||||
|
|
||||||
|
parser.c parser.h: parser.bison
|
||||||
|
bison --defines=token.h --output=parser.c -v parser.bison
|
||||||
|
|
||||||
|
# This pattern indicates that any .o file depends
|
||||||
|
# upon the .c file of the same name, and all of the .h files.
|
||||||
|
# So, if a .o file is needed, it is built automatically.
|
||||||
|
|
||||||
|
%.o: %.c *.h
|
||||||
|
gcc -Wall -c $< -o $@
|
||||||
|
|
||||||
|
# clean causes all intermediate files to be deleted.
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f parser.c parser.output token.h scanner.c *.o parser.out parser_test.out
|
||||||
|
|
||||||
|
|
@ -0,0 +1,98 @@
|
||||||
|
# Bison Parser With Tests
|
||||||
|
|
||||||
|
Create a scanner for your sample programs with tests.
|
||||||
|
The tests should include basic statements and the sample files for your language.
|
||||||
|
See the [example lab for Python](https://gitlab.cs.wallawalla.edu/cptr354/language-interpreter-lab-python).
|
||||||
|
|
||||||
|
## Build Process
|
||||||
|
|
||||||
|
To build the `scanner.c` run the following **flex** command.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
flex -o scanner.c scanner.flex
|
||||||
|
```
|
||||||
|
|
||||||
|
The parser is built using **bison**.
|
||||||
|
Note this command also builds the `token.h`.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
bison --defines=token.h --output=parser.c -v parser.bison
|
||||||
|
```
|
||||||
|
|
||||||
|
THe `-v` flag will create a `parser.output` which represents the grammar in text form.
|
||||||
|
|
||||||
|
|
||||||
|
### Running the Parser
|
||||||
|
|
||||||
|
Then build the `main.c`, `parcer.c` and `scanner.c` using **gcc**.
|
||||||
|
Note that you may get a few warnings that can be ignored.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
gcc main.c scanner.c parser.c -o parser.out
|
||||||
|
```
|
||||||
|
|
||||||
|
Then execute the test suite using `./parser.out` and pass in the input from your sample program.
|
||||||
|
For example here is a command for `samples/program.c`
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./parser.out < samples/program.c
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Testing the Parser
|
||||||
|
|
||||||
|
Then build the `main_test.c`, `parcer.c` and `scanner.c` using **gcc**.
|
||||||
|
Note that you may get a few warnings that can be ignored.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
gcc main_test.c scanner.c parser.c -o parser_test.out
|
||||||
|
```
|
||||||
|
|
||||||
|
Then execute the test suite using `./parser_test.out`.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./parser_test.out
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Using Make
|
||||||
|
|
||||||
|
Alternatively you can use the supplied make file.
|
||||||
|
|
||||||
|
* Build main program - `make`
|
||||||
|
* Build test program - `make test`
|
||||||
|
* Clean up build files - `make clean`
|
||||||
|
|
||||||
|
|
||||||
|
## Tests
|
||||||
|
|
||||||
|
* Write test for various statements in your language
|
||||||
|
* assignment
|
||||||
|
* print
|
||||||
|
* mathmatical expressions
|
||||||
|
* boolean expressions
|
||||||
|
* branching
|
||||||
|
* looping
|
||||||
|
* Write a test for each sample test file.
|
||||||
|
* Hello World!
|
||||||
|
* Quadratic
|
||||||
|
* Sorting
|
||||||
|
|
||||||
|
|
||||||
|
## Grading Rubric
|
||||||
|
|
||||||
|
The grading will be over the following categories.
|
||||||
|
|
||||||
|
Points Description
|
||||||
|
----------- ------------------------------------
|
||||||
|
60 points Ability to parse — Six different language statements
|
||||||
|
10 points Ability to parse — Hello world
|
||||||
|
10 points Ability to parse — Quadratic equation
|
||||||
|
10 points Ability to parse — Integer sorting
|
||||||
|
10 points Report formatting and readability
|
||||||
|
|
||||||
|
|
||||||
|
## Turn In
|
||||||
|
|
||||||
|
Please submit the URL of your gitlab project to D2L's Brightspace with your report.
|
||||||
|
On gitlab update the `lab-4` folder to have your report and code snippets before the due date.
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
extern int yyparse();
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
if (yyparse() == 0) {
|
||||||
|
printf("Parse successful!\n");
|
||||||
|
} else {
|
||||||
|
printf("Parse failed.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
// https://github.com/sheredom/utest.h/blob/master/utest.h
|
||||||
|
#include "utest.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
extern int yyparse();
|
||||||
|
|
||||||
|
typedef struct yy_buffer_state *YY_BUFFER_STATE;
|
||||||
|
extern int yyrestart();
|
||||||
|
extern YY_BUFFER_STATE yy_scan_buffer(char *str, int i);
|
||||||
|
extern YY_BUFFER_STATE yy_scan_string(char *str);
|
||||||
|
extern void yy_delete_buffer(YY_BUFFER_STATE buffer);
|
||||||
|
extern FILE *yyin;
|
||||||
|
extern int yylineno;
|
||||||
|
|
||||||
|
UTEST_MAIN();
|
||||||
|
|
||||||
|
|
||||||
|
UTEST(parser, math) {
|
||||||
|
// Must include the null character to terminate input
|
||||||
|
char string[] = "1+8/4-3;\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, missing_semi_colon) {
|
||||||
|
// Must include the null character to terminate input
|
||||||
|
char string[] = "1+8/4-3\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, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
UTEST(parser, sample) {
|
||||||
|
// Read sample file as input
|
||||||
|
yyin = fopen("samples/program.c", "r");
|
||||||
|
yyrestart(yyin);
|
||||||
|
ASSERT_TRUE(yyin);
|
||||||
|
|
||||||
|
yylineno = 1;
|
||||||
|
int result = yyparse();
|
||||||
|
|
||||||
|
// Assert the result to test correctness
|
||||||
|
ASSERT_EQ(result, 0);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,82 @@
|
||||||
|
%{
|
||||||
|
#define YYDEBUG 1
|
||||||
|
#include <stdio.h>
|
||||||
|
extern int yylineno;
|
||||||
|
void yyerror(const char*);
|
||||||
|
int yylex();
|
||||||
|
%}
|
||||||
|
|
||||||
|
%debug
|
||||||
|
%define parse.error detailed
|
||||||
|
|
||||||
|
%token TOKEN_EOF
|
||||||
|
%token TOKEN_IDENTIFICATION
|
||||||
|
%token TOKEN_KEYWORD_DIVISION
|
||||||
|
%token TOKEN_KEYWORD_DATA
|
||||||
|
%token TOKEN_KEYWORD_SECTION
|
||||||
|
%token TOKEN_PROGRAM_ID
|
||||||
|
%token TOKEN_WORKING_STORAGE
|
||||||
|
%token TOKEN_PROCEDURE
|
||||||
|
%token TOKEN_STOP
|
||||||
|
%token TOKEN_RUN
|
||||||
|
%token TOKEN_MOVE
|
||||||
|
%token TOKEN_KEYWORD_TO
|
||||||
|
%token TOKEN_PERFORM
|
||||||
|
%token TOKEN_VARYING
|
||||||
|
%token TOKEN_KEYWORD_FROM
|
||||||
|
%token TOKEN_KEYWORD_BY
|
||||||
|
%token TOKEN_UNTIL
|
||||||
|
%token TOKEN_END_PERFORM
|
||||||
|
%token TOKEN_IF
|
||||||
|
%token TOKEN_END_IF
|
||||||
|
%token TOKEN_SPACE
|
||||||
|
%token TOKEN_KEYWORD_OCCURS
|
||||||
|
%token TOKEN_KEYWORD_VALUE
|
||||||
|
%token TOKEN_KEYWORD_COMPUTE
|
||||||
|
%token TOKEN_KEYWORD_FUNCTION
|
||||||
|
%token TOKEN_IDENT
|
||||||
|
%token TOKEN_STRING
|
||||||
|
%token TOKEN_INTEGER
|
||||||
|
%token TOKEN_PICTURE
|
||||||
|
%token TOKEN_ALPHANUMERIC
|
||||||
|
%token TOKEN_NUMERIC
|
||||||
|
%token TOKEN_SIGNED_NUMERIC
|
||||||
|
%token TOKEN_IMPLIED_DECIMAL
|
||||||
|
%token TOKEN_COMPUTATION_LEVEL_0
|
||||||
|
%token TOKEN_COMPUTATION_LEVEL_1
|
||||||
|
%token TOKEN_COMPUTATION_LEVEL_2
|
||||||
|
%token TOKEN_COMPUTATION_LEVEL_3
|
||||||
|
%token TOKEN_LEFT_PARENTHESIS
|
||||||
|
%token TOKEN_RIGHT_PARENTHESIS
|
||||||
|
%token TOKEN_DOT
|
||||||
|
%token TOKEN_COMMENT
|
||||||
|
%token TOKEN_ADD
|
||||||
|
%token TOKEN_SUB
|
||||||
|
%token TOKEN_MULTIPLY
|
||||||
|
%token TOKEN_DIVIDE
|
||||||
|
%token TOKEN_EQUAL
|
||||||
|
%token TOKEN_GREATER_THAN
|
||||||
|
%token TOKEN_LESS_THAN
|
||||||
|
%token TOKEN_EXPONENTIAL
|
||||||
|
|
||||||
|
%%
|
||||||
|
program : expr TOKEN_SEMI;
|
||||||
|
|
||||||
|
expr : expr TOKEN_PLUS term
|
||||||
|
| expr TOKEN_MINUS term
|
||||||
|
| term
|
||||||
|
;
|
||||||
|
|
||||||
|
term : term TOKEN_MUL factor
|
||||||
|
| term TOKEN_DIV factor
|
||||||
|
| factor
|
||||||
|
;
|
||||||
|
|
||||||
|
factor: TOKEN_MINUS factor
|
||||||
|
| TOKEN_LPAREN expr TOKEN_RPAREN
|
||||||
|
| TOKEN_INT
|
||||||
|
;
|
||||||
|
%%
|
||||||
|
void yyerror(const char* msg) {
|
||||||
|
fprintf(stderr, "Error | Line: %d\n%s\n",yylineno,msg);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
IDENTIFICATION DIVISION.
|
||||||
|
PROGRAM-ID. HELLO-WORLD.
|
||||||
|
PROCEDURE DIVISION.
|
||||||
|
DISPLAY 'Hello World!'
|
||||||
|
STOP RUN.
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
*> 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.
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
%{
|
||||||
|
#include "token.h"
|
||||||
|
%}
|
||||||
|
|
||||||
|
%option nounput
|
||||||
|
%option noinput
|
||||||
|
%option yylineno
|
||||||
|
|
||||||
|
DIGIT [0-9]
|
||||||
|
LETTER [a-zA-Z]
|
||||||
|
|
||||||
|
%%
|
||||||
|
(" "|\t|\n) /* skip whitespace */
|
||||||
|
\+ { return TOKEN_PLUS; }
|
||||||
|
\- { return TOKEN_MINUS; }
|
||||||
|
\* { return TOKEN_MUL; }
|
||||||
|
\/ { return TOKEN_DIV; }
|
||||||
|
\( { return TOKEN_LPAREN; }
|
||||||
|
\) { return TOKEN_RPAREN; }
|
||||||
|
\; { return TOKEN_SEMI; }
|
||||||
|
{DIGIT}+ { return TOKEN_INT; }
|
||||||
|
. { return TOKEN_ERROR; }
|
||||||
|
%%
|
||||||
|
|
||||||
|
int yywrap() { return 1; }
|
||||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue