aoc-2022/day_2/parser.y

96 lines
2.2 KiB
Text

/* 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 total_score;
};
}
// Code for the c file
%{
#include <stdio.h>
#include <stdlib.h>
#include "parser.h"
#include "lexer.h"
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 }
%start input
%token NEWLINE
%token ROCK PAPER SCISSOR
%term END_OF_FILE
/* the format is: them<space>me */
%%
input
: line input
| END_OF_FILE { return 0; }
;
line
: game_move NEWLINE
;
game_move
: ROCK ROCK { state->total_score += 1 + 3; }
| ROCK PAPER { state->total_score += 2 + 6; }
| ROCK SCISSOR { state->total_score += 3 + 0; }
| PAPER ROCK { state->total_score += 1 + 0; }
| PAPER PAPER { state->total_score += 2 + 3; }
| PAPER SCISSOR { state->total_score += 3 + 6; }
| SCISSOR ROCK { state->total_score += 1 + 6; }
| SCISSOR PAPER { state->total_score += 2 + 0; }
| SCISSOR SCISSOR { state->total_score += 3 + 3; }
;
%%
int main(void) {
struct parser_state parser_state;
parser_state.total_score = 0;
yyscan_t scanner;
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 2
printf("total score: %lu\n", parser_state.total_score);
return 0;
}