day 6: task 1
This commit is contained in:
parent
c1f073246a
commit
8cb3eb85f5
4 changed files with 238 additions and 0 deletions
56
day_6/Makefile
Normal file
56
day_6/Makefile
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
CC := clang
|
||||||
|
YACC := bison
|
||||||
|
LEX := flex
|
||||||
|
CFLAGS := -std=c17 -Wpedantic -Wall -Wextra
|
||||||
|
BISONFLAGS :=
|
||||||
|
BUILD := ./build
|
||||||
|
INCLUDE := -I./
|
||||||
|
OBJ_DIR := $(BUILD)/objects
|
||||||
|
APP_DIR := $(BUILD)/bin
|
||||||
|
TARGET := day_6
|
||||||
|
|
||||||
|
SRC := $(wildcard ./*.cpp) lexer.c parser.c
|
||||||
|
|
||||||
|
OBJECTS := $(SRC:%.c=$(OBJ_DIR)/%.o)
|
||||||
|
|
||||||
|
# targets
|
||||||
|
all: build $(APP_DIR)/$(TARGET)
|
||||||
|
|
||||||
|
run: all
|
||||||
|
$(APP_DIR)/$(TARGET)
|
||||||
|
|
||||||
|
flex:
|
||||||
|
$(LEX) --outfile=lexer.c --header-file=lexer.h lexer.l
|
||||||
|
|
||||||
|
bison:
|
||||||
|
$(YACC) $(BISONFLAGS) --output=parser.c parser.y
|
||||||
|
|
||||||
|
generate: flex bison
|
||||||
|
|
||||||
|
$(OBJ_DIR)/%.o: %.c
|
||||||
|
@mkdir -p $(@D)
|
||||||
|
$(CC) $(CFLAGS) $(INCLUDE) -o $@ -c $<
|
||||||
|
|
||||||
|
$(APP_DIR)/$(TARGET): flex bison $(OBJECTS)
|
||||||
|
@mkdir -p $(@D)
|
||||||
|
$(CC) $(CFLAGS) $(INCLUDE) $(LDFLAGS) -o $(APP_DIR)/$(TARGET) $(OBJECTS)
|
||||||
|
|
||||||
|
.PHONY: all build clean debug release
|
||||||
|
|
||||||
|
build:
|
||||||
|
@mkdir -p $(APP_DIR)
|
||||||
|
@mkdir -p $(OBJ_DIR)
|
||||||
|
|
||||||
|
debug: CFLAGS += -DDEBUG -g
|
||||||
|
debug: BISONFLAGS += -Wcounterexamples
|
||||||
|
debug: all
|
||||||
|
|
||||||
|
sanitize: CFLAGS += -DDEBUG -g -fsanitize=address
|
||||||
|
sanitize: all
|
||||||
|
|
||||||
|
release: CFLAGS += -O2
|
||||||
|
release: all
|
||||||
|
|
||||||
|
clean:
|
||||||
|
-@rm -rvf $(BUILD)
|
||||||
|
-@rm -rvf {lexer.c,parser.c} {lexer.h,parser.h}
|
2
day_6/input.txt
Normal file
2
day_6/input.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
hrbbjllllspssblslvvrdrbbpbbmcccfppvbbwvbbmrmjrjrfrgfgbffgfqfqlltlwttscsncscchssrppffvwwvvpnnwwwpvwvhhnvhhbttvzzdlzdlzzwmmjhhznnjdnnnqddbtdbdbsdsmdsdrrdpdwpdppgcgqgcctftsfszslljbljbjwbwbnwnqqrnnztntmtrmmzwzdwzwgwwwjhjsjgjtjjhpjhhppqzqdqffrvrtvvsmmgwmgwgbbclltctptzpzhpzptzppcfpcfftflfzftztddzgzmmfsmsrmmsstttvbvmbvvsmsqmqlldjdtthwtwbwggrzzjrzrcctffsshqshhpthhlnhlhqhdqqrwrmmcttpfttzfzgzdgdzzwrrtsrrsnrnccrbbsssbpbjjvzzwlwtwjwsjwjggzqgzzrsszzjnzjzwjzzcrzczncnqqztzfzhfhvvtjvjdvjjmrjrppvzppczpczcggshghvhnhhsrsnsdszzdpzpzlpzzhwwmnwmwmcwwfnwfwjjcbcncllcsllqdqzzhqhmqmbbjvjjwwcjjpnpllzfzddtmtccqrcrtrwrpphpmpplslmltthnnvhhvrvbblhhrrdqqmbqqgtqggdgcdcvvsbsswvvpggbbtftlflglzlmlbbfhhrshswhshffhhdnnrfrvrmrnrprrmfmpmnpnfnggvvcncdcrczrzccpmmssrbbdjdtdrdwrrwhrrvrtvvszvvwvzzmhhjhhwlhlqlvlttzftztdtstftrfrdddmtmzzsqzqvvpdpdcpcncnrrtntznzrzgznztnznhhsqqnrqrhhlzhzthhfddrzdrrqmqggcmmllnjjvwwjccfjfqfcfzccwvcwvcvjcjtjtnnqsqmqrmrzrszrszzfwfggnmmcdmdjmmhwwgfwfnwnlwwcffsrffvnvbvnvwnwgnwnmmbzbmbpplmplpspzpmzpzdzgzrzrtrjrbbppwvwgwmggqwgghqqshhcwcqwcqcfcbbnsnrrtztzrtrvtvhthzhmmrqqrwqqsjqjcctgtwthhqmmnffmgmdgdlgljjhwjwggrqqfrqqjvqvhqqgsqsgsttmrrbprbppmjppslpsllvlfvlvrvhvtqmrjcdzwsbzfmgmwmwqwhztqrsdzhqjqvbjbntnbndflthljcczdmmhszfgsplrtlqnfzbrlqngwdqtfwcmrdjrsmdpmjmqwrbwfjzwnvqhfmlqtvvnlfzbfccwslqpbzzjccbvrzhghqwtvqgwrmsfzqnmnqqjsjtpcmngpqgllfsnpqtjjbqcdppnsmtwrslnrbqtwvnbctzvwfmgctscmzjbqqgqdwbpzmrdwgfcjzftzgmfcjhchbnmnqnrgtqngwrmncjvptqqdtjtgtpzzdrfsdgmwlwrjnqldbwrqjrhwcczlzvlhpgrnwzhbwjnpthggczfgtrjnzvnlfdfbwcnzfbwlwlmgnnjnpvhbhqgnzhqsnmvbcftsmrcgpvnnnmgnrvpbzlpwnbwpzmwpgqvbfgjwfrjqnvvgmqwwcfddqmdznmfhpjcfgptqdqwmplrglbwlmsqzjshrlhflcjvptgrcfhjfgqmlfzrtphpbvcqzwpcnwljjdlmqzhcctqshdngrgtlfsrfccdtlvmqcdgnpcvphdsrpzfzwclvsqcpzqlfvvqzggdhpfzdvhshglvfzfmcllrdfjfsjtngjgddcpqnlmrnplwtlvwdvzftltnsnspcdztgqhlhvvbnwvnmhscfnqbngpvprzfrjcmfpfzfftrlnwgllhnjndpjdrwcgqpcgcqngnbfzlvzvhnqdjthflmwvppmbdssddmgsbgrqnpjzrjpzdddqgsdlmwnhhpjbthclvqhgrsnrbqgtnsjhncnzbhrdgftvbptrqssvsqfpqnddhmgwcrfqndqjsqgffmhdvqhjrdlmrlcqctqccprwlbqgqrwmtfhwmfjfqzdqbsdsjbtsvfvgbsrvqwnqqqqthpsqgcfslsqtnjwtsrcdcctggdghrjwpbfccrtwgszwbrsjswmjmjbcqrsgbcfsdjzsbjnnssnddnnvwgftlrqvphnqcgjszscrlhhjnljlqcjqtqfwbmdmrgdlcqqwmbsmsdhpplvlfglqwspbfptlbzqjwhqmfvzvsvpjclcdzsbvntmhdqdvhghcmmflpjbglsghbswdshtsbdrgpsrsclrmfwwqbrgdjsqztgttqpwhnfhszlgbfpzhczsnwqflmshlgbrpmdzgpqwtsbssgfjbtrwbmztlwwfmsdgpgfgdjfdccwlfgztbcbqjvjtvslmddjplrswwcszspgplsrhrnwnmrrfbcgdmntcrlvnfqtwwcczsglrhtrfqnmhvgzjpmlplqvqhmnfgvzqcmzhqszgslvndqtqhvrbvbmclbcbjdswvcjrzgfdmdwnnlzlzqcffsrqdfmmpzfnmdsnqlpcrhzsdnsflblcjsfsgcnsspftjrlmdjsmfpqtmlgfvnlfnjscsgwzwvpjrvvclhsbqldlnmtglhbjfwlzmvrbvgtprfjbjhhnlqnbrswwlqtcgrjrltdrnfrjhrntllptlsbhqrwvdsfrlghtfcndznzjwcgmtdvffltgrdmljlqhdtmdvnfsfsrvdpmhlrrsttvqlwfptddwbpfrbclwwzmfpttmrmmqzjnbbnnfvzwmmcfshvrlbdbjzprftbqvdsghnnzwbjccpthdsvsdlgvphsgjdqjwsgmzqnqpqvgqjvwgjtzpmqqwnlwrwhqqjjclcbhjgpwhqdclwmqfmwbwmwwvcbhfznfhcfbprfcdqlbcttnvgnjwswcmpbrghtzgdbppbprffzjgvddzpwmdctrhnrfzdfhtmnfrsfdqvzcnrtncflhvldcndwqtvbggmwlzhchlcwtcbqcvlfhdwljgddwpvcfczvfqmphgtdsnsqwdpvvmwnwqjbrjwbdhhgtffphsdrvspsbgmfrmwmhnrgqdfppzgfpgmqjcsnglczgwhjthfhztzrlpgzjhcfrjpjvtjptptbvflftjtcfhmbwlhlbhvnjnbfmwjrgbvvhmdlncdgncgfjcnnpdljfcjsmsfscqpwsgcmlhhqmldsnjfrrqpghwncmgwgnjsdtvbhrbbnmpqjrrctqqnqzztmbqmdsgdvmmlwmbvprllzgntnmttrlzrttmjjlrwpwmtfznmwnsjmjhjdnsppfhcrjpzhjqzdtdbsjshfzzvrwvjbjbgtsfpgggbdztczwlhpmthfjdgsbrvlwmlrvgdrpjzccwmgpcnqqzmqdjqmwsrzwsmtmdjdhmjrwfwnzlmfnqtcgtslwtlnwhvmqntmglhntnsjlnmzfvfdztcfwmpchsrsdmqvqcwljzrmmssjvbmvvnmqlbsdwnrbmqctdtmfzlgfzpmjcnftgftvjpfbwwmzfdrrwjwcfwfcfmzbbnppgjrmbcvmvnjpdrzmvndvddtvshlnjjwgtsvnwtwnhcbfpnthpjlrhgrqccdgppjvdqjwqrfrrgnvhfwvjhnwhntnpmghphrtgqhwtbrqhqljfdjbgnlgmqqgfcqpqfhcpgspdbvlbfjvlrgmtjztwdzlrhqwwtcpdvsqgssjbjjgqlwbcctzzqvvmdzpfrmspmqhtzwgcfsslpnhpjfwqrrfbwbndrvhnnsjnlvlvqdsgwzjsrprhgtvsfbhbcpljdczbtdwzcnhzntrwcrjctmhtjfdlthznzmqblppzcqgpjhlzjrmcvpptfjjzltdhmvwphwlccscwrwfcqpqwwrzcmnltzdcfvtjrcvsqwtchrmdfzjmzjfhppjzbhglwqggzqqnspfmzrfwrqdqdrsdbsdhcgdqrrnjlwrqhfhpzjhrvjndqphndnnnbwhrjvqrrbvlhhbljjcwmfpvnhcszfshlsnczgtcfhjslbhzczdqdmdnvqdzhbmbpcnbntwgllfscrcwhfrgtfvftmwhbgfhjzjrbvvwc
|
||||||
|
|
41
day_6/lexer.l
Normal file
41
day_6/lexer.l
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
%{
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "parser.h"
|
||||||
|
%}
|
||||||
|
|
||||||
|
%option warn nodefault
|
||||||
|
|
||||||
|
/* makes the scanner terminate after reaching <<EOF>> instead of assuming a new input was provided */
|
||||||
|
%option noyywrap
|
||||||
|
/* disable some unused functionality, add scanner tracking */
|
||||||
|
%option nounput noinput batch debug
|
||||||
|
|
||||||
|
/* gimme a reentrant parser (overkill but more pure) */
|
||||||
|
%option reentrant
|
||||||
|
|
||||||
|
%option bison-bridge
|
||||||
|
|
||||||
|
|
||||||
|
NL [\n]
|
||||||
|
CHAR [a-z]
|
||||||
|
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
{NL} {
|
||||||
|
return NEWLINE;
|
||||||
|
}
|
||||||
|
{CHAR} {
|
||||||
|
yylval->cval = yytext[0];
|
||||||
|
return CHAR;
|
||||||
|
}
|
||||||
|
<<EOF>> {
|
||||||
|
return END_OF_FILE;
|
||||||
|
}
|
||||||
|
. {
|
||||||
|
printf("[error] Encountered unexpected token %s\n", yytext);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
%%
|
139
day_6/parser.y
Normal file
139
day_6/parser.y
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
/* 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 {
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
typedef void* yyscan_t;
|
||||||
|
|
||||||
|
struct parser_state {
|
||||||
|
// for storing the most recently read 4 chars
|
||||||
|
char buffer[4];
|
||||||
|
// location tracker
|
||||||
|
unsigned long loc;
|
||||||
|
bool found_start;
|
||||||
|
|
||||||
|
bool check_matrix[26];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Code for the c file
|
||||||
|
%{
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdbool.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 }
|
||||||
|
|
||||||
|
%union {
|
||||||
|
char cval;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
%start input
|
||||||
|
%token NEWLINE
|
||||||
|
%token <cval> CHAR
|
||||||
|
%term END_OF_FILE
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
input
|
||||||
|
: msg blanks END_OF_FILE { return 0; }
|
||||||
|
;
|
||||||
|
|
||||||
|
blanks
|
||||||
|
: NEWLINE blanks
|
||||||
|
| NEWLINE
|
||||||
|
;
|
||||||
|
|
||||||
|
msg
|
||||||
|
: bit msg
|
||||||
|
| bit
|
||||||
|
;
|
||||||
|
|
||||||
|
bit
|
||||||
|
: CHAR {
|
||||||
|
if (!state->found_start) {
|
||||||
|
state->loc++;
|
||||||
|
|
||||||
|
// left shift existing data
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
state->buffer[i] = state->buffer[i+1];
|
||||||
|
}
|
||||||
|
|
||||||
|
state->buffer[3] = $1;
|
||||||
|
|
||||||
|
// check whether condition is met
|
||||||
|
// offset array indices by the base -- 'a'
|
||||||
|
char offset = 'a';
|
||||||
|
|
||||||
|
state->found_start = true;
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
if (!state->check_matrix[state->buffer[i] - offset]) {
|
||||||
|
state->check_matrix[state->buffer[i] - offset] = true;
|
||||||
|
} else {
|
||||||
|
state->found_start = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// housekeeping; reset the fields to false
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
state->check_matrix[state->buffer[i] - offset] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
struct parser_state parser_state;
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
parser_state.buffer[i] = 'a';
|
||||||
|
}
|
||||||
|
parser_state.loc = 0;
|
||||||
|
parser_state.found_start = false;
|
||||||
|
|
||||||
|
yyscan_t scanner;
|
||||||
|
if (yylex_init(&scanner)) {
|
||||||
|
fprintf(stderr, "\033[91m[error] Could not initialize lexer\033[0m\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);
|
||||||
|
|
||||||
|
printf("First start-of-packet marker detected at: %lu\n", parser_state.loc);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in a new issue