/* Require bison minimal version */ %require "3.2" /* write out a header file containing the token defines */ %header // Code for the header file generated by bison %code requires { typedef void* yyscan_t; struct parser_state { unsigned long tmp_val; unsigned long* calorie_list; unsigned long size; }; } // Code for the c file %{ #include #include #include "parser.h" #include "lexer.h" void push_value(struct parser_state* state) { // TODO(feliix42): error handling here? state->calorie_list = realloc(state->calorie_list, (state->size+1) * sizeof(unsigned long)); state->calorie_list[state->size] = state->tmp_val; state->tmp_val = 0; state->size++; } void yyerror(struct parser_state* state, yyscan_t scanner, const char* msg) { (void)state; (void)scanner; fprintf(stderr, "\033[93mSyntax Error: %s\033[0m\n", msg); } %} // define a reentrant parser %define api.pure // enable parser tracing and detailed error messages (plus Lookahead Correction) %define parse.trace %define parse.error detailed %define parse.lac full %lex-param { yyscan_t scanner } %parse-param { struct parser_state* state } %parse-param { yyscan_t scanner } %union { unsigned long num; } %start input %token NEWLINE %token NUMBER %term END_OF_FILE %% input : line input | END_OF_FILE { if (state->tmp_val != 0) { push_value(state); } return 0; } ; line : NUMBER NEWLINE { state->tmp_val += $1; } | NEWLINE { push_value(state); } ; %% int main(void) { struct parser_state* parser_state = calloc(1, sizeof(struct parser_state)); if (!parser_state) { fprintf(stderr, "[error] failed to allocate parser state\n"); return EXIT_FAILURE; } yyscan_t scanner; /*YY_BUFFER_STATE state;*/ if (yylex_init(&scanner)) { fprintf(stderr, "\033[91m[error] Could not initialize lexer\n"); return EXIT_FAILURE; } if (yyparse(parser_state, scanner)) { // TODO: Error handling https://www.gnu.org/software/bison/manual/html_node/Parser-Function.html // error during parse occured return EXIT_FAILURE; } yylex_destroy(scanner); // task 1.1 unsigned long max_val = 0; for (unsigned long i = 0; i < parser_state->size; i++) { if (parser_state->calorie_list[i] > max_val) { max_val = parser_state->calorie_list[i]; } } printf("Largest individual calorie load: %lu\n", max_val); return 0; }