hello world partially parses

This commit is contained in:
vel 2024-11-13 22:42:07 -08:00
parent 5d03635b93
commit a3441f39c3
Signed by: velvox
GPG Key ID: 59D9762F674151DF
6 changed files with 156 additions and 20 deletions

View File

@ -2,17 +2,20 @@
# The top level rule indicates how to link everything together into main # The top level rule indicates how to link everything together into main
main: main.o symbol_map.o expr.o scanner.o parser.o main: main.o symbol_map.o expr.o scanner.o parser.o
gcc main.o symbol_map.o expr.o scanner.o parser.o -o interpreter.out -lm gcc -g3 main.o symbol_map.o expr.o scanner.o parser.o -o interpreter.out -lm
test: main_test.o symbol_map.o expr.o scanner.o parser.o test: main_test.o symbol_map.o expr.o scanner.o parser.o
gcc main_test.o symbol_map.o expr.o scanner.o parser.o -o interpreter_test.out -lm gcc main_test.o symbol_map.o expr.o scanner.o parser.o -o interpreter_test.out -lm
parser_test: parser_test.o symbol_map.o expr.o scanner.o parser.o
gcc parser_test.o symbol_map.o expr.o scanner.o parser.o -o parser_test.out -lm
# This pattern indicates that any .o file depends # This pattern indicates that any .o file depends
# upon the .c file of the same name, and all of the .h files. # 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. # So, if a .o file is needed, it is built automatically.
%.o: %.c *.h %.o: %.c *.h
gcc -Wall -c $< -o $@ gcc -g3 -Wall -c $< -o $@
# Only the files generated by flex and bison need explicit rules. # Only the files generated by flex and bison need explicit rules.

View File

