aoc-2022/day_1/parser.y

125 lines
3.1 KiB
Text
Raw Permalink Normal View History

2022-12-25 20:15:50 +00:00
/* Require bison minimal version */
%require "3.2"
/* write out a header file containing the token defines */
%header
2022-12-25 22:09:12 +00:00
// 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;
};
}
2022-12-25 20:15:50 +00:00
// Code for the c file
%{
#include <stdio.h>
#include <stdlib.h>
#include "parser.h"
#include "lexer.h"
void push_value(struct parser_state* state) {
2022-12-25 22:38:20 +00:00
unsigned long* resized = realloc(state->calorie_list, (state->size+1) * sizeof(unsigned long));
if (!resized) {
fprintf(stderr, "\033[93m[error] Failed to allocate enough memory to resize the list of calories\033[0m\n");
return;
}
state->calorie_list = resized;
2022-12-25 20:15:50 +00:00
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
2022-12-25 22:09:12 +00:00
%token NEWLINE
%token <num> NUMBER
%term END_OF_FILE
2022-12-25 20:15:50 +00:00
%%
input
: line input
2022-12-25 22:09:12 +00:00
| END_OF_FILE { if (state->tmp_val != 0) { push_value(state); } return 0; }
2022-12-25 20:15:50 +00:00
;
line
2022-12-25 22:09:12 +00:00
: NUMBER NEWLINE { state->tmp_val += $1; }
2022-12-25 20:15:50 +00:00
| NEWLINE { push_value(state); }
;
%%
2022-12-25 22:09:12 +00:00
int main(void) {
2022-12-25 20:15:50 +00:00
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);
2022-12-25 22:31:24 +00:00
// task 1
unsigned long max_vals[3] = {0, 0, 0};
2022-12-25 22:09:12 +00:00
for (unsigned long i = 0; i < parser_state->size; i++) {
2022-12-25 22:31:24 +00:00
if (parser_state->calorie_list[i] > max_vals[0]) {
int y = 0;
while (y < 3 && parser_state->calorie_list[i] > max_vals[y+1]) {
y++;
}
for (int yx = 0; yx < y; yx++) {
max_vals[yx] = max_vals[yx+1];
}
max_vals[y] = parser_state->calorie_list[i];
2022-12-25 20:15:50 +00:00
}
}
2022-12-25 22:31:24 +00:00
printf("Largest individual calorie loads:\n%lu\n%lu\n%lu\n", max_vals[0], max_vals[1], max_vals[2]);
printf("-------------\n");
printf("total: %lu\n", max_vals[0] + max_vals[1] + max_vals[2]);
2022-12-25 20:15:50 +00:00
return 0;
}