update lab-5 to use the correct files

This commit is contained in:
vel 2024-11-10 17:11:28 -08:00
parent ff8119ee56
commit 282aeafa54
Signed by: velvox
GPG Key ID: 59D9762F674151DF
21 changed files with 336 additions and 254 deletions

View File

@ -1,189 +1,172 @@
%{
/* #define YYDEBUG 1
Declare token types at the top of the bison file, #include <stdio.h>
causing them to be automatically generated in parser.tab.h extern int yylineno;
for use by scanner.c. void yyerror(const char*);
*/ int yylex();
%}
%debug %debug
%define parse.error detailed %define parse.error detailed
%token TOKEN_ASSIGNMENT %token TOKEN_EOF
%token TOKEN_COMMA %token TOKEN_KEYWORD_IDENTIFICATION
%token TOKEN_DIV %token TOKEN_KEYWORD_DIVISION
%token TOKEN_EQUAL_EQUAL %token TOKEN_KEYWORD_DATA
%token TOKEN_GREATER_THAN %token TOKEN_KEYWORD_SECTION
%token TOKEN_GREATER_THAN_OR_EQUAL %token TOKEN_PROGRAM_ID
%token TOKEN_ID %token TOKEN_WORKING_STORAGE
%token TOKEN_INT %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_ELSE_IF
%token TOKEN_ELSE
%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_INTEGER
%token TOKEN_KEYWORD_ENDIF %token TOKEN_PICTURE
%token TOKEN_KEYWORD_IF %token TOKEN_ALPHANUMERIC
%token TOKEN_KEYWORD_PRINT %token TOKEN_NUMERIC
%token TOKEN_KEYWORD_THEN %token TOKEN_SIGNED_NUMERIC
%token TOKEN_LBRACKET %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_LESS_THAN
%token TOKEN_LESS_THAN_OR_EQUAL %token TOKEN_EXPONENTIAL
%token TOKEN_LPAREN %token TOKEN_DISPLAY
%token TOKEN_MINUS
%token TOKEN_MUL
%token TOKEN_NOT_EQUAL
%token TOKEN_PLUS
%token TOKEN_RBRACKET
%token TOKEN_RPAREN
%token TOKEN_SEMI
%union {
struct stmt *stmt;
struct expr *expr;
struct decl *decl;
};
%type <stmt> program statement_list statement print_statement assignment_statement if_statement block
%type <expr> expr term factor name sum array_subscript star_expr
%type <decl> declaration
%{
#define YYDEBUG 1
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "expr.h"
/*
Clunky: Manually declare the interface to the scanner generated by flex.
*/
extern int yylineno;
extern char *yytext;
extern int yylex();
extern void yyerror(const char*);
/*
Clunky: Keep the final result of the parse in a global variable,
so that it can be retrieved by main().
*/
struct stmt * parser_result = 0;
%}
%% %%
file : statements
statements : statements statement
| statement
;
statement : section
| sect_data
| simple_stmt
| data_space
| data_declaration
;
section : type TOKEN_KEYWORD_DIVISION TOKEN_DOT
| type TOKEN_RUN TOKEN_DOT
;
sect_data : TOKEN_PROGRAM_ID TOKEN_DOT TOKEN_IDENT TOKEN_DOT
;
type : TOKEN_KEYWORD_IDENTIFICATION
| TOKEN_PROCEDURE
| TOKEN_STOP
| TOKEN_KEYWORD_DATA
;
simple_stmt : cbl_function
| cbl_function op_parms
| cbl_function assignment_stmt
| cbl_function op_parms assignment_stmt
| if_branch
| perform_stmt
;
;
assignment_stmt : TOKEN_EQUAL ext_function
| TOKEN_EQUAL function
| TOKEN_KEYWORD_TO op_parms
;
op_parms : op_parms TOKEN_ADD op_parms
| op_parms TOKEN_SUB op_parms
| op_parms TOKEN_MULTIPLY op_parms
| op_parms TOKEN_DIVIDE op_parms
| op_parms TOKEN_EXPONENTIAL op_parms
| op_parms TOKEN_LESS_THAN op_parms
| op_parms TOKEN_GREATER_THAN op_parms
| op_parms TOKEN_EQUAL op_parms
| TOKEN_SUB op_parms
| TOKEN_LEFT_PARENTHESIS op_parms TOKEN_RIGHT_PARENTHESIS
| TOKEN_IDENT
| TOKEN_INTEGER
| TOKEN_STRING
| TOKEN_SPACE
| op_parms op_parms
;
function : op_parms
;
ext_function : TOKEN_KEYWORD_FUNCTION TOKEN_IDENT TOKEN_LEFT_PARENTHESIS TOKEN_IDENT TOKEN_RIGHT_PARENTHESIS
;
cbl_function : TOKEN_DISPLAY
| TOKEN_MOVE
| TOKEN_KEYWORD_COMPUTE
| TOKEN_PERFORM
;
if_branch : TOKEN_IF op_parms
| TOKEN_ELSE_IF op_parms
| TOKEN_ELSE statement
| TOKEN_END_IF
;
perform_stmt : TOKEN_PERFORM TOKEN_VARYING TOKEN_IDENT TOKEN_KEYWORD_FROM TOKEN_INTEGER TOKEN_KEYWORD_BY TOKEN_INTEGER TOKEN_UNTIL op_parms
| TOKEN_END_PERFORM
;
data_space : TOKEN_WORKING_STORAGE
| TOKEN_KEYWORD_SECTION
| TOKEN_DOT
;
data_category : TOKEN_ALPHANUMERIC
| TOKEN_NUMERIC
| TOKEN_SIGNED_NUMERIC
| TOKEN_IMPLIED_DECIMAL
;
categry_contain : TOKEN_LEFT_PARENTHESIS TOKEN_INTEGER TOKEN_RIGHT_PARENTHESIS
| TOKEN_LEFT_PARENTHESIS TOKEN_IDENT TOKEN_RIGHT_PARENTHESIS
;
complete_category: complete_category complete_category
| data_category categry_contain
;
data_clause : TOKEN_COMPUTATION_LEVEL_0
| TOKEN_COMPUTATION_LEVEL_1
| TOKEN_COMPUTATION_LEVEL_2
| TOKEN_COMPUTATION_LEVEL_3
| TOKEN_KEYWORD_VALUE
| TOKEN_KEYWORD_OCCURS
;
full_data_clause: data_clause data_clause
| data_clause
;
simple_decl : TOKEN_INTEGER TOKEN_IDENT TOKEN_DOT
;
full_decl : TOKEN_INTEGER TOKEN_IDENT TOKEN_PICTURE complete_category TOKEN_DOT
| TOKEN_INTEGER TOKEN_IDENT TOKEN_PICTURE complete_category full_data_clause TOKEN_DOT
| TOKEN_INTEGER TOKEN_IDENT TOKEN_PICTURE complete_category full_data_clause TOKEN_INTEGER TOKEN_DOT
;
data_declaration: simple_decl
| full_decl
;
/* Here is the grammar: program is the start symbol. */
program : statement_list
{ parser_result = $1; return 0; }
;
statement_list : statement
{ $$ = $1; }
| statement statement_list
{ $$ = $1; $1->next = $2; }
;
block : statement
{ $$ = $1; }
| statement block
{ $$ = $1; $1->next = $2; }
;
statement : assignment_statement TOKEN_SEMI
{ $$ = $1; }
| print_statement TOKEN_SEMI
{ $$ = $1; }
| if_statement
{ $$ = $1; }
;
assignment_statement : declaration
{ $$ = stmt_create(STMT_DECL,$1,0,0,0,0,0,0); }
;
print_statement : TOKEN_KEYWORD_PRINT expr
{ $$ = stmt_create(STMT_PRINT,0,0,$2,0,0,0,0); }
;
if_statement : TOKEN_KEYWORD_IF expr TOKEN_KEYWORD_THEN block TOKEN_KEYWORD_ENDIF
{ $$ = stmt_create(STMT_IF,0,0,$2,0,$4,0,0); }
;
declaration : name TOKEN_ASSIGNMENT expr
{ $$ = decl_create($1,0,$3,0,0); }
| array_subscript TOKEN_ASSIGNMENT expr
{ $$ = decl_create($1,0,$3,0,0); }
;
name : TOKEN_ID
{ $$ = expr_create_name(yytext); }
;
array_subscript : name TOKEN_LBRACKET expr TOKEN_RBRACKET
{ $$ = expr_create(EXPR_SUBSCRIPT,$1,$3); }
;
star_expr : expr
{ $$ = expr_create(EXPR_ARRAY,$1,0); }
| expr TOKEN_COMMA star_expr
{ $$ = expr_create(EXPR_ARRAY,$1,$3); }
;
expr : sum TOKEN_LESS_THAN sum
{ $$ = expr_create(EXPR_LESS_THAN,$1,$3); }
| sum TOKEN_LESS_THAN_OR_EQUAL sum
{ $$ = expr_create(EXPR_LESS_THAN_OR_EQUAL,$1,$3); }
| sum TOKEN_GREATER_THAN sum
{ $$ = expr_create(EXPR_GREATER_THAN,$1,$3); }
| sum TOKEN_GREATER_THAN_OR_EQUAL sum
{ $$ = expr_create(EXPR_GREATER_THAN_OR_EQUAL,$1,$3); }
| sum TOKEN_EQUAL_EQUAL sum
{ $$ = expr_create(EXPR_EQUAL_EQUAL,$1,$3); }
| sum TOKEN_NOT_EQUAL sum
{ $$ = expr_create(EXPR_NOT_EQUAL,$1,$3); }
| sum
{ $$ = $1; }
;
sum : sum TOKEN_PLUS term
{ $$ = expr_create(EXPR_ADD,$1,$3); }
| sum TOKEN_MINUS term
{ $$ = expr_create(EXPR_SUBTRACT,$1,$3); }
| term
{ $$ = $1; }
;
term : term TOKEN_MUL factor
{ $$ = expr_create(EXPR_MULTIPLY,$1,$3); }
| term TOKEN_DIV factor
{ $$ = expr_create(EXPR_DIVIDE,$1,$3); }
| factor
{ $$ = $1; }
;
factor : TOKEN_LPAREN expr TOKEN_RPAREN
{ $$ = $2; }
| TOKEN_MINUS factor
{ $$ = expr_create(EXPR_SUBTRACT,expr_create_integer_literal(0),$2); }
| TOKEN_INT
{ $$ = expr_create_integer_literal(atoi(yytext)); }
| TOKEN_LBRACKET star_expr TOKEN_RBRACKET
{ $$ = $2; }
| array_subscript
{ $$ = $1; }
| name
{ $$ = $1; }
;
%% %%
/*
This function will be called by bison if the parse should
encounter an error. In principle, "str" will contain something
useful. In practice, it often does not.
*/
void yyerror(const char* msg) { void yyerror(const char* msg) {
fprintf(stderr, "Error | Line: %d\n%s\n", yylineno, msg); fprintf(stderr, "Error | Line: %d\n%s\n",yylineno,msg);
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1 +0,0 @@
56

View File

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

View File

@ -0,0 +1,24 @@
IDENTIFICATION DIVISION.
PROGRAM-ID. variables.
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.
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.
DISPLAY 'Hello World!'
STOP RUN.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1 +0,0 @@
2024

View File

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

View File

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

View File

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

View File

@ -1,47 +1,64 @@
%{ %{
#include "parser.h" #include "token.h"
%} %}
NAME [a-zA-Z]([a-zA-Z0-9_-]*[a-zA-Z0-9])?
%option nounput DIGIT [0-9]+
%option noinput
%option noyywrap
%option yylineno
DIGIT [0-9]
LETTER [a-zA-Z_]
%% %%
[ \n\r\t]* /* skip whitespace */; (" "|\t|\n) /* skip whitespace */
"print" return TOKEN_KEYWORD_PRINT; \*>\ ?.*
"if" return TOKEN_KEYWORD_IF; IDENTIFICATION { return TOKEN_KEYWORD_IDENTIFICATION; }
"then" return TOKEN_KEYWORD_THEN; DIVISION { return TOKEN_KEYWORD_DIVISION; }
"endif" return TOKEN_KEYWORD_ENDIF; PROGRAM-ID { return TOKEN_PROGRAM_ID; }
{DIGIT}+ return TOKEN_INT; PROCEDURE { return TOKEN_PROCEDURE; }
{LETTER}+ return TOKEN_ID; DATA { return TOKEN_KEYWORD_DATA; }
"," return TOKEN_COMMA; SECTION { return TOKEN_KEYWORD_SECTION; }
"]" return TOKEN_RBRACKET; WORKING-STORAGE { return TOKEN_WORKING_STORAGE; }
"[" return TOKEN_LBRACKET; DISPLAY { return TOKEN_DISPLAY; }
"==" return TOKEN_EQUAL_EQUAL; STOP { return TOKEN_STOP; }
"!=" return TOKEN_NOT_EQUAL; RUN { return TOKEN_RUN; }
"<=" return TOKEN_LESS_THAN_OR_EQUAL; MOVE { return TOKEN_MOVE; }
">=" return TOKEN_GREATER_THAN_OR_EQUAL; TO { return TOKEN_KEYWORD_TO; }
"<" return TOKEN_LESS_THAN; VARYING { return TOKEN_VARYING; }
">" return TOKEN_GREATER_THAN; FROM { return TOKEN_KEYWORD_FROM; }
\= return TOKEN_ASSIGNMENT; BY { return TOKEN_KEYWORD_BY; }
\* return TOKEN_MUL; UNTIL { return TOKEN_UNTIL; }
\+ return TOKEN_PLUS; PERFORM { return TOKEN_PERFORM; }
\- return TOKEN_MINUS; END-PERFORM { return TOKEN_END_PERFORM; }
\/ return TOKEN_DIV; IF { return TOKEN_IF; }
\( return TOKEN_LPAREN; END-IF { return TOKEN_END_IF; }
\) return TOKEN_RPAREN; SPACE { return TOKEN_SPACE; }
\; return TOKEN_SEMI; PIC { return TOKEN_PICTURE; }
. { printf("scan error: bad token: %c\n", yytext[0]); } OCCURS { return TOKEN_KEYWORD_OCCURS; }
%% VALUE { return TOKEN_KEYWORD_VALUE; }
COMPUTE { return TOKEN_KEYWORD_COMPUTE; }
FUNCTION { return TOKEN_KEYWORD_FUNCTION; }
X { return TOKEN_ALPHANUMERIC; }
S9 { return TOKEN_SIGNED_NUMERIC; }
9 { return TOKEN_NUMERIC; }
V9 { return TOKEN_IMPLIED_DECIMAL; }
COMP { return TOKEN_COMPUTATION_LEVEL_0; }
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; }
flex calls yywrap() whenever it reaches the end of the current file. {NAME} { return TOKEN_IDENT; }
If yywrap returns false to indicate the end of the program. \+ { return TOKEN_ADD; }
It could alternatively open up another file and return true, \- { return TOKEN_SUB; }
so that flex would keep going. \*\* { return TOKEN_EXPONENTIAL; }
*/ \* { return TOKEN_MULTIPLY; }
\/ { return TOKEN_DIVIDE; }
\> { return TOKEN_GREATER_THAN; }
\< { return TOKEN_LESS_THAN; }
\= { return TOKEN_EQUAL;}
"\""[^"]*"\"" { return TOKEN_STRING; }
"\'"[^']*"\'" { return TOKEN_STRING; }
"(" { return TOKEN_LEFT_PARENTHESIS; }
")" { return TOKEN_RIGHT_PARENTHESIS; }
\. { return TOKEN_DOT; }
%%
int yywrap() { return 1; }