From 4e7e1f43f5e17ad4425b3bd907505419d37d093d Mon Sep 17 00:00:00 2001 From: Preston Carman Date: Fri, 8 Nov 2024 11:42:13 -0800 Subject: [PATCH 01/21] Updating testing to use fixtures --- lab-5/main_test.c | 149 ++++++++++++++++++---------------------------- lab-5/utest.h | 128 +++++++++++++++++++++++++++------------ 2 files changed, 148 insertions(+), 129 deletions(-) diff --git a/lab-5/main_test.c b/lab-5/main_test.c index d40e918..4b1ec9f 100644 --- a/lab-5/main_test.c +++ b/lab-5/main_test.c @@ -19,20 +19,45 @@ extern int yylineno; UTEST_MAIN(); -void read_file(const char *filename, char *expected_output) { - // Read the expected output from a file - FILE *expected_file = fopen(filename, "r"); - if (expected_file == NULL) { - perror("fopen"); - exit(EXIT_FAILURE); - } - size_t n = - fread(expected_output, 1, sizeof(expected_output) - 1, expected_file); - expected_output[n] = '\0'; - fclose(expected_file); +char* read_file_dynamic(const char* filename) { + FILE* file = fopen(filename, "r"); + if (file == NULL) { + perror("fopen"); + return NULL; + } + + // Seek to the end of the file to determine its size + fseek(file, 0, SEEK_END); + long file_size = ftell(file); + fseek(file, 0, SEEK_SET); + + // Allocate a buffer to hold the file contents + char* buffer = (char*)malloc(file_size + 1); + if (buffer == NULL) { + perror("malloc"); + fclose(file); + return NULL; + } + + // Read the entire file into the buffer + size_t read_size = fread(buffer, 1, file_size, file); + if (read_size != file_size) { + perror("fread"); + free(buffer); + fclose(file); + return NULL; + } + + // Null-terminate the buffer + buffer[file_size] = '\0'; + + fclose(file); + return buffer; } void redirect_stdout(const char *filename, int evalutate) { + fflush(stdout); + // Redirect stdout to a temporary file FILE *temp_file = fopen(filename, "w"); if (temp_file == NULL) { @@ -56,42 +81,18 @@ void redirect_stdout(const char *filename, int evalutate) { close(stdout_fd); } -UTEST(interpreter, print) { +struct InterpreterTestFile { + const char *evaluated_file; + const char *print_file; + const char *test_file; +}; - yyin = fopen("samples/multiple_statements.c", "r"); - yyrestart(yyin); - ASSERT_TRUE(yyin); - -// yylineno = 1; - yylineno = 1; - int result = yyparse(); - - if (result == 0) { - // Catch the standard output and compare with expected test result - redirect_stdout("test_print.txt", 0); - redirect_stdout("test_evaluate.txt", 1); - } - - // Assert the result to test correctness - ASSERT_EQ(result, 0); - - char actual_print[1024]; - read_file("test_print.txt", actual_print); - char expected_print[1024]; - read_file("samples/multiple_statements_print.txt", expected_print); - ASSERT_STREQ(actual_print, expected_print); - - char actual_evaluate[1024]; - read_file("test_evaluate.txt", actual_evaluate); - char expected_evaluate[1024]; - read_file("samples/multiple_statements_evaluate.txt", expected_evaluate); - ASSERT_STREQ(actual_evaluate, expected_evaluate); +UTEST_F_SETUP(InterpreterTestFile) { } - - -UTEST(interpreter, program) { - yyin = fopen("samples/program.c", "r"); +UTEST_F_TEARDOWN(InterpreterTestFile) { + // and also assert and expect in teardown! + yyin = fopen(utest_fixture->test_file, "r"); yyrestart(yyin); ASSERT_TRUE(yyin); @@ -107,55 +108,23 @@ UTEST(interpreter, program) { // Assert the result to test correctness ASSERT_EQ(result, 0); - char actual_print[1024]; - read_file("test_print.txt", actual_print); - char expected_print[1024]; - read_file("samples/program_print.txt", expected_print); + char *actual_print = read_file_dynamic("test_print.txt"); + char *expected_print = read_file_dynamic(utest_fixture->print_file); ASSERT_STREQ(actual_print, expected_print); - char actual_evaluate[1024]; - read_file("test_evaluate.txt", actual_evaluate); - char expected_evaluate[1024]; - read_file("samples/program_evaluate.txt", expected_evaluate); + char *actual_evaluate = read_file_dynamic("test_evaluate.txt"); + char *expected_evaluate = read_file_dynamic(utest_fixture->evaluated_file); ASSERT_STREQ(actual_evaluate, expected_evaluate); } -// UTEST(parser, missing_new_line) { -// // 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)); +UTEST_F(InterpreterTestFile, print) { + utest_fixture->test_file = "samples/multiple_statements.c"; + utest_fixture->print_file = "samples/multiple_statements_print.txt"; + utest_fixture->evaluated_file = "samples/multiple_statements_evaluate.txt"; +} -// yylineno = 1; -// int result = yyparse(); - -// yy_delete_buffer(buffer); - -// // Assert the result to test correctness -// ASSERT_EQ(result, 1); -// } - -// UTEST(parser, hello_world) { -// // Read sample file as input -// yyin = fopen("samples/hello.py", "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.py", "r"); -// yyrestart(yyin); -// ASSERT_TRUE(yyin); - -// yylineno = 1; -// int result = yyparse(); - -// // Assert the result to test correctness -// ASSERT_EQ(result, 0); -// } +UTEST_F(InterpreterTestFile, program_file) { + utest_fixture->test_file = "samples/program.c"; + utest_fixture->print_file = "samples/program_print.txt"; + utest_fixture->evaluated_file = "samples/program_evaluate.txt"; +} diff --git a/lab-5/utest.h b/lab-5/utest.h index 8767600..82de631 100644 --- a/lab-5/utest.h +++ b/lab-5/utest.h @@ -255,8 +255,8 @@ UTEST_C_FUNC __declspec(dllimport) int __stdcall QueryPerformanceFrequency( static void __cdecl f(void); \ UTEST_INITIALIZER_BEGIN_DISABLE_WARNINGS \ __pragma(comment(linker, "/include:" UTEST_SYMBOL_PREFIX #f "_")) \ - UTEST_C_FUNC __declspec(allocate(".CRT$XCU")) void(__cdecl * \ - f##_)(void) = f; \ + UTEST_C_FUNC \ + __declspec(allocate(".CRT$XCU")) void(__cdecl * f##_)(void) = f; \ UTEST_INITIALIZER_END_DISABLE_WARNINGS \ static void __cdecl f(void) #else @@ -321,22 +321,32 @@ static UTEST_INLINE void *utest_realloc(void *const pointer, size_t new_size) { void *const new_pointer = realloc(pointer, new_size); if (UTEST_NULL == new_pointer) { - free(new_pointer); + free(pointer); } return new_pointer; } +// Prevent 64-bit integer overflow when computing a timestamp by using a trick +// from Sokol: +// https://github.com/floooh/sokol/blob/189843bf4f86969ca4cc4b6d94e793a37c5128a7/sokol_time.h#L204 +static UTEST_INLINE utest_int64_t utest_mul_div(const utest_int64_t value, + const utest_int64_t numer, + const utest_int64_t denom) { + const utest_int64_t q = value / denom; + const utest_int64_t r = value % denom; + return q * numer + r * numer / denom; +} + static UTEST_INLINE utest_int64_t utest_ns(void) { #if defined(_MSC_VER) || defined(__MINGW64__) || defined(__MINGW32__) utest_large_integer counter; utest_large_integer frequency; QueryPerformanceCounter(&counter); QueryPerformanceFrequency(&frequency); - return UTEST_CAST(utest_int64_t, - (counter.QuadPart * 1000000000) / frequency.QuadPart); + return utest_mul_div(counter.QuadPart, 1000000000, frequency.QuadPart); #elif defined(__linux__) && defined(__STRICT_ANSI__) - return UTEST_CAST(utest_int64_t, clock()) * 1000000000 / CLOCKS_PER_SEC; + return utest_mul_div(clock(), 1000000000, CLOCKS_PER_SEC); #elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || \ defined(__NetBSD__) || defined(__DragonFly__) || defined(__sun__) || \ defined(__HAIKU__) @@ -447,6 +457,15 @@ struct utest_type_deducer final { static void _(const T t); }; +template <> struct utest_type_deducer { + static void _(const char c) { + if (std::is_signed::value) { + UTEST_PRINTF("%d", static_cast(c)); + } else { + UTEST_PRINTF("%u", static_cast(c)); + } + } +}; template <> struct utest_type_deducer { static void _(const signed char c) { UTEST_PRINTF("%d", static_cast(c)); @@ -512,6 +531,10 @@ template <> struct utest_type_deducer { static void _(const unsigned long long i) { UTEST_PRINTF("%llu", i); } }; +template <> struct utest_type_deducer { + static void _(const bool i) { UTEST_PRINTF(i ? "true" : "false"); } +}; + template struct utest_type_deducer { static void _(const T *t) { UTEST_PRINTF("%p", static_cast(const_cast(t))); @@ -528,6 +551,12 @@ template struct utest_type_deducer { } }; +template <> struct utest_type_deducer { + static void _(std::nullptr_t t) { + UTEST_PRINTF("%p", static_cast(t)); + } +}; + template UTEST_WEAK UTEST_OVERLOADABLE void utest_type_printer(const T t) { utest_type_deducer::_(t); @@ -626,24 +655,23 @@ utest_type_printer(long long unsigned int i) { !(defined(__MINGW32__) || defined(__MINGW64__)) || \ defined(__TINYC__) #define utest_type_printer(val) \ - UTEST_PRINTF(_Generic((val), signed char \ - : "%d", unsigned char \ - : "%u", short \ - : "%d", unsigned short \ - : "%u", int \ - : "%d", long \ - : "%ld", long long \ - : "%lld", unsigned \ - : "%u", unsigned long \ - : "%lu", unsigned long long \ - : "%llu", float \ - : "%f", double \ - : "%f", long double \ - : "%Lf", default \ - : _Generic((val - val), ptrdiff_t \ - : "%p", default \ - : "undef")), \ - (val)) + UTEST_PRINTF( \ + _Generic((val), \ + signed char: "%d", \ + unsigned char: "%u", \ + short: "%d", \ + unsigned short: "%u", \ + int: "%d", \ + long: "%ld", \ + long long: "%lld", \ + unsigned: "%u", \ + unsigned long: "%lu", \ + unsigned long long: "%llu", \ + float: "%f", \ + double: "%f", \ + long double: "%Lf", \ + default: _Generic((val - val), ptrdiff_t: "%p", default: "undef")), \ + (val)) #else /* we don't have the ability to print the values we got, so we create a macro @@ -724,10 +752,12 @@ utest_strncpy_gcc(char *const dst, const char *const src, const size_t size) { UTEST_AUTO(x) xEval = (x); \ UTEST_AUTO(y) yEval = (y); \ if (!((xEval)cond(yEval))) { \ + const char *const xAsString = #x; \ + const char *const yAsString = #y; \ _Pragma("clang diagnostic pop") \ UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__); \ UTEST_PRINTF(" Expected : ("); \ - UTEST_PRINTF(#x ") " #cond " (" #y); \ + UTEST_PRINTF("%s) " #cond " (%s", xAsString, yAsString); \ UTEST_PRINTF(")\n"); \ UTEST_PRINTF(" Actual : "); \ utest_type_printer(xEval); \ @@ -751,9 +781,11 @@ utest_strncpy_gcc(char *const dst, const char *const src, const size_t size) { UTEST_AUTO(x) xEval = (x); \ UTEST_AUTO(y) yEval = (y); \ if (!((xEval)cond(yEval))) { \ + const char *const xAsString = #x; \ + const char *const yAsString = #y; \ UTEST_PRINTF("%s:%i: Failure\n", __FILE__, __LINE__); \ UTEST_PRINTF(" Expected : ("); \ - UTEST_PRINTF(#x ") " #cond " (" #y); \ + UTEST_PRINTF("%s) " #cond " (%s", xAsString, yAsString); \ UTEST_PRINTF(")\n"); \ UTEST_PRINTF(" Actual : "); \ utest_type_printer(xEval); \ @@ -1130,7 +1162,7 @@ utest_strncpy_gcc(char *const dst, const char *const src, const size_t size) { } \ UTEST_INITIALIZER(utest_register_##SET##_##NAME) { \ const size_t index = utest_state.tests_length++; \ - const char *name_part = #SET "." #NAME; \ + const char name_part[] = #SET "." #NAME; \ const size_t name_size = strlen(name_part) + 1; \ char *name = UTEST_PTR_CAST(char *, malloc(name_size)); \ utest_state.tests = UTEST_PTR_CAST( \ @@ -1138,13 +1170,19 @@ utest_strncpy_gcc(char *const dst, const char *const src, const size_t size) { utest_realloc(UTEST_PTR_CAST(void *, utest_state.tests), \ sizeof(struct utest_test_state_s) * \ utest_state.tests_length)); \ - if (utest_state.tests) { \ + if (utest_state.tests && name) { \ utest_state.tests[index].func = &utest_##SET##_##NAME; \ utest_state.tests[index].name = name; \ utest_state.tests[index].index = 0; \ UTEST_SNPRINTF(name, name_size, "%s", name_part); \ - } else if (name) { \ - free(name); \ + } else { \ + if (utest_state.tests) { \ + free(utest_state.tests); \ + utest_state.tests = NULL; \ + } \ + if (name) { \ + free(name); \ + } \ } \ } \ UTEST_SURPRESS_WARNINGS_END \ @@ -1178,7 +1216,7 @@ utest_strncpy_gcc(char *const dst, const char *const src, const size_t size) { } \ UTEST_INITIALIZER(utest_register_##FIXTURE##_##NAME) { \ const size_t index = utest_state.tests_length++; \ - const char *name_part = #FIXTURE "." #NAME; \ + const char name_part[] = #FIXTURE "." #NAME; \ const size_t name_size = strlen(name_part) + 1; \ char *name = UTEST_PTR_CAST(char *, malloc(name_size)); \ utest_state.tests = UTEST_PTR_CAST( \ @@ -1186,12 +1224,18 @@ utest_strncpy_gcc(char *const dst, const char *const src, const size_t size) { utest_realloc(UTEST_PTR_CAST(void *, utest_state.tests), \ sizeof(struct utest_test_state_s) * \ utest_state.tests_length)); \ - if (utest_state.tests) { \ + if (utest_state.tests && name) { \ utest_state.tests[index].func = &utest_f_##FIXTURE##_##NAME; \ utest_state.tests[index].name = name; \ UTEST_SNPRINTF(name, name_size, "%s", name_part); \ - } else if (name) { \ - free(name); \ + } else { \ + if (utest_state.tests) { \ + free(utest_state.tests); \ + utest_state.tests = NULL; \ + } \ + if (name) { \ + free(name); \ + } \ } \ } \ UTEST_SURPRESS_WARNINGS_END \ @@ -1226,7 +1270,7 @@ utest_strncpy_gcc(char *const dst, const char *const src, const size_t size) { utest_uint64_t iUp; \ for (i = 0; i < (INDEX); i++) { \ const size_t index = utest_state.tests_length++; \ - const char *name_part = #FIXTURE "." #NAME; \ + const char name_part[] = #FIXTURE "." #NAME; \ const size_t name_size = strlen(name_part) + 32; \ char *name = UTEST_PTR_CAST(char *, malloc(name_size)); \ utest_state.tests = UTEST_PTR_CAST( \ @@ -1234,14 +1278,20 @@ utest_strncpy_gcc(char *const dst, const char *const src, const size_t size) { utest_realloc(UTEST_PTR_CAST(void *, utest_state.tests), \ sizeof(struct utest_test_state_s) * \ utest_state.tests_length)); \ - if (utest_state.tests) { \ + if (utest_state.tests && name) { \ utest_state.tests[index].func = &utest_i_##FIXTURE##_##NAME##_##INDEX; \ utest_state.tests[index].index = i; \ utest_state.tests[index].name = name; \ iUp = UTEST_CAST(utest_uint64_t, i); \ UTEST_SNPRINTF(name, name_size, "%s/%" UTEST_PRIu64, name_part, iUp); \ - } else if (name) { \ - free(name); \ + } else { \ + if (utest_state.tests) { \ + free(utest_state.tests); \ + utest_state.tests = NULL; \ + } \ + if (name) { \ + free(name); \ + } \ } \ } \ } \ @@ -1665,4 +1715,4 @@ cleanup: return utest_main(argc, argv); \ } -#endif /* SHEREDOM_UTEST_H_INCLUDED */ +#endif /* SHEREDOM_UTEST_H_INCLUDED */ \ No newline at end of file From e7b8c97dce5b84ce71aab9c38b988da388e8bbaa Mon Sep 17 00:00:00 2001 From: Riley Smith Date: Mon, 11 Nov 2024 11:22:13 -0800 Subject: [PATCH 02/21] test --- lab-4/parser.bison | 30 ++++++++++- lab-5/parser.bison | 1 - lab-5/token.h | 126 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 154 insertions(+), 3 deletions(-) create mode 100644 lab-5/token.h diff --git a/lab-4/parser.bison b/lab-4/parser.bison index c0c71ca..0876739 100644 --- a/lab-4/parser.bison +++ b/lab-4/parser.bison @@ -1,14 +1,41 @@ %{ #define YYDEBUG 1 #include + +#include +#include +#include +#include "expr.h" + +/* +YYSTYPE is the lexical value returned by each rule in a bison grammar. +By default, it is an integer. In this example, we are returning a pointer to an expression. +*/ + +#define YYSTYPE struct expr * + +/* +Clunky: Manually declare the interface to the scanner generated by flex. +*/ + +extern char *yytext; +extern int yylex(); extern int yylineno; void yyerror(const char*); -int yylex(); + + +/* +Clunky: Keep the final result of the parse in a global variable, +so that it can be retrieved by main(). +*/ + +struct expr * parser_result = 0; %} %debug %define parse.error detailed + %token TOKEN_EOF %token TOKEN_KEYWORD_IDENTIFICATION %token TOKEN_KEYWORD_DIVISION @@ -75,7 +102,6 @@ statement : section | data_space | data_declaration ; - section : type TOKEN_KEYWORD_DIVISION TOKEN_DOT | type TOKEN_RUN TOKEN_DOT ; diff --git a/lab-5/parser.bison b/lab-5/parser.bison index e536a2c..0876739 100644 --- a/lab-5/parser.bison +++ b/lab-5/parser.bison @@ -102,7 +102,6 @@ statement : section | data_space | data_declaration ; - section : type TOKEN_KEYWORD_DIVISION TOKEN_DOT | type TOKEN_RUN TOKEN_DOT ; diff --git a/lab-5/token.h b/lab-5/token.h new file mode 100644 index 0000000..ebb85f5 --- /dev/null +++ b/lab-5/token.h @@ -0,0 +1,126 @@ +/* A Bison parser, made by GNU Bison 3.8.2. */ + +/* Bison interface for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, + Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, + especially those whose name start with YY_ or yy_. They are + private implementation details that can be changed or removed. */ + +#ifndef YY_YY_TOKEN_H_INCLUDED +# define YY_YY_TOKEN_H_INCLUDED +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 1 +#endif +#if YYDEBUG +extern int yydebug; +#endif + +/* Token kinds. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + enum yytokentype + { + YYEMPTY = -2, + YYEOF = 0, /* "end of file" */ + YYerror = 256, /* error */ + YYUNDEF = 257, /* "invalid token" */ + TOKEN_EOF = 258, /* TOKEN_EOF */ + TOKEN_KEYWORD_IDENTIFICATION = 259, /* TOKEN_KEYWORD_IDENTIFICATION */ + TOKEN_KEYWORD_DIVISION = 260, /* TOKEN_KEYWORD_DIVISION */ + TOKEN_KEYWORD_DATA = 261, /* TOKEN_KEYWORD_DATA */ + TOKEN_KEYWORD_SECTION = 262, /* TOKEN_KEYWORD_SECTION */ + TOKEN_PROGRAM_ID = 263, /* TOKEN_PROGRAM_ID */ + TOKEN_WORKING_STORAGE = 264, /* TOKEN_WORKING_STORAGE */ + TOKEN_PROCEDURE = 265, /* TOKEN_PROCEDURE */ + TOKEN_STOP = 266, /* TOKEN_STOP */ + TOKEN_RUN = 267, /* TOKEN_RUN */ + TOKEN_MOVE = 268, /* TOKEN_MOVE */ + TOKEN_KEYWORD_TO = 269, /* TOKEN_KEYWORD_TO */ + TOKEN_PERFORM = 270, /* TOKEN_PERFORM */ + TOKEN_VARYING = 271, /* TOKEN_VARYING */ + TOKEN_KEYWORD_FROM = 272, /* TOKEN_KEYWORD_FROM */ + TOKEN_KEYWORD_BY = 273, /* TOKEN_KEYWORD_BY */ + TOKEN_UNTIL = 274, /* TOKEN_UNTIL */ + TOKEN_END_PERFORM = 275, /* TOKEN_END_PERFORM */ + TOKEN_IF = 276, /* TOKEN_IF */ + TOKEN_ELSE_IF = 277, /* TOKEN_ELSE_IF */ + TOKEN_ELSE = 278, /* TOKEN_ELSE */ + TOKEN_END_IF = 279, /* TOKEN_END_IF */ + TOKEN_SPACE = 280, /* TOKEN_SPACE */ + TOKEN_KEYWORD_OCCURS = 281, /* TOKEN_KEYWORD_OCCURS */ + TOKEN_KEYWORD_VALUE = 282, /* TOKEN_KEYWORD_VALUE */ + TOKEN_KEYWORD_COMPUTE = 283, /* TOKEN_KEYWORD_COMPUTE */ + TOKEN_KEYWORD_FUNCTION = 284, /* TOKEN_KEYWORD_FUNCTION */ + TOKEN_IDENT = 285, /* TOKEN_IDENT */ + TOKEN_STRING = 286, /* TOKEN_STRING */ + TOKEN_INTEGER = 287, /* TOKEN_INTEGER */ + TOKEN_PICTURE = 288, /* TOKEN_PICTURE */ + TOKEN_ALPHANUMERIC = 289, /* TOKEN_ALPHANUMERIC */ + TOKEN_NUMERIC = 290, /* TOKEN_NUMERIC */ + TOKEN_SIGNED_NUMERIC = 291, /* TOKEN_SIGNED_NUMERIC */ + TOKEN_IMPLIED_DECIMAL = 292, /* TOKEN_IMPLIED_DECIMAL */ + TOKEN_COMPUTATION_LEVEL_0 = 293, /* TOKEN_COMPUTATION_LEVEL_0 */ + TOKEN_COMPUTATION_LEVEL_1 = 294, /* TOKEN_COMPUTATION_LEVEL_1 */ + TOKEN_COMPUTATION_LEVEL_2 = 295, /* TOKEN_COMPUTATION_LEVEL_2 */ + TOKEN_COMPUTATION_LEVEL_3 = 296, /* TOKEN_COMPUTATION_LEVEL_3 */ + TOKEN_LEFT_PARENTHESIS = 297, /* TOKEN_LEFT_PARENTHESIS */ + TOKEN_RIGHT_PARENTHESIS = 298, /* TOKEN_RIGHT_PARENTHESIS */ + TOKEN_DOT = 299, /* TOKEN_DOT */ + TOKEN_ADD = 300, /* TOKEN_ADD */ + TOKEN_SUB = 301, /* TOKEN_SUB */ + TOKEN_MULTIPLY = 302, /* TOKEN_MULTIPLY */ + TOKEN_DIVIDE = 303, /* TOKEN_DIVIDE */ + TOKEN_EQUAL = 304, /* TOKEN_EQUAL */ + TOKEN_GREATER_THAN = 305, /* TOKEN_GREATER_THAN */ + TOKEN_LESS_THAN = 306, /* TOKEN_LESS_THAN */ + TOKEN_EXPONENTIAL = 307, /* TOKEN_EXPONENTIAL */ + TOKEN_DISPLAY = 308 /* TOKEN_DISPLAY */ + }; + typedef enum yytokentype yytoken_kind_t; +#endif + +/* Value type. */ +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef int YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define YYSTYPE_IS_DECLARED 1 +#endif + + +extern YYSTYPE yylval; + + +int yyparse (void); + + +#endif /* !YY_YY_TOKEN_H_INCLUDED */ From 2f9ed953116604f2dfa0f820ed8e054e7138749b Mon Sep 17 00:00:00 2001 From: Josh Date: Mon, 11 Nov 2024 11:22:42 -0800 Subject: [PATCH 03/21] changed op_parms --- lab-5/parser.bison | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/lab-5/parser.bison b/lab-5/parser.bison index e536a2c..c7ca676 100644 --- a/lab-5/parser.bison +++ b/lab-5/parser.bison @@ -126,20 +126,25 @@ assignment_stmt : TOKEN_EQUAL ext_function | TOKEN_EQUAL function | TOKEN_KEYWORD_TO op_parms ; -op_parms : op_parms TOKEN_ADD op_parms +op_parms : mathmaticalexpr + | booleanexpr + | otherexpr + | type_expr + ; +mathmaticalexpr : 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 + ; +booleanexpr : 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 - | expr + ; +otherexpr : TOKEN_LEFT_PARENTHESIS op_parms TOKEN_RIGHT_PARENTHESIS | op_parms op_parms ; -expr : TOKEN_IDENT +type_expr : TOKEN_IDENT | TOKEN_INTEGER | TOKEN_STRING | TOKEN_SPACE From e5b1dd03b5bd4ed389daaaa564918c6d92afaf8a Mon Sep 17 00:00:00 2001 From: Riley Smith Date: Tue, 12 Nov 2024 15:41:25 -0800 Subject: [PATCH 04/21] test bison --- lab-4/parser.bison | 30 ++---------------------------- 1 file changed, 2 insertions(+), 28 deletions(-) diff --git a/lab-4/parser.bison b/lab-4/parser.bison index 0876739..c0c71ca 100644 --- a/lab-4/parser.bison +++ b/lab-4/parser.bison @@ -1,41 +1,14 @@ %{ #define YYDEBUG 1 #include - -#include -#include -#include -#include "expr.h" - -/* -YYSTYPE is the lexical value returned by each rule in a bison grammar. -By default, it is an integer. In this example, we are returning a pointer to an expression. -*/ - -#define YYSTYPE struct expr * - -/* -Clunky: Manually declare the interface to the scanner generated by flex. -*/ - -extern char *yytext; -extern int yylex(); extern int yylineno; 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 expr * parser_result = 0; +int yylex(); %} %debug %define parse.error detailed - %token TOKEN_EOF %token TOKEN_KEYWORD_IDENTIFICATION %token TOKEN_KEYWORD_DIVISION @@ -102,6 +75,7 @@ statement : section | data_space | data_declaration ; + section : type TOKEN_KEYWORD_DIVISION TOKEN_DOT | type TOKEN_RUN TOKEN_DOT ; From 2d3dfc621c6a0e6455c95594367bb5341efc3b83 Mon Sep 17 00:00:00 2001 From: Josh Date: Tue, 12 Nov 2024 15:48:10 -0800 Subject: [PATCH 05/21] reducing conflicts --- lab-4/parser.bison | 26 ++++++++++++++++---------- lab-5/parser.bison | 11 ++++++----- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/lab-4/parser.bison b/lab-4/parser.bison index c0c71ca..c24ae00 100644 --- a/lab-4/parser.bison +++ b/lab-4/parser.bison @@ -99,20 +99,26 @@ 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 : mathmaticalexpr + | booleanexpr + | otherexpr + | type_expr + ; +mathmaticalexpr : type_expr TOKEN_ADD type_expr + | type_expr TOKEN_SUB type_expr + | type_expr TOKEN_MULTIPLY type_expr + | type_expr TOKEN_DIVIDE type_expr + | type_expr TOKEN_EXPONENTIAL type_expr + | TOKEN_SUB type_expr + ; +booleanexpr : 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 - | expr + ; +otherexpr : TOKEN_LEFT_PARENTHESIS op_parms TOKEN_RIGHT_PARENTHESIS | op_parms op_parms ; -expr : TOKEN_IDENT +type_expr : TOKEN_IDENT | TOKEN_INTEGER | TOKEN_STRING | TOKEN_SPACE diff --git a/lab-5/parser.bison b/lab-5/parser.bison index c7ca676..2139d87 100644 --- a/lab-5/parser.bison +++ b/lab-5/parser.bison @@ -131,11 +131,12 @@ op_parms : mathmaticalexpr | otherexpr | type_expr ; -mathmaticalexpr : 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 +mathmaticalexpr : type_expr TOKEN_ADD type_expr + | type_expr TOKEN_SUB type_expr + | type_expr TOKEN_MULTIPLY type_expr + | type_expr TOKEN_DIVIDE type_expr + | type_expr TOKEN_EXPONENTIAL type_expr + | TOKEN_SUB type_expr ; booleanexpr : op_parms TOKEN_LESS_THAN op_parms | op_parms TOKEN_GREATER_THAN op_parms From 9ed9e72ad26d42425de6f91283c157d490730b51 Mon Sep 17 00:00:00 2001 From: Riley Smith Date: Tue, 12 Nov 2024 16:23:41 -0800 Subject: [PATCH 06/21] fix everything --- lab-3/main.c | 2 +- lab-3/main_test.c | 6 ++-- lab-3/samples/quadratic-snippet.cbl | 17 +++++---- lab-3/scanner | Bin 0 -> 53112 bytes lab-3/scanner.flex | 9 ++--- lab-3/token.h | 2 +- lab-4/parser.bison | 54 ++++++++++++++++------------ lab-4/samples/quadratic-snippet.cbl | 2 -- lab-4/samples/sorting-snippet.cbl | 1 - 9 files changed, 48 insertions(+), 45 deletions(-) create mode 100755 lab-3/scanner diff --git a/lab-3/main.c b/lab-3/main.c index 1187003..7e4a834 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/quadratic_snippet.cbl"; // Default filename + const char *filename = "samples/quadratic-snippet.cbl"; // 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 1eb729a..1dd60bd 100644 --- a/lab-3/main_test.c +++ b/lab-3/main_test.c @@ -20,7 +20,7 @@ struct token_st { UTEST(scanner, hello) { struct token_st tokens[] = { - {TOKEN_IDENTIFICATION, "IDENTIFICATION"}, + {TOKEN_KEYWORD_IDENTIFICATION, "IDENTIFICATION"}, {TOKEN_KEYWORD_DIVISION, "DIVISION"}, {TOKEN_DOT, "."}, {TOKEN_PROGRAM_ID, "PROGRAM-ID"}, @@ -56,7 +56,7 @@ UTEST(scanner, quadratic) { {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_IDENTIFICATION, "IDENTIFICATION"}, {TOKEN_KEYWORD_DIVISION, "DIVISION"}, {TOKEN_DOT, "."}, {TOKEN_PROGRAM_ID, "PROGRAM-ID"}, @@ -316,7 +316,7 @@ UTEST(scanner, quadratic) { UTEST(scanner, sorting) { struct token_st tokens[] = { - {TOKEN_IDENTIFICATION, "IDENTIFICATION"}, + {TOKEN_KEYWORD_IDENTIFICATION, "IDENTIFICATION"}, {TOKEN_KEYWORD_DIVISION, "DIVISION"}, {TOKEN_DOT, "."}, {TOKEN_PROGRAM_ID, "PROGRAM-ID"}, diff --git a/lab-3/samples/quadratic-snippet.cbl b/lab-3/samples/quadratic-snippet.cbl index 18ba158..00eb26f 100644 --- a/lab-3/samples/quadratic-snippet.cbl +++ b/lab-3/samples/quadratic-snippet.cbl @@ -14,22 +14,21 @@ 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." + END-IF STOP RUN. diff --git a/lab-3/scanner b/lab-3/scanner new file mode 100755 index 0000000000000000000000000000000000000000..896da2e7d112bdd9b0fd8bba5e7075c48dadba02 GIT binary patch literal 53112 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 M@bWG75niwV1Y6Sb^Z)<= literal 0 HcmV?d00001 diff --git a/lab-3/scanner.flex b/lab-3/scanner.flex index cc22816..4b7a148 100644 --- a/lab-3/scanner.flex +++ b/lab-3/scanner.flex @@ -6,8 +6,8 @@ DIGIT [0-9]+ %% (" "|\t|\n) /* skip whitespace */ -\*>\ ?.* { return TOKEN_COMMENT; } -IDENTIFICATION { return TOKEN_IDENTIFICATION; } +\*>\ ?.* +IDENTIFICATION { return TOKEN_KEYWORD_IDENTIFICATION; } DIVISION { return TOKEN_KEYWORD_DIVISION; } PROGRAM-ID { return TOKEN_PROGRAM_ID; } PROCEDURE { return TOKEN_PROCEDURE; } @@ -27,8 +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; } +SPACE { return TOKEN_SPACE; } PIC { return TOKEN_PICTURE; } OCCURS { return TOKEN_KEYWORD_OCCURS; } VALUE { return TOKEN_KEYWORD_VALUE; } @@ -43,7 +42,6 @@ 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; } @@ -55,7 +53,6 @@ COMP-3 { return TOKEN_COMPUTATION_LEVEL_3; } \< { return TOKEN_LESS_THAN; } \= { return TOKEN_EQUAL;} - "\""[^"]*"\"" { return TOKEN_STRING; } "\'"[^']*"\'" { return TOKEN_STRING; } "(" { return TOKEN_LEFT_PARENTHESIS; } diff --git a/lab-3/token.h b/lab-3/token.h index e64609e..20c1ffa 100644 --- a/lab-3/token.h +++ b/lab-3/token.h @@ -1,6 +1,6 @@ typedef enum { TOKEN_EOF = 0, - TOKEN_IDENTIFICATION, + TOKEN_KEYWORD_IDENTIFICATION, TOKEN_KEYWORD_DIVISION, TOKEN_KEYWORD_DATA, TOKEN_KEYWORD_SECTION, diff --git a/lab-4/parser.bison b/lab-4/parser.bison index c0c71ca..dfeb38e 100644 --- a/lab-4/parser.bison +++ b/lab-4/parser.bison @@ -93,43 +93,53 @@ simple_stmt : cbl_func_stmt cbl_func_stmt : cbl_function | cbl_function op_parms | cbl_function assignment_stmt - | cbl_function op_parms assignment_stmt + | cbl_function op_parm assignment_stmt ; assignment_stmt : TOKEN_EQUAL ext_function - | TOKEN_EQUAL function + | TOKEN_EQUAL op_parms | 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 - | expr - | op_parms op_parms +op_parms : op_parm + | op_parms op_parm ; -expr : TOKEN_IDENT +op_parm : mathmaticalexpr + | booleanexpr + | type_expr + ; +mathmaticalexpr : type_expr + | mathmaticalexpr TOKEN_ADD mathmaticalexpr + | mathmaticalexpr TOKEN_SUB mathmaticalexpr + | mathmaticalexpr TOKEN_MULTIPLY mathmaticalexpr + | mathmaticalexpr TOKEN_DIVIDE mathmaticalexpr + | mathmaticalexpr TOKEN_EXPONENTIAL mathmaticalexpr + | container_expr + | type_expr container_expr + ; +container_expr : TOKEN_LEFT_PARENTHESIS op_parms TOKEN_RIGHT_PARENTHESIS + ; +booleanexpr : mathmaticalexpr TOKEN_LESS_THAN mathmaticalexpr + | mathmaticalexpr TOKEN_GREATER_THAN mathmaticalexpr + | mathmaticalexpr TOKEN_EQUAL mathmaticalexpr + ; +type_expr : TOKEN_IDENT | TOKEN_INTEGER | TOKEN_STRING | TOKEN_SPACE - ; -function : op_parms + | TOKEN_SUB TOKEN_IDENT ; 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 +if_branch : if_start statements else_parts + ; +if_start : TOKEN_IF booleanexpr + ; +else_parts : + | TOKEN_ELSE_IF booleanexpr statements else_parts + | TOKEN_ELSE statements ; 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 diff --git a/lab-4/samples/quadratic-snippet.cbl b/lab-4/samples/quadratic-snippet.cbl index ab76e40..7f27b4d 100644 --- a/lab-4/samples/quadratic-snippet.cbl +++ b/lab-4/samples/quadratic-snippet.cbl @@ -24,12 +24,10 @@ 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. diff --git a/lab-4/samples/sorting-snippet.cbl b/lab-4/samples/sorting-snippet.cbl index 8324e47..07b2ebd 100644 --- a/lab-4/samples/sorting-snippet.cbl +++ b/lab-4/samples/sorting-snippet.cbl @@ -39,7 +39,6 @@ PROCEDURE DIVISION. 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 From 58dad1f505634083d55dc07fe066577a431a2828 Mon Sep 17 00:00:00 2001 From: Riley Smith Date: Tue, 12 Nov 2024 16:25:39 -0800 Subject: [PATCH 07/21] move over files again --- lab-5/parser.bison | 84 ++++++++++++----------------- lab-5/samples/quadratic-snippet.cbl | 2 - lab-5/samples/sorting-snippet.cbl | 1 - lab-5/scanner.flex | 2 +- 4 files changed, 35 insertions(+), 54 deletions(-) diff --git a/lab-5/parser.bison b/lab-5/parser.bison index 0876739..dfeb38e 100644 --- a/lab-5/parser.bison +++ b/lab-5/parser.bison @@ -1,41 +1,14 @@ %{ #define YYDEBUG 1 #include - -#include -#include -#include -#include "expr.h" - -/* -YYSTYPE is the lexical value returned by each rule in a bison grammar. -By default, it is an integer. In this example, we are returning a pointer to an expression. -*/ - -#define YYSTYPE struct expr * - -/* -Clunky: Manually declare the interface to the scanner generated by flex. -*/ - -extern char *yytext; -extern int yylex(); extern int yylineno; 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 expr * parser_result = 0; +int yylex(); %} %debug %define parse.error detailed - %token TOKEN_EOF %token TOKEN_KEYWORD_IDENTIFICATION %token TOKEN_KEYWORD_DIVISION @@ -102,6 +75,7 @@ statement : section | data_space | data_declaration ; + section : type TOKEN_KEYWORD_DIVISION TOKEN_DOT | type TOKEN_RUN TOKEN_DOT ; @@ -119,43 +93,53 @@ simple_stmt : cbl_func_stmt cbl_func_stmt : cbl_function | cbl_function op_parms | cbl_function assignment_stmt - | cbl_function op_parms assignment_stmt + | cbl_function op_parm assignment_stmt ; assignment_stmt : TOKEN_EQUAL ext_function - | TOKEN_EQUAL function + | TOKEN_EQUAL op_parms | 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 - | expr - | op_parms op_parms +op_parms : op_parm + | op_parms op_parm ; -expr : TOKEN_IDENT +op_parm : mathmaticalexpr + | booleanexpr + | type_expr + ; +mathmaticalexpr : type_expr + | mathmaticalexpr TOKEN_ADD mathmaticalexpr + | mathmaticalexpr TOKEN_SUB mathmaticalexpr + | mathmaticalexpr TOKEN_MULTIPLY mathmaticalexpr + | mathmaticalexpr TOKEN_DIVIDE mathmaticalexpr + | mathmaticalexpr TOKEN_EXPONENTIAL mathmaticalexpr + | container_expr + | type_expr container_expr + ; +container_expr : TOKEN_LEFT_PARENTHESIS op_parms TOKEN_RIGHT_PARENTHESIS + ; +booleanexpr : mathmaticalexpr TOKEN_LESS_THAN mathmaticalexpr + | mathmaticalexpr TOKEN_GREATER_THAN mathmaticalexpr + | mathmaticalexpr TOKEN_EQUAL mathmaticalexpr + ; +type_expr : TOKEN_IDENT | TOKEN_INTEGER | TOKEN_STRING | TOKEN_SPACE - ; -function : op_parms + | TOKEN_SUB TOKEN_IDENT ; 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 +if_branch : if_start statements else_parts + ; +if_start : TOKEN_IF booleanexpr + ; +else_parts : + | TOKEN_ELSE_IF booleanexpr statements else_parts + | TOKEN_ELSE statements ; 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 diff --git a/lab-5/samples/quadratic-snippet.cbl b/lab-5/samples/quadratic-snippet.cbl index ab76e40..7f27b4d 100644 --- a/lab-5/samples/quadratic-snippet.cbl +++ b/lab-5/samples/quadratic-snippet.cbl @@ -24,12 +24,10 @@ 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. diff --git a/lab-5/samples/sorting-snippet.cbl b/lab-5/samples/sorting-snippet.cbl index 8324e47..07b2ebd 100644 --- a/lab-5/samples/sorting-snippet.cbl +++ b/lab-5/samples/sorting-snippet.cbl @@ -39,7 +39,6 @@ PROCEDURE DIVISION. 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 diff --git a/lab-5/scanner.flex b/lab-5/scanner.flex index ca9acac..4b7a148 100644 --- a/lab-5/scanner.flex +++ b/lab-5/scanner.flex @@ -1,5 +1,5 @@ %{ -#include "parser.h" +#include "token.h" %} NAME [a-zA-Z]([a-zA-Z0-9_-]*[a-zA-Z0-9])? DIGIT [0-9]+ From 1802175103fecd0a6f5f0cd3396d5a279eeda09c Mon Sep 17 00:00:00 2001 From: Josh Date: Tue, 12 Nov 2024 19:41:10 -0800 Subject: [PATCH 08/21] 30 shift/reduce 25 reduce/reduce --- lab-4/parser.bison | 122 ++++++++++++++++++++++----------------------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/lab-4/parser.bison b/lab-4/parser.bison index dfeb38e..9b42942 100644 --- a/lab-4/parser.bison +++ b/lab-4/parser.bison @@ -9,57 +9,58 @@ int yylex(); %debug %define parse.error detailed -%token TOKEN_EOF -%token TOKEN_KEYWORD_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_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_PICTURE +%token TOKEN_ADD %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_ADD -%token TOKEN_SUB -%token TOKEN_MULTIPLY -%token TOKEN_DIVIDE -%token TOKEN_EQUAL -%token TOKEN_GREATER_THAN -%token TOKEN_LESS_THAN -%token TOKEN_EXPONENTIAL %token TOKEN_DISPLAY +%token TOKEN_DIVIDE +%token TOKEN_DOT +%token TOKEN_ELSE +%token TOKEN_ELSE_IF +%token TOKEN_END_IF +%token TOKEN_END_PERFORM +%token TOKEN_EQUAL +%token TOKEN_EXPONENTIAL +%token TOKEN_GREATER_THAN +%token TOKEN_IDENT +%token TOKEN_IF +%token TOKEN_IMPLIED_DECIMAL +%token TOKEN_INTEGER +%token TOKEN_KEYWORD_BY +%token TOKEN_KEYWORD_COMPUTE +%token TOKEN_KEYWORD_DATA +%token TOKEN_KEYWORD_DIVISION +%token TOKEN_KEYWORD_FROM +%token TOKEN_KEYWORD_FUNCTION +%token TOKEN_KEYWORD_IDENTIFICATION +%token TOKEN_KEYWORD_OCCURS +%token TOKEN_KEYWORD_SECTION +%token TOKEN_KEYWORD_TO +%token TOKEN_KEYWORD_VALUE +%token TOKEN_LEFT_PARENTHESIS +%token TOKEN_LESS_THAN +%token TOKEN_MOVE +%token TOKEN_MULTIPLY +%token TOKEN_NUMERIC +%token TOKEN_PERFORM +%token TOKEN_PICTURE +%token TOKEN_PROGRAM_ID +%token TOKEN_PROCEDURE +%token TOKEN_RIGHT_PARENTHESIS +%token TOKEN_RUN +%token TOKEN_SIGNED_NUMERIC +%token TOKEN_SPACE +%token TOKEN_STOP +%token TOKEN_STRING +%token TOKEN_SUB +%token TOKEN_UNTIL +%token TOKEN_VARYING +%token TOKEN_WORKING_STORAGE +%token TOKEN_EOF + %% @@ -88,6 +89,7 @@ type : TOKEN_KEYWORD_IDENTIFICATION ; simple_stmt : cbl_func_stmt | if_branch + | else_parts | perform_stmt ; cbl_func_stmt : cbl_function @@ -106,20 +108,22 @@ op_parm : mathmaticalexpr | booleanexpr | type_expr ; +term : mathmaticalexpr + ; mathmaticalexpr : type_expr - | mathmaticalexpr TOKEN_ADD mathmaticalexpr - | mathmaticalexpr TOKEN_SUB mathmaticalexpr - | mathmaticalexpr TOKEN_MULTIPLY mathmaticalexpr - | mathmaticalexpr TOKEN_DIVIDE mathmaticalexpr - | mathmaticalexpr TOKEN_EXPONENTIAL mathmaticalexpr + | mathmaticalexpr TOKEN_ADD term + | mathmaticalexpr TOKEN_SUB term + | mathmaticalexpr TOKEN_MULTIPLY term + | mathmaticalexpr TOKEN_DIVIDE term + | mathmaticalexpr TOKEN_EXPONENTIAL term | container_expr | type_expr container_expr ; container_expr : TOKEN_LEFT_PARENTHESIS op_parms TOKEN_RIGHT_PARENTHESIS ; -booleanexpr : mathmaticalexpr TOKEN_LESS_THAN mathmaticalexpr - | mathmaticalexpr TOKEN_GREATER_THAN mathmaticalexpr - | mathmaticalexpr TOKEN_EQUAL mathmaticalexpr +booleanexpr : mathmaticalexpr TOKEN_LESS_THAN term + | mathmaticalexpr TOKEN_GREATER_THAN term + | mathmaticalexpr TOKEN_EQUAL term ; type_expr : TOKEN_IDENT | TOKEN_INTEGER @@ -133,20 +137,16 @@ cbl_function : TOKEN_DISPLAY | TOKEN_MOVE | TOKEN_KEYWORD_COMPUTE ; -if_branch : if_start statements else_parts +if_branch : TOKEN_IF booleanexpr ; -if_start : TOKEN_IF booleanexpr - ; -else_parts : - | TOKEN_ELSE_IF booleanexpr statements else_parts +else_parts : TOKEN_ELSE_IF booleanexpr statements | TOKEN_ELSE statements + | 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_space : TOKEN_WORKING_STORAGE TOKEN_KEYWORD_SECTION TOKEN_DOT ; data_category : TOKEN_ALPHANUMERIC | TOKEN_NUMERIC From a089fe73dbb481ab903180a3233b10c0c3b96239 Mon Sep 17 00:00:00 2001 From: Riley Smith Date: Wed, 13 Nov 2024 17:12:09 -0800 Subject: [PATCH 09/21] fix sample --- lab-4/samples/sorting-snippet.cbl | 2 +- lab-5/Makefile | 2 +- lab-5/parser.bison | 36 +++++++++++++++++++++++++++---- 3 files changed, 34 insertions(+), 6 deletions(-) diff --git a/lab-4/samples/sorting-snippet.cbl b/lab-4/samples/sorting-snippet.cbl index 07b2ebd..7019d00 100644 --- a/lab-4/samples/sorting-snippet.cbl +++ b/lab-4/samples/sorting-snippet.cbl @@ -48,7 +48,7 @@ PROCEDURE DIVISION. 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. + END-PERFORM STOP RUN. \ No newline at end of file diff --git a/lab-5/Makefile b/lab-5/Makefile index dfc7723..0361623 100644 --- a/lab-5/Makefile +++ b/lab-5/Makefile @@ -20,7 +20,7 @@ scanner.c: scanner.flex parser.h flex -oscanner.c scanner.flex parser.c parser.h: parser.bison - bison --defines=parser.h --output=parser.c -v parser.bison -Wconflicts-sr -Wcounterexamples + bison --defines=parser.h --output=parser.c -v parser.bison # clean causes all intermediate files to be deleted. diff --git a/lab-5/parser.bison b/lab-5/parser.bison index dfeb38e..f51f45c 100644 --- a/lab-5/parser.bison +++ b/lab-5/parser.bison @@ -1,9 +1,35 @@ %{ #define YYDEBUG 1 #include -extern int yylineno; +#include +#include +#include +#include "expr.h" + +/* +YYSTYPE is the lexical value returned by each rule in a bison grammar. +By default, it is an integer. In this example, we are returning a pointer to an expression. +*/ + +#define YYSTYPE struct expr * + +/* +Clunky: Manually declare the interface to the scanner generated by flex. +*/ + +extern char *yytext; +extern int yylex(); void yyerror(const char*); -int yylex(); + +/* +Clunky: Keep the final result of the parse in a global variable, +so that it can be retrieved by main(). +*/ + +struct expr * parser_result = 0; + + +extern int yylineno; %} %debug @@ -63,7 +89,9 @@ int yylex(); %% -file : statements +program : statements + { parser_result = $1; return 0;} + ; statements : statement_list ; statement_list : statement_list statement @@ -91,7 +119,7 @@ simple_stmt : cbl_func_stmt | perform_stmt ; cbl_func_stmt : cbl_function - | cbl_function op_parms + | cbl_function op_parms | cbl_function assignment_stmt | cbl_function op_parm assignment_stmt ; From 7694728a2104abfdd6fd10ed86667fc92bd13d71 Mon Sep 17 00:00:00 2001 From: Josh Date: Wed, 13 Nov 2024 17:49:38 -0800 Subject: [PATCH 10/21] 11 13 24 5 49 --- lab-4/parser.bison | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/lab-4/parser.bison b/lab-4/parser.bison index 9b42942..62b7693 100644 --- a/lab-4/parser.bison +++ b/lab-4/parser.bison @@ -108,14 +108,16 @@ op_parm : mathmaticalexpr | booleanexpr | type_expr ; -term : mathmaticalexpr +term : mathmaticalexpr + ; +math_op : TOKEN_ADD + | TOKEN_SUB + | TOKEN_MULTIPLY + | TOKEN_DIVIDE + | TOKEN_EXPONENTIAL ; mathmaticalexpr : type_expr - | mathmaticalexpr TOKEN_ADD term - | mathmaticalexpr TOKEN_SUB term - | mathmaticalexpr TOKEN_MULTIPLY term - | mathmaticalexpr TOKEN_DIVIDE term - | mathmaticalexpr TOKEN_EXPONENTIAL term + | mathmaticalexpr math_op term | container_expr | type_expr container_expr ; @@ -139,8 +141,8 @@ cbl_function : TOKEN_DISPLAY ; if_branch : TOKEN_IF booleanexpr ; -else_parts : TOKEN_ELSE_IF booleanexpr statements - | TOKEN_ELSE statements +else_parts : TOKEN_ELSE_IF booleanexpr simple_stmt + | TOKEN_ELSE simple_stmt | 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 From 7e8d5162df704b6d382dee973a9bbef712c7ee16 Mon Sep 17 00:00:00 2001 From: Riley Smith Date: Wed, 13 Nov 2024 17:50:28 -0800 Subject: [PATCH 11/21] make cbl_func_stmt easier --- lab-4/parser.bison | 42 +++++++++++++++++++++++------------------- lab-5/parser.bison | 14 +++++++------- 2 files changed, 30 insertions(+), 26 deletions(-) diff --git a/lab-4/parser.bison b/lab-4/parser.bison index 9b42942..a6d0172 100644 --- a/lab-4/parser.bison +++ b/lab-4/parser.bison @@ -92,17 +92,23 @@ simple_stmt : cbl_func_stmt | else_parts | perform_stmt ; -cbl_func_stmt : cbl_function - | cbl_function op_parms - | cbl_function assignment_stmt - | cbl_function op_parm assignment_stmt +cbl_func_stmt : display_stmt + | move_stmt + | compute_stmt + ; + +display_stmt : TOKEN_DISPLAY op_parms_list + ; +move_stmt : TOKEN_MOVE op_parms_list assignment_stmt + ; +compute_stmt : TOKEN_KEYWORD_COMPUTE single_op_parm assignment_stmt ; assignment_stmt : TOKEN_EQUAL ext_function - | TOKEN_EQUAL op_parms - | TOKEN_KEYWORD_TO op_parms + | TOKEN_EQUAL op_parms_list + | TOKEN_KEYWORD_TO op_parms_list ; -op_parms : op_parm - | op_parms op_parm +op_parms_list : single_op_parm + | op_parms_list op_parm ; op_parm : mathmaticalexpr | booleanexpr @@ -111,15 +117,15 @@ op_parm : mathmaticalexpr term : mathmaticalexpr ; mathmaticalexpr : type_expr + | container_expr + | type_expr container_expr | mathmaticalexpr TOKEN_ADD term | mathmaticalexpr TOKEN_SUB term | mathmaticalexpr TOKEN_MULTIPLY term | mathmaticalexpr TOKEN_DIVIDE term | mathmaticalexpr TOKEN_EXPONENTIAL term - | container_expr - | type_expr container_expr - ; -container_expr : TOKEN_LEFT_PARENTHESIS op_parms TOKEN_RIGHT_PARENTHESIS + ; +container_expr : TOKEN_LEFT_PARENTHESIS op_parms_list TOKEN_RIGHT_PARENTHESIS ; booleanexpr : mathmaticalexpr TOKEN_LESS_THAN term | mathmaticalexpr TOKEN_GREATER_THAN term @@ -133,17 +139,13 @@ type_expr : TOKEN_IDENT ; ext_function : TOKEN_KEYWORD_FUNCTION TOKEN_IDENT TOKEN_LEFT_PARENTHESIS TOKEN_IDENT TOKEN_RIGHT_PARENTHESIS ; -cbl_function : TOKEN_DISPLAY - | TOKEN_MOVE - | TOKEN_KEYWORD_COMPUTE - ; if_branch : TOKEN_IF booleanexpr ; -else_parts : TOKEN_ELSE_IF booleanexpr statements - | TOKEN_ELSE statements +else_parts : TOKEN_ELSE_IF booleanexpr simple_stmt + | TOKEN_ELSE simple_stmt | 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 +perform_stmt : TOKEN_PERFORM TOKEN_VARYING TOKEN_IDENT TOKEN_KEYWORD_FROM TOKEN_INTEGER TOKEN_KEYWORD_BY TOKEN_INTEGER TOKEN_UNTIL op_parms_list | TOKEN_END_PERFORM ; data_space : TOKEN_WORKING_STORAGE TOKEN_KEYWORD_SECTION TOKEN_DOT @@ -182,6 +184,8 @@ data_clauses : full_data_clause data_declaration: simple_decl | complex_decl ; +single_op_parm : op_parm + ; %% void yyerror(const char* msg) { diff --git a/lab-5/parser.bison b/lab-5/parser.bison index f51f45c..999a159 100644 --- a/lab-5/parser.bison +++ b/lab-5/parser.bison @@ -184,8 +184,8 @@ data_category : TOKEN_ALPHANUMERIC categry_contain : TOKEN_LEFT_PARENTHESIS TOKEN_INTEGER TOKEN_RIGHT_PARENTHESIS | TOKEN_LEFT_PARENTHESIS TOKEN_IDENT TOKEN_RIGHT_PARENTHESIS ; -complete_category: data_category categry_contain - | data_category categry_contain complete_category +complete_ctgry : data_category categry_contain + | data_category categry_contain complete_ctgry ; data_clause : TOKEN_COMPUTATION_LEVEL_0 | TOKEN_COMPUTATION_LEVEL_1 @@ -194,21 +194,21 @@ data_clause : TOKEN_COMPUTATION_LEVEL_0 | TOKEN_KEYWORD_VALUE | TOKEN_KEYWORD_OCCURS ; -full_data_clause: data_clause data_clause - | data_clause +full_data_clause: data_clause + | data_clause full_data_clause ; simple_decl : TOKEN_INTEGER TOKEN_IDENT TOKEN_DOT ; complex_decl : TOKEN_INTEGER TOKEN_IDENT TOKEN_PICTURE category_spec TOKEN_DOT ; -category_spec : complete_category - | complete_category data_clauses +category_spec : complete_ctgry + | complete_ctgry data_clauses ; data_clauses : full_data_clause | full_data_clause TOKEN_INTEGER ; data_declaration: simple_decl - | complex_decl + | complex_decl`` ; %% From 8aae70da64c7af5a1c29b857619adcb26549937d Mon Sep 17 00:00:00 2001 From: Riley Smith Date: Wed, 13 Nov 2024 17:51:37 -0800 Subject: [PATCH 12/21] fix complication error --- lab-4/parser.bison | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lab-4/parser.bison b/lab-4/parser.bison index 8407f70..e214068 100644 --- a/lab-4/parser.bison +++ b/lab-4/parser.bison @@ -127,7 +127,7 @@ mathmaticalexpr : type_expr | container_expr | type_expr container_expr ; -container_expr : TOKEN_LEFT_PARENTHESIS op_parms TOKEN_RIGHT_PARENTHESIS +container_expr : TOKEN_LEFT_PARENTHESIS op_parms_list TOKEN_RIGHT_PARENTHESIS ; booleanexpr : mathmaticalexpr TOKEN_LESS_THAN term | mathmaticalexpr TOKEN_GREATER_THAN term From 75e28de83c9206b5d993ba8b7c5768255f5c78d3 Mon Sep 17 00:00:00 2001 From: Riley Smith Date: Wed, 13 Nov 2024 18:14:31 -0800 Subject: [PATCH 13/21] get shift/reduce conflicts down by one --- lab-4/parser.bison | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/lab-4/parser.bison b/lab-4/parser.bison index e214068..2dd7f19 100644 --- a/lab-4/parser.bison +++ b/lab-4/parser.bison @@ -61,6 +61,9 @@ int yylex(); %token TOKEN_WORKING_STORAGE %token TOKEN_EOF +%left TOKEN_ADD TOKEN_SUB +%left TOKEN_MULTIPLY TOKEN_DIVIDE +%right TOKEN_EXPONENTIAL %% @@ -96,18 +99,17 @@ cbl_func_stmt : display_stmt | move_stmt | compute_stmt ; - display_stmt : TOKEN_DISPLAY op_parms_list ; move_stmt : TOKEN_MOVE op_parms_list assignment_stmt ; -compute_stmt : TOKEN_KEYWORD_COMPUTE single_op_parm assignment_stmt +compute_stmt : TOKEN_KEYWORD_COMPUTE op_parms_list assignment_stmt ; assignment_stmt : TOKEN_EQUAL ext_function | TOKEN_EQUAL op_parms_list | TOKEN_KEYWORD_TO op_parms_list ; -op_parms_list : single_op_parm +op_parms_list : op_parm | op_parms_list op_parm ; op_parm : mathmaticalexpr @@ -116,18 +118,24 @@ op_parm : mathmaticalexpr ; term : mathmaticalexpr ; + math_op : TOKEN_ADD | TOKEN_SUB | TOKEN_MULTIPLY | TOKEN_DIVIDE | TOKEN_EXPONENTIAL ; -mathmaticalexpr : type_expr +mathmaticalexpr : primary_expr | mathmaticalexpr math_op term - | container_expr - | type_expr container_expr ; -container_expr : TOKEN_LEFT_PARENTHESIS op_parms_list TOKEN_RIGHT_PARENTHESIS +full_contain : simple_contain + | TOKEN_IDENT simple_contain + ; +simple_contain : TOKEN_LEFT_PARENTHESIS mathmaticalexpr TOKEN_RIGHT_PARENTHESIS + ; +primary_expr : type_expr + | full_contain + | TOKEN_SUB primary_expr ; booleanexpr : mathmaticalexpr TOKEN_LESS_THAN term | mathmaticalexpr TOKEN_GREATER_THAN term @@ -137,7 +145,6 @@ type_expr : TOKEN_IDENT | TOKEN_INTEGER | TOKEN_STRING | TOKEN_SPACE - | TOKEN_SUB TOKEN_IDENT ; ext_function : TOKEN_KEYWORD_FUNCTION TOKEN_IDENT TOKEN_LEFT_PARENTHESIS TOKEN_IDENT TOKEN_RIGHT_PARENTHESIS ; @@ -186,8 +193,6 @@ data_clauses : full_data_clause data_declaration: simple_decl | complex_decl ; -single_op_parm : op_parm - ; %% void yyerror(const char* msg) { From f85d4c3599721b68b71a9e015a1fd9b4719609f7 Mon Sep 17 00:00:00 2001 From: Josh Date: Wed, 13 Nov 2024 19:23:10 -0800 Subject: [PATCH 14/21] only 13 shift/reduce --- lab-4/parser.bison | 48 ++++++++++++++++++---------------------------- 1 file changed, 19 insertions(+), 29 deletions(-) diff --git a/lab-4/parser.bison b/lab-4/parser.bison index 2dd7f19..2585a15 100644 --- a/lab-4/parser.bison +++ b/lab-4/parser.bison @@ -61,9 +61,6 @@ int yylex(); %token TOKEN_WORKING_STORAGE %token TOKEN_EOF -%left TOKEN_ADD TOKEN_SUB -%left TOKEN_MULTIPLY TOKEN_DIVIDE -%right TOKEN_EXPONENTIAL %% @@ -95,47 +92,34 @@ simple_stmt : cbl_func_stmt | else_parts | perform_stmt ; -cbl_func_stmt : display_stmt - | move_stmt - | compute_stmt +cbl_func_stmt : cbl_function + | cbl_function op_parms + | cbl_function assignment_stmt + | cbl_function op_parm assignment_stmt ; -display_stmt : TOKEN_DISPLAY op_parms_list +assignment_stmt : TOKEN_EQUAL op_parms + | TOKEN_KEYWORD_TO op_parms ; -move_stmt : TOKEN_MOVE op_parms_list assignment_stmt - ; -compute_stmt : TOKEN_KEYWORD_COMPUTE op_parms_list assignment_stmt - ; -assignment_stmt : TOKEN_EQUAL ext_function - | TOKEN_EQUAL op_parms_list - | TOKEN_KEYWORD_TO op_parms_list - ; -op_parms_list : op_parm - | op_parms_list op_parm +op_parms : op_parm + | op_parms op_parm ; op_parm : mathmaticalexpr | booleanexpr - | type_expr ; term : mathmaticalexpr ; - math_op : TOKEN_ADD | TOKEN_SUB | TOKEN_MULTIPLY | TOKEN_DIVIDE | TOKEN_EXPONENTIAL ; -mathmaticalexpr : primary_expr +mathmaticalexpr : type_expr | mathmaticalexpr math_op term + | container_expr + | type_expr container_expr ; -full_contain : simple_contain - | TOKEN_IDENT simple_contain - ; -simple_contain : TOKEN_LEFT_PARENTHESIS mathmaticalexpr TOKEN_RIGHT_PARENTHESIS - ; -primary_expr : type_expr - | full_contain - | TOKEN_SUB primary_expr +container_expr : TOKEN_LEFT_PARENTHESIS mathmaticalexpr TOKEN_RIGHT_PARENTHESIS ; booleanexpr : mathmaticalexpr TOKEN_LESS_THAN term | mathmaticalexpr TOKEN_GREATER_THAN term @@ -145,16 +129,22 @@ type_expr : TOKEN_IDENT | TOKEN_INTEGER | TOKEN_STRING | TOKEN_SPACE + | TOKEN_SUB TOKEN_IDENT + | ext_function ; ext_function : TOKEN_KEYWORD_FUNCTION TOKEN_IDENT TOKEN_LEFT_PARENTHESIS TOKEN_IDENT TOKEN_RIGHT_PARENTHESIS ; +cbl_function : TOKEN_DISPLAY + | TOKEN_MOVE + | TOKEN_KEYWORD_COMPUTE + ; if_branch : TOKEN_IF booleanexpr ; else_parts : TOKEN_ELSE_IF booleanexpr simple_stmt | TOKEN_ELSE simple_stmt | 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_list +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 From 74faae27436c3e26e09624aa8f2e436f760dfda6 Mon Sep 17 00:00:00 2001 From: Riley Smith Date: Wed, 13 Nov 2024 20:06:55 -0800 Subject: [PATCH 15/21] move over lab-5 --- lab-5/main.c | 20 +++++++----- lab-5/parser.bison | 78 +++++++++++++++++++++------------------------- 2 files changed, 47 insertions(+), 51 deletions(-) diff --git a/lab-5/main.c b/lab-5/main.c index 63208e9..e464500 100644 --- a/lab-5/main.c +++ b/lab-5/main.c @@ -7,23 +7,27 @@ Simply invoke the parser generated by bison, and then display the output. #include /* Clunky: Declare the parse function generated from parser.bison */ -extern int yyparse(); +extern int yyparse(struct stmt *parser_result); /* Clunky: Declare the result of the parser from parser.bison */ -extern struct stmt *parser_result; + +struct stmt *parser_result; int main(int argc, char *argv[]) { printf("Lab 6 Example Interpreter Compiler\n"); printf( "Enter an infix expression using the operators +-*/() ending with ;\n\n"); - if (yyparse() == 0) { + if (yyparse(parser_result) == 0) { printf("Parse successful: "); - stmt_print(parser_result); - printf("\n"); - printf("Running the program, results in: "); - stmt_evaluate(parser_result); - printf("\n"); + if (parser_result != NULL) { + stmt_print(parser_result); + printf("\n"); + printf("Running the program, results in: "); + stmt_evaluate(parser_result); + printf("\n"); + } + printf("parser_result is %p\n", parser_result); return 0; } else { printf("Parse failed!\n"); diff --git a/lab-5/parser.bison b/lab-5/parser.bison index 999a159..4e91288 100644 --- a/lab-5/parser.bison +++ b/lab-5/parser.bison @@ -11,7 +11,7 @@ YYSTYPE is the lexical value returned by each rule in a bison grammar. By default, it is an integer. In this example, we are returning a pointer to an expression. */ -#define YYSTYPE struct expr * +#define YYSTYPE struct stmt * /* Clunky: Manually declare the interface to the scanner generated by flex. @@ -19,19 +19,14 @@ Clunky: Manually declare the interface to the scanner generated by flex. extern char *yytext; extern int yylex(); -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 expr * parser_result = 0; +void yyerror(struct stmt *parser_result, const char*); extern int yylineno; %} +%parse-param {struct stmt *parser_result} + %debug %define parse.error detailed @@ -89,9 +84,7 @@ extern int yylineno; %% -program : statements - { parser_result = $1; return 0;} - ; +file : statements statements : statement_list ; statement_list : statement_list statement @@ -116,15 +109,15 @@ type : TOKEN_KEYWORD_IDENTIFICATION ; simple_stmt : cbl_func_stmt | if_branch + | else_parts | perform_stmt ; cbl_func_stmt : cbl_function - | cbl_function op_parms + | cbl_function op_parms | cbl_function assignment_stmt | cbl_function op_parm assignment_stmt ; -assignment_stmt : TOKEN_EQUAL ext_function - | TOKEN_EQUAL op_parms +assignment_stmt : TOKEN_EQUAL op_parms | TOKEN_KEYWORD_TO op_parms ; op_parms : op_parm @@ -132,28 +125,32 @@ op_parms : op_parm ; op_parm : mathmaticalexpr | booleanexpr - | type_expr + ; +term : mathmaticalexpr + ; +math_op : TOKEN_ADD + | TOKEN_SUB + | TOKEN_MULTIPLY + | TOKEN_DIVIDE + | TOKEN_EXPONENTIAL ; mathmaticalexpr : type_expr - | mathmaticalexpr TOKEN_ADD mathmaticalexpr - | mathmaticalexpr TOKEN_SUB mathmaticalexpr - | mathmaticalexpr TOKEN_MULTIPLY mathmaticalexpr - | mathmaticalexpr TOKEN_DIVIDE mathmaticalexpr - | mathmaticalexpr TOKEN_EXPONENTIAL mathmaticalexpr + | mathmaticalexpr math_op term | container_expr | type_expr container_expr ; -container_expr : TOKEN_LEFT_PARENTHESIS op_parms TOKEN_RIGHT_PARENTHESIS +container_expr : TOKEN_LEFT_PARENTHESIS mathmaticalexpr TOKEN_RIGHT_PARENTHESIS ; -booleanexpr : mathmaticalexpr TOKEN_LESS_THAN mathmaticalexpr - | mathmaticalexpr TOKEN_GREATER_THAN mathmaticalexpr - | mathmaticalexpr TOKEN_EQUAL mathmaticalexpr +booleanexpr : mathmaticalexpr TOKEN_LESS_THAN term + | mathmaticalexpr TOKEN_GREATER_THAN term + | mathmaticalexpr TOKEN_EQUAL term ; type_expr : TOKEN_IDENT | TOKEN_INTEGER | TOKEN_STRING | TOKEN_SPACE | TOKEN_SUB TOKEN_IDENT + | ext_function ; ext_function : TOKEN_KEYWORD_FUNCTION TOKEN_IDENT TOKEN_LEFT_PARENTHESIS TOKEN_IDENT TOKEN_RIGHT_PARENTHESIS ; @@ -161,20 +158,16 @@ cbl_function : TOKEN_DISPLAY | TOKEN_MOVE | TOKEN_KEYWORD_COMPUTE ; -if_branch : if_start statements else_parts +if_branch : TOKEN_IF booleanexpr ; -if_start : TOKEN_IF booleanexpr - ; -else_parts : - | TOKEN_ELSE_IF booleanexpr statements else_parts - | TOKEN_ELSE statements +else_parts : TOKEN_ELSE_IF booleanexpr simple_stmt + | TOKEN_ELSE simple_stmt + | 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_space : TOKEN_WORKING_STORAGE TOKEN_KEYWORD_SECTION TOKEN_DOT ; data_category : TOKEN_ALPHANUMERIC | TOKEN_NUMERIC @@ -184,8 +177,8 @@ data_category : TOKEN_ALPHANUMERIC categry_contain : TOKEN_LEFT_PARENTHESIS TOKEN_INTEGER TOKEN_RIGHT_PARENTHESIS | TOKEN_LEFT_PARENTHESIS TOKEN_IDENT TOKEN_RIGHT_PARENTHESIS ; -complete_ctgry : data_category categry_contain - | data_category categry_contain complete_ctgry +complete_category: data_category categry_contain + | data_category categry_contain complete_category ; data_clause : TOKEN_COMPUTATION_LEVEL_0 | TOKEN_COMPUTATION_LEVEL_1 @@ -194,24 +187,23 @@ data_clause : TOKEN_COMPUTATION_LEVEL_0 | TOKEN_KEYWORD_VALUE | TOKEN_KEYWORD_OCCURS ; -full_data_clause: data_clause - | data_clause full_data_clause +full_data_clause: data_clause data_clause + | data_clause ; simple_decl : TOKEN_INTEGER TOKEN_IDENT TOKEN_DOT ; complex_decl : TOKEN_INTEGER TOKEN_IDENT TOKEN_PICTURE category_spec TOKEN_DOT ; -category_spec : complete_ctgry - | complete_ctgry data_clauses +category_spec : complete_category + | complete_category data_clauses ; data_clauses : full_data_clause | full_data_clause TOKEN_INTEGER ; data_declaration: simple_decl - | complex_decl`` + | complex_decl ; - %% -void yyerror(const char* msg) { +void yyerror(struct stmt *parser_result, const char* msg) { fprintf(stderr, "Error | Line: %d\n%s\n",yylineno,msg); } From 5d03635b931e652dc14837908a866d3f87b39548 Mon Sep 17 00:00:00 2001 From: Riley Smith Date: Wed, 13 Nov 2024 21:22:40 -0800 Subject: [PATCH 16/21] start work on getting hello world interpreting --- lab-5/main.c | 11 ++-- lab-5/parser.bison | 49 ++++++++++++----- lab-5/parser.bison.new | 117 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 162 insertions(+), 15 deletions(-) create mode 100644 lab-5/parser.bison.new diff --git a/lab-5/main.c b/lab-5/main.c index e464500..1a4d24d 100644 --- a/lab-5/main.c +++ b/lab-5/main.c @@ -4,10 +4,15 @@ Simply invoke the parser generated by bison, and then display the output. */ #include "expr.h" +#include "token.h" #include /* Clunky: Declare the parse function generated from parser.bison */ -extern int yyparse(struct stmt *parser_result); +// extern int yyparse(struct stmt *parser_result); +extern int yyparse(); +extern char *yytext; + +extern int yylex(); /* Clunky: Declare the result of the parser from parser.bison */ @@ -17,8 +22,9 @@ int main(int argc, char *argv[]) { printf("Lab 6 Example Interpreter Compiler\n"); printf( "Enter an infix expression using the operators +-*/() ending with ;\n\n"); + - if (yyparse(parser_result) == 0) { + if (yyparse() == 0) { printf("Parse successful: "); if (parser_result != NULL) { stmt_print(parser_result); @@ -27,7 +33,6 @@ int main(int argc, char *argv[]) { stmt_evaluate(parser_result); printf("\n"); } - printf("parser_result is %p\n", parser_result); return 0; } else { printf("Parse failed!\n"); diff --git a/lab-5/parser.bison b/lab-5/parser.bison index 4e91288..480271d 100644 --- a/lab-5/parser.bison +++ b/lab-5/parser.bison @@ -19,13 +19,16 @@ Clunky: Manually declare the interface to the scanner generated by flex. extern char *yytext; extern int yylex(); -void yyerror(struct stmt *parser_result, const char*); - +// void yyerror(struct stmt *parser_result, const char*); +void yyerror(const char*); extern int yylineno; + +struct stmt *parser_result = 0; + %} -%parse-param {struct stmt *parser_result} +// %parse-param {struct stmt *parser_result} %debug %define parse.error detailed @@ -84,19 +87,21 @@ extern int yylineno; %% -file : statements -statements : statement_list +file : statement_list + {parser_result = $1; return 0;} ; statement_list : statement_list statement + { $$ = $1; $1->next = $2; } | statement + { $$ = $1; } ; statement : section | sect_data | simple_stmt + {$$ = stmt_create(STMT_BLOCK, NULL, NULL, NULL, NULL, $1, NULL, NULL);} | data_space | data_declaration ; - section : type TOKEN_KEYWORD_DIVISION TOKEN_DOT | type TOKEN_RUN TOKEN_DOT ; @@ -108,12 +113,14 @@ type : TOKEN_KEYWORD_IDENTIFICATION | TOKEN_KEYWORD_DATA ; simple_stmt : cbl_func_stmt - | if_branch + {$$ = $1;} + | if_branch | else_parts | perform_stmt ; cbl_func_stmt : cbl_function - | cbl_function op_parms + | cbl_function op_parms + {$$ = stmt_create($1->kind, NULL, NULL, $2, NULL, NULL, NULL, NULL);} | cbl_function assignment_stmt | cbl_function op_parm assignment_stmt ; @@ -121,12 +128,17 @@ assignment_stmt : TOKEN_EQUAL op_parms | TOKEN_KEYWORD_TO op_parms ; op_parms : op_parm - | op_parms op_parm + {$$ = $1;} + | op_parm op_parms + {$$ = $1; $1->next_expr = $2;} ; op_parm : mathmaticalexpr + {$$ = $1;} | booleanexpr + {$$ = $1;} ; -term : mathmaticalexpr +term : mathmaticalexpr + {$$ = $1;} ; math_op : TOKEN_ADD | TOKEN_SUB @@ -135,9 +147,12 @@ math_op : TOKEN_ADD | TOKEN_EXPONENTIAL ; mathmaticalexpr : type_expr + {$$ = $1;} | mathmaticalexpr math_op term | container_expr + {$$ = $1;} | type_expr container_expr + {$$ = $1; $1->next_expr = $2;} ; container_expr : TOKEN_LEFT_PARENTHESIS mathmaticalexpr TOKEN_RIGHT_PARENTHESIS ; @@ -146,15 +161,21 @@ booleanexpr : mathmaticalexpr TOKEN_LESS_THAN term | mathmaticalexpr TOKEN_EQUAL term ; type_expr : TOKEN_IDENT + {$$ = expr_create_name(yytext);} | TOKEN_INTEGER + {$$ = expr_create_integer_literal(yytext);} | TOKEN_STRING + {$$ = expr_create_string_literal(atoi(yytext));} | TOKEN_SPACE + {$$ = expr_create_integer_literal(0);} | TOKEN_SUB TOKEN_IDENT + {$$ = expr_create_integer_literal(atoi(yytext) * -1);} | ext_function ; ext_function : TOKEN_KEYWORD_FUNCTION TOKEN_IDENT TOKEN_LEFT_PARENTHESIS TOKEN_IDENT TOKEN_RIGHT_PARENTHESIS ; cbl_function : TOKEN_DISPLAY + {$$ = stmt_create(STMT_PRINT, NULL, NULL, NULL, NULL, NULL, NULL, NULL);} | TOKEN_MOVE | TOKEN_KEYWORD_COMPUTE ; @@ -204,6 +225,10 @@ data_declaration: simple_decl | complex_decl ; %% -void yyerror(struct stmt *parser_result, const char* msg) { +// void yyerror(struct stmt *parser_result, const char* msg) { +// fprintf(stderr, "Error | Line: %d\n%s\n",yylineno,msg); +// } + +void yyerror(const char* msg) { fprintf(stderr, "Error | Line: %d\n%s\n",yylineno,msg); -} +} \ No newline at end of file diff --git a/lab-5/parser.bison.new b/lab-5/parser.bison.new new file mode 100644 index 0000000..50bf300 --- /dev/null +++ b/lab-5/parser.bison.new @@ -0,0 +1,117 @@ +%{ +#define YYDEBUG 1 +#include +#include +#include +#include +#include "expr.h" + +/* +YYSTYPE is the lexical value returned by each rule in a bison grammar. +By default, it is an integer. In this example, we are returning a pointer to an expression. +*/ + +#define YYSTYPE struct stmt * + +/* +Clunky: Manually declare the interface to the scanner generated by flex. +*/ + +extern char *yytext; +extern int yylex(); +// void yyerror(struct stmt *parser_result, const char*); +void yyerror(const char*); + +extern int yylineno; + +struct stmt *parser_result = 0; + +%} + +// %parse-param {struct stmt *parser_result} + +%debug +%define parse.error detailed + +%token TOKEN_EOF +%token TOKEN_KEYWORD_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_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_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_ADD +%token TOKEN_SUB +%token TOKEN_MULTIPLY +%token TOKEN_DIVIDE +%token TOKEN_EQUAL +%token TOKEN_GREATER_THAN +%token TOKEN_LESS_THAN +%token TOKEN_EXPONENTIAL +%token TOKEN_DISPLAY + + +%% +file : statements + {parser_result = $1; return 0;} + ; +statements : statements statement + { $$ = $1; $1->next = $2; } + | statement + { $$ = $1; } + ; +statement : simple_stmt + {$$ = stmt_create(STMT_BLOCK, NULL, NULL, NULL, NULL, $1, NULL, NULL);} + ; +simple_stmt : cbl_func_stmt + {$$ = $1;} + ; +cbl_func_stmt : display_stmt + {$$ = $1;} + ; +display_stmt : TOKEN_DISPLAY expr + {$$ = stmt_create(STMT_PRINT, NULL, NULL, $2, NULL, NULL, NULL, NULL);} + ; +expr : TOKEN_STRING + { $$ = expr_create_string_literal(yytext);} + ; +%% + +void yyerror(const char* msg) { + fprintf(stderr, "Error | Line: %d\n%s\n",yylineno,msg); +} \ No newline at end of file From a3441f39c35c130f59d5cd2a803a48c0d83b6763 Mon Sep 17 00:00:00 2001 From: Riley Smith Date: Wed, 13 Nov 2024 22:42:07 -0800 Subject: [PATCH 17/21] hello world partially parses --- lab-5/Makefile | 7 ++- lab-5/expr.c | 10 ++++ lab-5/expr.h | 2 +- lab-5/main.c | 2 +- lab-5/parser.bison | 32 ++++++------ lab-5/parser_test.c | 123 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 156 insertions(+), 20 deletions(-) create mode 100644 lab-5/parser_test.c diff --git a/lab-5/Makefile b/lab-5/Makefile index 0361623..4c4f16d 100644 --- a/lab-5/Makefile +++ b/lab-5/Makefile @@ -2,17 +2,20 @@ # The top level rule indicates how to link everything together into main 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 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 # 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 $@ + gcc -g3 -Wall -c $< -o $@ # Only the files generated by flex and bison need explicit rules. diff --git a/lab-5/expr.c b/lab-5/expr.c index 6b0e94d..c9d6660 100644 --- a/lab-5/expr.c +++ b/lab-5/expr.c @@ -122,6 +122,8 @@ between the left and right nodes. void stmt_print(struct stmt *s) { if (!s) return; + + printf("stmt_print: %d\n", s->kind); switch (s->kind) { case STMT_DECL: @@ -146,6 +148,12 @@ void stmt_print(struct stmt *s) { case STMT_BLOCK: stmt_print(s->body); 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); @@ -271,6 +279,8 @@ void stmt_evaluate(struct stmt *s) { case STMT_BLOCK: stmt_evaluate(s->body); break; + case STMT_SECTION: + break; } stmt_evaluate(s->next); diff --git a/lab-5/expr.h b/lab-5/expr.h index 99d8461..42d0863 100644 --- a/lab-5/expr.h +++ b/lab-5/expr.h @@ -60,7 +60,7 @@ struct decl { 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 { stmt_t kind; diff --git a/lab-5/main.c b/lab-5/main.c index 1a4d24d..cc05425 100644 --- a/lab-5/main.c +++ b/lab-5/main.c @@ -26,7 +26,7 @@ int main(int argc, char *argv[]) { if (yyparse() == 0) { printf("Parse successful: "); - if (parser_result != NULL) { + if (parser_result != NULL) { stmt_print(parser_result); printf("\n"); printf("Running the program, results in: "); diff --git a/lab-5/parser.bison b/lab-5/parser.bison index 480271d..0699648 100644 --- a/lab-5/parser.bison +++ b/lab-5/parser.bison @@ -19,7 +19,6 @@ Clunky: Manually declare the interface to the scanner generated by flex. extern char *yytext; extern int yylex(); -// void yyerror(struct stmt *parser_result, const char*); void yyerror(const char*); extern int yylineno; @@ -28,8 +27,6 @@ struct stmt *parser_result = 0; %} -// %parse-param {struct stmt *parser_result} - %debug %define parse.error detailed @@ -86,30 +83,37 @@ struct stmt *parser_result = 0; %token TOKEN_DISPLAY + %% -file : statement_list - {parser_result = $1; return 0;} +file : statement_list + {parser_result = $1; return 0;} ; -statement_list : statement_list statement - { $$ = $1; $1->next = $2; } +statement_list : statement statement_list + { $$ = $1; $1->next = $2; } | statement - { $$ = $1; } + { $$ = $1; } ; statement : section + {$$ = $1;} | sect_data + {$$ = $1;} | simple_stmt {$$ = stmt_create(STMT_BLOCK, NULL, NULL, NULL, NULL, $1, NULL, NULL);} | data_space + {$$ = stmt_create(STMT_SECTION, NULL, NULL, NULL, NULL, NULL, NULL, NULL);} | data_declaration + {$$ = stmt_create(STMT_BLOCK, NULL, NULL, NULL, NULL, $1, NULL, NULL);} ; 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 + {$$ = stmt_create(STMT_SECTION, NULL, NULL, NULL, NULL, NULL, NULL, NULL);} ; type : TOKEN_KEYWORD_IDENTIFICATION | TOKEN_PROCEDURE - | TOKEN_STOP | TOKEN_KEYWORD_DATA ; simple_stmt : cbl_func_stmt @@ -163,9 +167,9 @@ booleanexpr : mathmaticalexpr TOKEN_LESS_THAN term type_expr : TOKEN_IDENT {$$ = expr_create_name(yytext);} | TOKEN_INTEGER - {$$ = expr_create_integer_literal(yytext);} + {$$ = expr_create_integer_literal(atoi(yytext));} | TOKEN_STRING - {$$ = expr_create_string_literal(atoi(yytext));} + {$$ = expr_create_string_literal(yytext);} | TOKEN_SPACE {$$ = expr_create_integer_literal(0);} | TOKEN_SUB TOKEN_IDENT @@ -225,10 +229,6 @@ data_declaration: simple_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) { fprintf(stderr, "Error | Line: %d\n%s\n",yylineno,msg); } \ No newline at end of file diff --git a/lab-5/parser_test.c b/lab-5/parser_test.c new file mode 100644 index 0000000..c9c8fe6 --- /dev/null +++ b/lab-5/parser_test.c @@ -0,0 +1,123 @@ +// https://github.com/sheredom/utest.h/blob/master/utest.h +#include "utest.h" +#include "expr.h" +#include + +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); +} From 8ab4a56aade0582f9345fe91792996f6d80efd3e Mon Sep 17 00:00:00 2001 From: Riley Smith Date: Wed, 13 Nov 2024 23:20:31 -0800 Subject: [PATCH 18/21] fix lab-3 + add back else to our parsing --- lab-3/main.c | 2 +- lab-3/main_test.c | 23 ++++++++--------------- lab-3/scanner | Bin 53112 -> 71688 bytes lab-3/scanner.flex | 11 ++++++++--- lab-3/token.h | 1 + lab-5/expr.c | 6 +----- lab-5/main.c | 1 - lab-5/parser.bison | 16 ++++++++-------- lab-5/scanner.flex | 13 +++++++++---- 9 files changed, 36 insertions(+), 37 deletions(-) diff --git a/lab-3/main.c b/lab-3/main.c index 7e4a834..78770a1 100644 --- a/lab-3/main.c +++ b/lab-3/main.c @@ -25,6 +25,6 @@ int main(int argc, char *argv[]) { token_t t = yylex(); if (t == TOKEN_EOF) break; - printf("token: %d text: %s\n", t, yytext); + printf("token: %d, text: %s\n", t, yytext); } } diff --git a/lab-3/main_test.c b/lab-3/main_test.c index 1dd60bd..8f22d24 100644 --- a/lab-3/main_test.c +++ b/lab-3/main_test.c @@ -53,9 +53,6 @@ UTEST(scanner, hello) { 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_KEYWORD_IDENTIFICATION, "IDENTIFICATION"}, {TOKEN_KEYWORD_DIVISION, "DIVISION"}, {TOKEN_DOT, "."}, @@ -180,9 +177,8 @@ UTEST(scanner, quadratic) { {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_STRING, "\"EQUATION: (1x^2) + 5x + 6 = 0\""}, {TOKEN_KEYWORD_COMPUTE, "COMPUTE"}, {TOKEN_IDENT, "discriminant"}, {TOKEN_EQUAL, "="}, @@ -250,14 +246,14 @@ UTEST(scanner, quadratic) { {TOKEN_RIGHT_PARENTHESIS, ")"}, {TOKEN_DISPLAY, "DISPLAY"}, - {TOKEN_STRING, "'The equation has two distinct real roots: '"}, + {TOKEN_STRING, "\"The equation has two distinct real roots: \""}, {TOKEN_DISPLAY, "DISPLAY"}, - {TOKEN_STRING, "'Root 1: '"}, + {TOKEN_STRING, "\"Root 1: \""}, {TOKEN_IDENT, "root1"}, {TOKEN_DISPLAY, "DISPLAY"}, - {TOKEN_STRING, "'Root 2: '"}, + {TOKEN_STRING, "\"Root 2: \""}, {TOKEN_IDENT, "root2"}, // {TOKEN_EOF, ""}, @@ -282,17 +278,18 @@ UTEST(scanner, quadratic) { {TOKEN_DISPLAY, "DISPLAY"}, - {TOKEN_STRING, "'The equation has one real root: '"}, + {TOKEN_STRING, "\"The equation has one real root: \""}, {TOKEN_DISPLAY, "DISPLAY"}, - {TOKEN_STRING, "'Root: '"}, + {TOKEN_STRING, "\"Root: \""}, {TOKEN_IDENT, "root1"}, {TOKEN_ELSE, "ELSE"}, {TOKEN_DISPLAY, "DISPLAY"}, - {TOKEN_STRING, "'The equation has no real roots.'"}, + {TOKEN_STRING, "\"The equation has no real roots.\""}, + {TOKEN_END_IF, "END-IF"}, // {TOKEN_EOF, ""}, @@ -403,7 +400,6 @@ UTEST(scanner, sorting) { {TOKEN_PROCEDURE, "PROCEDURE"}, {TOKEN_KEYWORD_DIVISION, "DIVISION"}, {TOKEN_DOT, "."}, - {TOKEN_COMMENT, "*> Initialize test data"}, {TOKEN_MOVE, "MOVE"}, {TOKEN_STRING, "\"30\""}, {TOKEN_KEYWORD_TO, "TO"}, @@ -443,7 +439,6 @@ UTEST(scanner, sorting) { {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"}, @@ -470,7 +465,6 @@ UTEST(scanner, sorting) { {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"}, @@ -540,7 +534,6 @@ UTEST(scanner, sorting) { {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"}, diff --git a/lab-3/scanner b/lab-3/scanner index 896da2e7d112bdd9b0fd8bba5e7075c48dadba02..28ce88dba2b110110b8001bc3f96f5532b1f51a5 100755 GIT binary patch literal 71688 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 M82*0!X0p2f2P-r~Qvd(} literal 53112 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 M@bWG75niwV1Y6Sb^Z)<= diff --git a/lab-3/scanner.flex b/lab-3/scanner.flex index 4b7a148..262c437 100644 --- a/lab-3/scanner.flex +++ b/lab-3/scanner.flex @@ -1,6 +1,10 @@ %{ #include "token.h" %} +%option warn +%option nodefault +%option yylineno + NAME [a-zA-Z]([a-zA-Z0-9_-]*[a-zA-Z0-9])? DIGIT [0-9]+ %% @@ -26,6 +30,7 @@ UNTIL { return TOKEN_UNTIL; } PERFORM { return TOKEN_PERFORM; } END-PERFORM { return TOKEN_END_PERFORM; } IF { return TOKEN_IF; } +ELSE { return TOKEN_ELSE; } END-IF { return TOKEN_END_IF; } SPACE { return TOKEN_SPACE; } PIC { return TOKEN_PICTURE; } @@ -42,8 +47,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; } \- { return TOKEN_SUB; } \*\* { return TOKEN_EXPONENTIAL; } @@ -57,8 +61,9 @@ COMP-3 { return TOKEN_COMPUTATION_LEVEL_3; } "\'"[^']*"\'" { return TOKEN_STRING; } "(" { return TOKEN_LEFT_PARENTHESIS; } ")" { return TOKEN_RIGHT_PARENTHESIS; } +{NAME} { return TOKEN_IDENT; } +{DIGIT} { return TOKEN_INTEGER; } \. { return TOKEN_DOT; } - %% int yywrap() { return 1; } diff --git a/lab-3/token.h b/lab-3/token.h index 20c1ffa..47ce470 100644 --- a/lab-3/token.h +++ b/lab-3/token.h @@ -21,6 +21,7 @@ typedef enum { TOKEN_IF, TOKEN_ELSE, TOKEN_END_IF, + TOKEN_ELSE_IF, TOKEN_SPACE, TOKEN_KEYWORD_OCCURS, TOKEN_KEYWORD_VALUE, diff --git a/lab-5/expr.c b/lab-5/expr.c index c9d6660..c9c1733 100644 --- a/lab-5/expr.c +++ b/lab-5/expr.c @@ -123,7 +123,6 @@ void stmt_print(struct stmt *s) { if (!s) return; - printf("stmt_print: %d\n", s->kind); switch (s->kind) { case STMT_DECL: @@ -148,11 +147,8 @@ void stmt_print(struct stmt *s) { case STMT_BLOCK: stmt_print(s->body); break; + // we haven't implemented sections yet 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; } diff --git a/lab-5/main.c b/lab-5/main.c index cc05425..c0ba9d7 100644 --- a/lab-5/main.c +++ b/lab-5/main.c @@ -23,7 +23,6 @@ int main(int argc, char *argv[]) { printf( "Enter an infix expression using the operators +-*/() ending with ;\n\n"); - if (yyparse() == 0) { printf("Parse successful: "); if (parser_result != NULL) { diff --git a/lab-5/parser.bison b/lab-5/parser.bison index 0699648..01d6fa3 100644 --- a/lab-5/parser.bison +++ b/lab-5/parser.bison @@ -89,7 +89,7 @@ file : statement_list {parser_result = $1; return 0;} ; statement_list : statement statement_list - { $$ = $1; $1->next = $2; } + { $$ = $1; $1->next = $2;} | statement { $$ = $1; } ; @@ -98,7 +98,7 @@ statement : section | sect_data {$$ = $1;} | simple_stmt - {$$ = stmt_create(STMT_BLOCK, NULL, NULL, NULL, NULL, $1, NULL, NULL);} + {$$ = stmt_create(STMT_BLOCK, NULL, NULL, NULL, NULL, $1, NULL, NULL); printf("yytext1: %s\n", yytext);} | data_space {$$ = stmt_create(STMT_SECTION, NULL, NULL, NULL, NULL, NULL, NULL, NULL);} | data_declaration @@ -117,14 +117,14 @@ type : TOKEN_KEYWORD_IDENTIFICATION | TOKEN_KEYWORD_DATA ; simple_stmt : cbl_func_stmt - {$$ = $1;} + {$$ = $1; printf("yytext2: %s\n", yytext);} | if_branch | else_parts | perform_stmt ; cbl_func_stmt : cbl_function | cbl_function op_parms - {$$ = stmt_create($1->kind, NULL, NULL, $2, NULL, NULL, NULL, NULL);} + {$$ = stmt_create($1->kind, NULL, NULL, $2, NULL, NULL, NULL, NULL); printf("yytext3: %s\n", yytext);} | cbl_function assignment_stmt | cbl_function op_parm assignment_stmt ; @@ -132,12 +132,12 @@ assignment_stmt : TOKEN_EQUAL op_parms | TOKEN_KEYWORD_TO op_parms ; op_parms : op_parm - {$$ = $1;} + {$$ = $1; printf("yytext4: %s\n", yytext);} | op_parm op_parms {$$ = $1; $1->next_expr = $2;} ; op_parm : mathmaticalexpr - {$$ = $1;} + {$$ = $1; printf("yytext5: %s\n", yytext);} | booleanexpr {$$ = $1;} ; @@ -151,7 +151,7 @@ math_op : TOKEN_ADD | TOKEN_EXPONENTIAL ; mathmaticalexpr : type_expr - {$$ = $1;} + {$$ = $1; printf("yytext6: %s\n", yytext);} | mathmaticalexpr math_op term | container_expr {$$ = $1;} @@ -169,7 +169,7 @@ type_expr : TOKEN_IDENT | TOKEN_INTEGER {$$ = expr_create_integer_literal(atoi(yytext));} | TOKEN_STRING - {$$ = expr_create_string_literal(yytext);} + {$$ = expr_create_string_literal(yytext); printf("yytext7: %s\n", yytext);} | TOKEN_SPACE {$$ = expr_create_integer_literal(0);} | TOKEN_SUB TOKEN_IDENT diff --git a/lab-5/scanner.flex b/lab-5/scanner.flex index 4b7a148..528650c 100644 --- a/lab-5/scanner.flex +++ b/lab-5/scanner.flex @@ -1,6 +1,10 @@ %{ #include "token.h" %} +%option warn +%option nodefault +%option yylineno + NAME [a-zA-Z]([a-zA-Z0-9_-]*[a-zA-Z0-9])? DIGIT [0-9]+ %% @@ -26,6 +30,7 @@ UNTIL { return TOKEN_UNTIL; } PERFORM { return TOKEN_PERFORM; } END-PERFORM { return TOKEN_END_PERFORM; } IF { return TOKEN_IF; } +ELSE { return TOKEN_ELSE; } END-IF { return TOKEN_END_IF; } SPACE { return TOKEN_SPACE; } PIC { return TOKEN_PICTURE; } @@ -42,8 +47,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; } \- { return TOKEN_SUB; } \*\* { return TOKEN_EXPONENTIAL; } @@ -57,8 +61,9 @@ COMP-3 { return TOKEN_COMPUTATION_LEVEL_3; } "\'"[^']*"\'" { return TOKEN_STRING; } "(" { return TOKEN_LEFT_PARENTHESIS; } ")" { return TOKEN_RIGHT_PARENTHESIS; } +{NAME} { return TOKEN_IDENT; } +{DIGIT} { return TOKEN_INTEGER; } \. { return TOKEN_DOT; } - %% -int yywrap() { return 1; } +int yywrap() { return 1; } \ No newline at end of file From 312e06d12083353c157f7f15f06f825c5a5b3e50 Mon Sep 17 00:00:00 2001 From: Riley Smith Date: Wed, 13 Nov 2024 23:30:56 -0800 Subject: [PATCH 19/21] hello world parses properly --- lab-5/parser.bison | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/lab-5/parser.bison b/lab-5/parser.bison index 01d6fa3..3b76da2 100644 --- a/lab-5/parser.bison +++ b/lab-5/parser.bison @@ -4,6 +4,7 @@ #include #include #include +#include #include "expr.h" /* @@ -82,10 +83,8 @@ struct stmt *parser_result = 0; %token TOKEN_EXPONENTIAL %token TOKEN_DISPLAY - - %% -file : statement_list +file : statement_list stop_run {parser_result = $1; return 0;} ; statement_list : statement statement_list @@ -98,7 +97,7 @@ statement : section | sect_data {$$ = $1;} | simple_stmt - {$$ = stmt_create(STMT_BLOCK, NULL, NULL, NULL, NULL, $1, NULL, NULL); printf("yytext1: %s\n", yytext);} + {$$ = stmt_create(STMT_BLOCK, NULL, NULL, NULL, NULL, $1, NULL, NULL);} | data_space {$$ = stmt_create(STMT_SECTION, NULL, NULL, NULL, NULL, NULL, NULL, NULL);} | data_declaration @@ -106,7 +105,8 @@ statement : section ; section : type TOKEN_KEYWORD_DIVISION TOKEN_DOT {$$ = stmt_create(STMT_SECTION, NULL, NULL, NULL, NULL, NULL, NULL, NULL);} - | TOKEN_STOP TOKEN_RUN TOKEN_DOT + ; +stop_run : 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 @@ -117,14 +117,14 @@ type : TOKEN_KEYWORD_IDENTIFICATION | TOKEN_KEYWORD_DATA ; simple_stmt : cbl_func_stmt - {$$ = $1; printf("yytext2: %s\n", yytext);} + {$$ = $1;} | if_branch | else_parts | perform_stmt ; cbl_func_stmt : cbl_function | cbl_function op_parms - {$$ = stmt_create($1->kind, NULL, NULL, $2, NULL, NULL, NULL, NULL); printf("yytext3: %s\n", yytext);} + {$$ = stmt_create($1->kind, NULL, NULL, $2, NULL, NULL, NULL, NULL);} | cbl_function assignment_stmt | cbl_function op_parm assignment_stmt ; @@ -132,12 +132,12 @@ assignment_stmt : TOKEN_EQUAL op_parms | TOKEN_KEYWORD_TO op_parms ; op_parms : op_parm - {$$ = $1; printf("yytext4: %s\n", yytext);} + {$$ = $1;} | op_parm op_parms {$$ = $1; $1->next_expr = $2;} ; op_parm : mathmaticalexpr - {$$ = $1; printf("yytext5: %s\n", yytext);} + {$$ = $1;} | booleanexpr {$$ = $1;} ; @@ -151,7 +151,7 @@ math_op : TOKEN_ADD | TOKEN_EXPONENTIAL ; mathmaticalexpr : type_expr - {$$ = $1; printf("yytext6: %s\n", yytext);} + {$$ = $1;} | mathmaticalexpr math_op term | container_expr {$$ = $1;} @@ -169,11 +169,10 @@ type_expr : TOKEN_IDENT | TOKEN_INTEGER {$$ = expr_create_integer_literal(atoi(yytext));} | TOKEN_STRING - {$$ = expr_create_string_literal(yytext); printf("yytext7: %s\n", yytext);} + {char *str = malloc(strlen(yytext) + 1); strcpy(str, yytext); $$ = expr_create_string_literal(str);} | TOKEN_SPACE {$$ = expr_create_integer_literal(0);} | TOKEN_SUB TOKEN_IDENT - {$$ = expr_create_integer_literal(atoi(yytext) * -1);} | ext_function ; ext_function : TOKEN_KEYWORD_FUNCTION TOKEN_IDENT TOKEN_LEFT_PARENTHESIS TOKEN_IDENT TOKEN_RIGHT_PARENTHESIS From fc6c46c8b8d9aabd8b0f3a0ca6bf56a514500751 Mon Sep 17 00:00:00 2001 From: Riley Smith Date: Thu, 14 Nov 2024 11:12:37 -0800 Subject: [PATCH 20/21] mathematical expression --- lab-5/expr.c | 1 + lab-5/parser.bison | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/lab-5/expr.c b/lab-5/expr.c index c9c1733..1c690b0 100644 --- a/lab-5/expr.c +++ b/lab-5/expr.c @@ -149,6 +149,7 @@ void stmt_print(struct stmt *s) { break; // we haven't implemented sections yet case STMT_SECTION: + printf("section\n"); break; } diff --git a/lab-5/parser.bison b/lab-5/parser.bison index 3b76da2..5830e55 100644 --- a/lab-5/parser.bison +++ b/lab-5/parser.bison @@ -145,14 +145,20 @@ term : mathmaticalexpr {$$ = $1;} ; math_op : TOKEN_ADD + {$$ = expr_create(EXPR_ADD, NULL, NULL);} | TOKEN_SUB + {$$ = expr_create(EXPR_SUBTRACT, NULL, NULL);} | TOKEN_MULTIPLY + {$$ = expr_create(EXPR_MULTIPLY, NULL, NULL);} | TOKEN_DIVIDE + {$$ = expr_create(EXPR_DIVIDE, NULL, NULL);} | TOKEN_EXPONENTIAL + {$$ = expr_create(EXPR_EXPONENTIAL, NULL, NULL);} ; mathmaticalexpr : type_expr {$$ = $1;} | mathmaticalexpr math_op term + {$$ = expr_create($2->kind, $1, $3);} | container_expr {$$ = $1;} | type_expr container_expr @@ -161,8 +167,11 @@ mathmaticalexpr : type_expr container_expr : TOKEN_LEFT_PARENTHESIS mathmaticalexpr TOKEN_RIGHT_PARENTHESIS ; booleanexpr : mathmaticalexpr TOKEN_LESS_THAN term + {$$ = expr_create(EXPR_LESS_THAN, $1, $3);} | mathmaticalexpr TOKEN_GREATER_THAN term + {$$ = expr_create(EXPR_GREATER_THAN, $1, $3);} | mathmaticalexpr TOKEN_EQUAL term + {$$ = expr_create(EXPR_EQUAL, $1, $3);} ; type_expr : TOKEN_IDENT {$$ = expr_create_name(yytext);} From 4ee4bf6919017ac9bc631199392c3fc5f203a4d3 Mon Sep 17 00:00:00 2001 From: Riley Smith Date: Thu, 14 Nov 2024 11:23:37 -0800 Subject: [PATCH 21/21] add move & compute stmts --- lab-5/expr.c | 4 +++- lab-5/expr.h | 12 +++++++++++- lab-5/parser.bison | 9 ++++++--- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/lab-5/expr.c b/lab-5/expr.c index 1c690b0..1bbd990 100644 --- a/lab-5/expr.c +++ b/lab-5/expr.c @@ -85,7 +85,9 @@ struct expr *expr_create_float_literal(float value) { struct expr *expr_create_string_literal(const char *value) { struct expr *e = expr_create(EXPR_STRING_LITERAL, 0, 0); - e->string_literal = value; + char *dest = malloc(sizeof(*value)); + strcpy(dest, value); // copy contents of source to dest + e->string_literal = dest; return e; } diff --git a/lab-5/expr.h b/lab-5/expr.h index 42d0863..bf404b4 100644 --- a/lab-5/expr.h +++ b/lab-5/expr.h @@ -20,6 +20,7 @@ typedef enum { EXPR_ADD, EXPR_ARRAY, EXPR_DIVIDE, + EXPR_EXPONENTIAL, EXPR_EQUAL_EQUAL, EXPR_FLOAT_LITERAL, EXPR_GREATER_THAN, @@ -60,7 +61,16 @@ struct decl { struct decl *next; }; -typedef enum { STMT_BLOCK, STMT_DECL, STMT_EXPR, STMT_IF, STMT_PRINT, STMT_SECTION } stmt_t; +typedef enum { + STMT_BLOCK, + STMT_DECL, + STMT_EXPR, + STMT_IF, + STMT_PRINT, + STMT_SECTION, + STMT_COMPUTE, + STMT_MOVE +} stmt_t; struct stmt { stmt_t kind; diff --git a/lab-5/parser.bison b/lab-5/parser.bison index 5830e55..79ffcd0 100644 --- a/lab-5/parser.bison +++ b/lab-5/parser.bison @@ -158,7 +158,7 @@ math_op : TOKEN_ADD mathmaticalexpr : type_expr {$$ = $1;} | mathmaticalexpr math_op term - {$$ = expr_create($2->kind, $1, $3);} + | container_expr {$$ = $1;} | type_expr container_expr @@ -171,25 +171,28 @@ booleanexpr : mathmaticalexpr TOKEN_LESS_THAN term | mathmaticalexpr TOKEN_GREATER_THAN term {$$ = expr_create(EXPR_GREATER_THAN, $1, $3);} | mathmaticalexpr TOKEN_EQUAL term - {$$ = expr_create(EXPR_EQUAL, $1, $3);} + {$$ = expr_create(EXPR_EQUAL_EQUAL, $1, $3);} ; type_expr : TOKEN_IDENT {$$ = expr_create_name(yytext);} | TOKEN_INTEGER {$$ = expr_create_integer_literal(atoi(yytext));} | TOKEN_STRING - {char *str = malloc(strlen(yytext) + 1); strcpy(str, yytext); $$ = expr_create_string_literal(str);} + {$$ = expr_create_string_literal(yytext);} | TOKEN_SPACE {$$ = expr_create_integer_literal(0);} | TOKEN_SUB TOKEN_IDENT | ext_function ; ext_function : TOKEN_KEYWORD_FUNCTION TOKEN_IDENT TOKEN_LEFT_PARENTHESIS TOKEN_IDENT TOKEN_RIGHT_PARENTHESIS + ; cbl_function : TOKEN_DISPLAY {$$ = stmt_create(STMT_PRINT, NULL, NULL, NULL, NULL, NULL, NULL, NULL);} | TOKEN_MOVE + {$$ = stmt_create(STMT_MOVE, NULL, NULL, NULL, NULL, NULL, NULL, NULL);} | TOKEN_KEYWORD_COMPUTE + {$$ = stmt_create(STMT_COMPUTE, NULL, NULL, NULL, NULL, NULL, NULL, NULL);} ; if_branch : TOKEN_IF booleanexpr ;