@ -123,6 +123,8 @@ void stmt_print(struct stmt *s) {
if (!s) if (!s)
return; return;
printf("stmt_print: %d\n", s->kind);
switch (s->kind) { switch (s->kind) {
case STMT_DECL: case STMT_DECL:
decl_print(s->decl); decl_print(s->decl);
@ -146,6 +148,12 @@ void stmt_print(struct stmt *s) {
case STMT_BLOCK: case STMT_BLOCK:
stmt_print(s->body); stmt_print(s->body);
break; break;
case STMT_SECTION:
printf("section\n");
printf("body: %p\n", s->body);
printf("expr: %p\n", s->expr);
printf("next: %p\n", s->next);
break;
} }
stmt_print(s->next); stmt_print(s->next);
@ -271,6 +279,8 @@ void stmt_evaluate(struct stmt *s) {
case STMT_BLOCK: case STMT_BLOCK:
stmt_evaluate(s->body); stmt_evaluate(s->body);
break; break;
case STMT_SECTION:
break;
} }
stmt_evaluate(s->next); stmt_evaluate(s->next);

View File

@ -60,7 +60,7 @@ struct decl {
struct decl *next; struct decl *next;
}; };
typedef enum { STMT_BLOCK, STMT_DECL, STMT_EXPR, STMT_IF, STMT_PRINT } stmt_t; typedef enum { STMT_BLOCK, STMT_DECL, STMT_EXPR, STMT_IF, STMT_PRINT, STMT_SECTION } stmt_t;
struct stmt { struct stmt {
stmt_t kind; stmt_t kind;

View File

@ -19,7 +19,6 @@ Clunky: Manually declare the interface to the scanner generated by flex.
extern char *yytext; extern char *yytext;
extern int yylex(); extern int yylex();
// void yyerror(struct stmt *parser_result, const char*);
void yyerror(const char*); void yyerror(const char*);
extern int yylineno; extern int yylineno;
@ -28,8 +27,6 @@ struct stmt *parser_result = 0;
%} %}
// %parse-param {struct stmt *parser_result}
%debug %debug
%define parse.error detailed %define parse.error detailed
@ -86,30 +83,37 @@ struct stmt *parser_result = 0;
%token TOKEN_DISPLAY %token TOKEN_DISPLAY
%% %%
file : statement_list file : statement_list
{parser_result = $1; return 0;} {parser_result = $1; return 0;}
; ;
statement_list : statement_list statement statement_list : statement statement_list
{ $$ = $1; $1->next = $2; } { $$ = $1; $1->next = $2; }
| statement | statement
{ $$ = $1; } { $$ = $1; }
; ;
statement : section statement : section
{$$ = $1;}
| sect_data | sect_data
{$$ = $1;}
| simple_stmt | simple_stmt
{$$ = stmt_create(STMT_BLOCK, NULL, NULL, NULL, NULL, $1, NULL, NULL);} {$$ = stmt_create(STMT_BLOCK, NULL, NULL, NULL, NULL, $1, NULL, NULL);}
| data_space | data_space
{$$ = stmt_create(STMT_SECTION, NULL, NULL, NULL, NULL, NULL, NULL, NULL);}
| data_declaration | data_declaration
{$$ = stmt_create(STMT_BLOCK, NULL, NULL, NULL, NULL, $1, NULL, NULL);}
; ;
section : type TOKEN_KEYWORD_DIVISION TOKEN_DOT section : type TOKEN_KEYWORD_DIVISION TOKEN_DOT
| type TOKEN_RUN TOKEN_DOT {$$ = stmt_create(STMT_SECTION, NULL, NULL, NULL, NULL, NULL, NULL, NULL);}
| TOKEN_STOP TOKEN_RUN TOKEN_DOT
{$$ = stmt_create(STMT_SECTION, NULL, NULL, NULL, NULL, NULL, NULL, NULL);}
; ;
sect_data : TOKEN_PROGRAM_ID TOKEN_DOT TOKEN_IDENT TOKEN_DOT sect_data : TOKEN_PROGRAM_ID TOKEN_DOT TOKEN_IDENT TOKEN_DOT
{$$ = stmt_create(STMT_SECTION, NULL, NULL, NULL, NULL, NULL, NULL, NULL);}
; ;
type : TOKEN_KEYWORD_IDENTIFICATION type : TOKEN_KEYWORD_IDENTIFICATION
| TOKEN_PROCEDURE | TOKEN_PROCEDURE
| TOKEN_STOP
| TOKEN_KEYWORD_DATA | TOKEN_KEYWORD_DATA
; ;
simple_stmt : cbl_func_stmt simple_stmt : cbl_func_stmt
@ -163,9 +167,9 @@ booleanexpr : mathmaticalexpr TOKEN_LESS_THAN term
type_expr : TOKEN_IDENT type_expr : TOKEN_IDENT
{$$ = expr_create_name(yytext);} {$$ = expr_create_name(yytext);}
| TOKEN_INTEGER | TOKEN_INTEGER
{$$ = expr_create_integer_literal(yytext);} {$$ = expr_create_integer_literal(atoi(yytext));}
| TOKEN_STRING | TOKEN_STRING
{$$ = expr_create_string_literal(atoi(yytext));} {$$ = expr_create_string_literal(yytext);}
| TOKEN_SPACE | TOKEN_SPACE
{$$ = expr_create_integer_literal(0);} {$$ = expr_create_integer_literal(0);}
| TOKEN_SUB TOKEN_IDENT | TOKEN_SUB TOKEN_IDENT
@ -225,10 +229,6 @@ data_declaration: simple_decl
| complex_decl | complex_decl
; ;
%% %%
// void yyerror(struct stmt *parser_result, const char* msg) {
// fprintf(stderr, "Error | Line: %d\n%s\n",yylineno,msg);
// }
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);
} }

123
lab-5/parser_test.c Normal file
View File

@ -0,0 +1,123 @@
// https://github.com/sheredom/utest.h/blob/master/utest.h
#include "utest.h"
#include "expr.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[] = "COMPUTE A = (b ** 2) - (4 * a * c)\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, hello) {
// Read sample file as input
yyin = fopen("samples/hello-world.cbl", "r");
yyrestart(yyin);
ASSERT_TRUE(yyin);
yylineno = 1;
int result = yyparse();
// Assert the result to test correctness
ASSERT_EQ(result, 0);
}
UTEST(parser, print) {
// Must include the null character to terminate input
char string[] = "DISPLAY 'Hello World!'\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, branching) {
// Must include the null character to terminate input
char string[] = "IF A > B DISPLAY 'A is greater than B' ELSE DISPLAY 'B is greater than 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\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, assignment) {
char string[] = "MOVE I TO A(I) MOVE 1 TO I COMPUTE discriminant = (b ** 2) - (4 * a * c)\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);
}
UTEST(parser, quadratic) {
// Read sample file as input
yyin = fopen("samples/quadratic-snippet.cbl", "r");
yyrestart(yyin);
ASSERT_TRUE(yyin);
yylineno = 1;
int result = yyparse();
// Assert the result to test correctness
ASSERT_EQ(result, 0);
}