From a1385956ce74601a1bb54c0ebc60025133d6b007 Mon Sep 17 00:00:00 2001 From: Felix Suchert Date: Wed, 28 Dec 2022 02:48:00 +0100 Subject: [PATCH] add solution for day 5, task 1 --- day_5/Makefile | 56 ++++++ day_5/input.txt | 513 ++++++++++++++++++++++++++++++++++++++++++++++++ day_5/lexer.l | 68 +++++++ day_5/parser.y | 177 +++++++++++++++++ 4 files changed, 814 insertions(+) create mode 100644 day_5/Makefile create mode 100644 day_5/input.txt create mode 100644 day_5/lexer.l create mode 100644 day_5/parser.y diff --git a/day_5/Makefile b/day_5/Makefile new file mode 100644 index 0000000..aef3d04 --- /dev/null +++ b/day_5/Makefile @@ -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_5 + +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} diff --git a/day_5/input.txt b/day_5/input.txt new file mode 100644 index 0000000..5005a4f --- /dev/null +++ b/day_5/input.txt @@ -0,0 +1,513 @@ + [H] [D] [P] +[W] [B] [C] [Z] [D] +[T] [J] [T] [J] [D] [J] +[H] [Z] [H] [H] [W] [S] [M] +[P] [F] [R] [P] [Z] [F] [W] [F] +[J] [V] [T] [N] [F] [G] [Z] [S] [S] +[C] [R] [P] [S] [V] [M] [V] [D] [Z] +[F] [G] [H] [Z] [N] [P] [M] [N] [D] + 1 2 3 4 5 6 7 8 9 + +move 2 from 8 to 2 +move 3 from 9 to 2 +move 1 from 3 to 8 +move 5 from 1 to 7 +move 2 from 9 to 2 +move 8 from 2 to 4 +move 6 from 7 to 2 +move 2 from 1 to 7 +move 4 from 5 to 9 +move 4 from 5 to 6 +move 1 from 8 to 3 +move 1 from 8 to 5 +move 2 from 9 to 8 +move 8 from 6 to 4 +move 4 from 3 to 6 +move 10 from 2 to 3 +move 1 from 5 to 1 +move 1 from 7 to 4 +move 2 from 9 to 8 +move 18 from 4 to 8 +move 1 from 1 to 6 +move 4 from 7 to 3 +move 12 from 8 to 4 +move 4 from 7 to 9 +move 5 from 6 to 9 +move 2 from 2 to 7 +move 3 from 9 to 5 +move 3 from 5 to 9 +move 1 from 2 to 8 +move 10 from 3 to 1 +move 2 from 7 to 8 +move 10 from 1 to 9 +move 1 from 3 to 5 +move 16 from 9 to 8 +move 1 from 3 to 2 +move 3 from 8 to 3 +move 1 from 5 to 9 +move 3 from 6 to 7 +move 2 from 7 to 2 +move 1 from 3 to 8 +move 5 from 4 to 1 +move 4 from 9 to 5 +move 2 from 2 to 5 +move 2 from 1 to 9 +move 23 from 8 to 4 +move 6 from 5 to 2 +move 5 from 2 to 6 +move 1 from 9 to 6 +move 2 from 2 to 4 +move 35 from 4 to 9 +move 1 from 6 to 1 +move 2 from 8 to 7 +move 1 from 6 to 8 +move 3 from 1 to 7 +move 1 from 7 to 1 +move 3 from 6 to 2 +move 4 from 3 to 7 +move 6 from 7 to 9 +move 1 from 6 to 9 +move 1 from 8 to 1 +move 2 from 2 to 9 +move 2 from 8 to 2 +move 3 from 7 to 3 +move 2 from 1 to 9 +move 5 from 9 to 3 +move 1 from 4 to 2 +move 1 from 1 to 4 +move 7 from 3 to 9 +move 1 from 3 to 4 +move 2 from 4 to 7 +move 24 from 9 to 4 +move 12 from 9 to 3 +move 1 from 3 to 1 +move 1 from 1 to 2 +move 2 from 2 to 6 +move 1 from 6 to 5 +move 1 from 6 to 8 +move 3 from 2 to 4 +move 1 from 7 to 4 +move 1 from 5 to 3 +move 1 from 9 to 8 +move 23 from 4 to 8 +move 17 from 8 to 5 +move 12 from 9 to 8 +move 10 from 8 to 7 +move 1 from 8 to 6 +move 5 from 4 to 3 +move 3 from 5 to 1 +move 3 from 1 to 6 +move 6 from 5 to 4 +move 10 from 3 to 1 +move 9 from 1 to 7 +move 2 from 4 to 9 +move 1 from 1 to 6 +move 4 from 8 to 1 +move 4 from 3 to 7 +move 4 from 6 to 5 +move 1 from 9 to 6 +move 1 from 9 to 2 +move 1 from 1 to 7 +move 1 from 2 to 7 +move 3 from 1 to 7 +move 9 from 5 to 9 +move 7 from 9 to 7 +move 2 from 9 to 1 +move 3 from 5 to 9 +move 3 from 4 to 8 +move 1 from 1 to 2 +move 1 from 2 to 6 +move 1 from 1 to 6 +move 5 from 8 to 7 +move 1 from 8 to 1 +move 1 from 3 to 9 +move 1 from 1 to 6 +move 2 from 9 to 5 +move 2 from 3 to 9 +move 4 from 6 to 3 +move 1 from 9 to 4 +move 2 from 4 to 8 +move 1 from 4 to 8 +move 1 from 9 to 5 +move 1 from 6 to 8 +move 23 from 7 to 8 +move 27 from 8 to 2 +move 2 from 8 to 1 +move 23 from 2 to 6 +move 3 from 5 to 3 +move 4 from 2 to 5 +move 2 from 3 to 1 +move 2 from 9 to 3 +move 4 from 1 to 4 +move 13 from 7 to 9 +move 1 from 5 to 6 +move 2 from 5 to 9 +move 1 from 5 to 3 +move 3 from 9 to 3 +move 5 from 9 to 5 +move 2 from 4 to 2 +move 1 from 4 to 9 +move 11 from 6 to 9 +move 9 from 6 to 1 +move 17 from 9 to 5 +move 3 from 7 to 4 +move 3 from 6 to 3 +move 14 from 5 to 2 +move 5 from 3 to 1 +move 2 from 9 to 4 +move 2 from 3 to 8 +move 5 from 5 to 9 +move 2 from 5 to 4 +move 7 from 1 to 8 +move 2 from 9 to 5 +move 3 from 9 to 8 +move 8 from 4 to 2 +move 2 from 7 to 8 +move 10 from 2 to 9 +move 10 from 2 to 6 +move 8 from 9 to 7 +move 2 from 3 to 9 +move 3 from 9 to 8 +move 5 from 3 to 9 +move 7 from 7 to 9 +move 3 from 2 to 9 +move 10 from 8 to 5 +move 1 from 7 to 6 +move 1 from 2 to 3 +move 4 from 1 to 6 +move 2 from 8 to 4 +move 1 from 4 to 6 +move 2 from 6 to 3 +move 2 from 3 to 1 +move 1 from 4 to 9 +move 4 from 1 to 5 +move 2 from 5 to 2 +move 2 from 8 to 4 +move 1 from 3 to 5 +move 3 from 5 to 7 +move 2 from 2 to 9 +move 3 from 7 to 6 +move 3 from 8 to 5 +move 10 from 5 to 7 +move 3 from 6 to 4 +move 11 from 6 to 1 +move 3 from 6 to 2 +move 12 from 1 to 3 +move 1 from 7 to 5 +move 9 from 7 to 3 +move 5 from 5 to 1 +move 4 from 4 to 6 +move 2 from 1 to 7 +move 1 from 2 to 6 +move 2 from 7 to 8 +move 1 from 2 to 4 +move 1 from 9 to 5 +move 3 from 6 to 7 +move 1 from 5 to 2 +move 9 from 9 to 5 +move 1 from 2 to 8 +move 1 from 4 to 8 +move 1 from 1 to 8 +move 1 from 4 to 2 +move 1 from 7 to 2 +move 1 from 6 to 2 +move 1 from 6 to 8 +move 6 from 9 to 6 +move 1 from 3 to 4 +move 9 from 3 to 5 +move 1 from 1 to 3 +move 2 from 2 to 6 +move 1 from 3 to 5 +move 14 from 5 to 1 +move 1 from 2 to 6 +move 5 from 6 to 4 +move 3 from 8 to 2 +move 5 from 6 to 1 +move 5 from 4 to 6 +move 1 from 7 to 1 +move 3 from 9 to 3 +move 7 from 5 to 7 +move 1 from 4 to 6 +move 2 from 7 to 5 +move 3 from 6 to 1 +move 3 from 8 to 1 +move 14 from 3 to 4 +move 8 from 4 to 2 +move 1 from 6 to 1 +move 15 from 1 to 6 +move 7 from 1 to 6 +move 6 from 1 to 3 +move 3 from 3 to 1 +move 2 from 4 to 5 +move 1 from 4 to 2 +move 19 from 6 to 8 +move 2 from 1 to 8 +move 4 from 5 to 4 +move 7 from 8 to 2 +move 2 from 3 to 1 +move 13 from 8 to 6 +move 4 from 4 to 9 +move 2 from 4 to 8 +move 2 from 1 to 6 +move 1 from 3 to 5 +move 19 from 2 to 3 +move 13 from 3 to 1 +move 1 from 4 to 9 +move 1 from 2 to 8 +move 3 from 7 to 1 +move 14 from 6 to 9 +move 2 from 6 to 4 +move 18 from 9 to 4 +move 3 from 7 to 2 +move 15 from 1 to 4 +move 2 from 1 to 8 +move 5 from 3 to 1 +move 1 from 3 to 6 +move 5 from 8 to 9 +move 3 from 9 to 5 +move 1 from 9 to 5 +move 1 from 8 to 9 +move 1 from 6 to 2 +move 3 from 9 to 4 +move 2 from 6 to 7 +move 30 from 4 to 6 +move 22 from 6 to 9 +move 6 from 9 to 4 +move 4 from 6 to 7 +move 1 from 1 to 6 +move 1 from 9 to 8 +move 1 from 7 to 6 +move 3 from 5 to 3 +move 5 from 6 to 5 +move 2 from 7 to 9 +move 4 from 1 to 5 +move 1 from 6 to 4 +move 1 from 8 to 7 +move 2 from 6 to 4 +move 17 from 9 to 8 +move 2 from 2 to 7 +move 2 from 3 to 1 +move 8 from 4 to 8 +move 1 from 3 to 8 +move 8 from 4 to 2 +move 2 from 1 to 2 +move 1 from 4 to 6 +move 4 from 7 to 1 +move 1 from 6 to 8 +move 19 from 8 to 3 +move 5 from 5 to 1 +move 5 from 5 to 9 +move 2 from 9 to 3 +move 6 from 1 to 9 +move 1 from 7 to 5 +move 1 from 7 to 4 +move 2 from 5 to 7 +move 2 from 2 to 4 +move 4 from 9 to 8 +move 12 from 8 to 7 +move 2 from 1 to 9 +move 1 from 7 to 4 +move 4 from 4 to 5 +move 3 from 9 to 3 +move 9 from 2 to 6 +move 2 from 7 to 5 +move 1 from 1 to 9 +move 5 from 9 to 7 +move 9 from 6 to 2 +move 6 from 2 to 8 +move 21 from 3 to 2 +move 12 from 2 to 9 +move 3 from 5 to 9 +move 3 from 3 to 8 +move 5 from 9 to 6 +move 13 from 2 to 3 +move 3 from 6 to 2 +move 10 from 9 to 8 +move 6 from 3 to 1 +move 3 from 2 to 9 +move 2 from 6 to 7 +move 5 from 3 to 9 +move 4 from 1 to 9 +move 3 from 8 to 5 +move 1 from 1 to 7 +move 6 from 5 to 7 +move 12 from 9 to 7 +move 1 from 1 to 8 +move 11 from 8 to 5 +move 9 from 5 to 7 +move 1 from 3 to 1 +move 4 from 8 to 7 +move 1 from 1 to 7 +move 2 from 8 to 3 +move 42 from 7 to 4 +move 3 from 7 to 9 +move 4 from 7 to 5 +move 1 from 7 to 8 +move 1 from 8 to 5 +move 1 from 7 to 5 +move 1 from 3 to 4 +move 1 from 3 to 9 +move 1 from 9 to 6 +move 1 from 6 to 4 +move 1 from 3 to 5 +move 3 from 9 to 2 +move 16 from 4 to 8 +move 3 from 2 to 4 +move 1 from 5 to 4 +move 30 from 4 to 6 +move 15 from 8 to 3 +move 2 from 4 to 5 +move 1 from 8 to 7 +move 13 from 3 to 6 +move 1 from 7 to 8 +move 1 from 3 to 8 +move 1 from 3 to 8 +move 4 from 5 to 2 +move 6 from 5 to 2 +move 2 from 8 to 6 +move 43 from 6 to 2 +move 1 from 6 to 1 +move 18 from 2 to 4 +move 24 from 2 to 6 +move 19 from 6 to 3 +move 4 from 6 to 3 +move 2 from 6 to 3 +move 3 from 3 to 2 +move 1 from 1 to 3 +move 23 from 3 to 6 +move 12 from 4 to 3 +move 7 from 3 to 9 +move 13 from 2 to 9 +move 1 from 8 to 4 +move 4 from 3 to 8 +move 6 from 4 to 2 +move 10 from 9 to 3 +move 6 from 2 to 9 +move 8 from 3 to 5 +move 3 from 5 to 3 +move 13 from 6 to 5 +move 4 from 3 to 9 +move 1 from 4 to 2 +move 4 from 8 to 3 +move 1 from 2 to 5 +move 14 from 9 to 5 +move 2 from 5 to 4 +move 2 from 4 to 3 +move 1 from 9 to 5 +move 4 from 6 to 1 +move 1 from 6 to 2 +move 6 from 3 to 2 +move 5 from 6 to 8 +move 2 from 3 to 7 +move 1 from 8 to 1 +move 25 from 5 to 7 +move 3 from 7 to 9 +move 5 from 2 to 9 +move 12 from 9 to 8 +move 3 from 1 to 6 +move 16 from 8 to 2 +move 1 from 9 to 2 +move 1 from 6 to 2 +move 1 from 1 to 3 +move 21 from 7 to 3 +move 2 from 7 to 1 +move 1 from 7 to 8 +move 2 from 2 to 1 +move 2 from 6 to 3 +move 18 from 2 to 9 +move 2 from 5 to 1 +move 1 from 2 to 1 +move 3 from 5 to 2 +move 13 from 9 to 1 +move 3 from 9 to 2 +move 1 from 8 to 7 +move 3 from 2 to 6 +move 2 from 5 to 1 +move 17 from 3 to 8 +move 3 from 3 to 8 +move 2 from 9 to 1 +move 1 from 7 to 5 +move 1 from 5 to 3 +move 2 from 6 to 4 +move 1 from 6 to 1 +move 15 from 8 to 2 +move 2 from 3 to 6 +move 1 from 8 to 5 +move 2 from 6 to 8 +move 13 from 2 to 9 +move 4 from 9 to 8 +move 9 from 8 to 9 +move 3 from 3 to 4 +move 4 from 9 to 7 +move 1 from 8 to 6 +move 1 from 7 to 5 +move 2 from 5 to 1 +move 1 from 6 to 3 +move 4 from 4 to 5 +move 1 from 4 to 6 +move 1 from 3 to 7 +move 1 from 5 to 6 +move 2 from 7 to 2 +move 4 from 2 to 3 +move 3 from 2 to 7 +move 1 from 3 to 6 +move 1 from 9 to 6 +move 2 from 5 to 2 +move 3 from 9 to 5 +move 1 from 6 to 1 +move 3 from 5 to 4 +move 12 from 1 to 2 +move 2 from 2 to 4 +move 2 from 7 to 8 +move 2 from 3 to 9 +move 1 from 4 to 7 +move 1 from 5 to 2 +move 1 from 8 to 3 +move 2 from 3 to 6 +move 7 from 2 to 8 +move 3 from 4 to 1 +move 7 from 8 to 5 +move 7 from 9 to 2 +move 1 from 4 to 5 +move 3 from 7 to 6 +move 5 from 6 to 9 +move 6 from 9 to 5 +move 4 from 9 to 6 +move 1 from 8 to 5 +move 1 from 7 to 4 +move 1 from 4 to 2 +move 2 from 2 to 9 +move 2 from 9 to 2 +move 11 from 5 to 3 +move 2 from 5 to 2 +move 1 from 2 to 9 +move 4 from 6 to 9 +move 1 from 2 to 9 +move 4 from 3 to 7 +move 3 from 6 to 4 +move 1 from 5 to 7 +move 18 from 1 to 3 +move 11 from 3 to 2 +move 1 from 7 to 9 +move 1 from 5 to 9 +move 14 from 3 to 6 +move 15 from 2 to 4 +move 5 from 2 to 5 +move 1 from 2 to 5 +move 1 from 1 to 9 +move 8 from 4 to 1 +move 5 from 5 to 9 +move 9 from 4 to 9 +move 4 from 7 to 4 +move 5 from 4 to 8 +move 2 from 9 to 6 +move 8 from 1 to 8 +move 1 from 5 to 3 +move 1 from 3 to 4 +move 1 from 1 to 8 +move 13 from 6 to 3 +move 9 from 9 to 5 +move 1 from 2 to 8 +move 8 from 5 to 1 +move 1 from 2 to 7 + diff --git a/day_5/lexer.l b/day_5/lexer.l new file mode 100644 index 0000000..cee6e83 --- /dev/null +++ b/day_5/lexer.l @@ -0,0 +1,68 @@ +%{ +#include +#include +#include "parser.h" +%} + +%option warn nodefault + +/* makes the scanner terminate after reaching <> 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] +SPACE [ ] +NUM [0-9] +CRATE_DELIM_OPEN "[" +CRATE_DELIM_CLOSE "]" +CRATE_ID [A-Z] + + +%% + +{NL} { + return NEWLINE; + } +{SPACE} { + return SPACE; + } +{NUM}+ { + unsigned long num = strtoul(yytext, NULL, 10); + yylval->num = num; + return NUMBER; + } +{CRATE_DELIM_OPEN} { + return CRATE_DELIM_OPEN; + } +{CRATE_DELIM_CLOSE} { + return CRATE_DELIM_CLOSE; + } +{CRATE_ID} { + yylval->cval = yytext[0]; + return CRATE_ID; + } +"move " { + return MOVE_OP; + } +" from " { + return ORIGIN; + } +" to " { + return DEST; + } +<> { + return END_OF_FILE; + } +. { + printf("[error] Encountered unexpected token %s\n", yytext); + return 0; + } + +%% diff --git a/day_5/parser.y b/day_5/parser.y new file mode 100644 index 0000000..c3869cc --- /dev/null +++ b/day_5/parser.y @@ -0,0 +1,177 @@ +/* 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; + + #define NUM_PILES 9 + + // a stack of crates, implemented as linked list (b/c it makes movement easier) + struct stack_item { + struct stack_item* next; + char crate_id; + }; + + struct parser_state { + // points to the topmost item in the stack + struct stack_item** stacks; + unsigned stack_idx; + }; +} + +// Code for the c file +%{ + #include + #include + #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 { + unsigned long num; + char cval; +} + + +%start input +%token NEWLINE SPACE +%token CRATE_DELIM_OPEN CRATE_DELIM_CLOSE +%token CRATE_ID +%token NUMBER +%token MOVE_OP ORIGIN DEST +%term END_OF_FILE + +%% + +input + : initialization NEWLINE movement END_OF_FILE { return 0; } + ; + +initialization + : line NEWLINE initialization + | line NEWLINE + ; + +line + : item SPACE line + | item + ; + +item + : CRATE_DELIM_OPEN CRATE_ID CRATE_DELIM_CLOSE { + // printf("Pushing %c onto stack #%lu\n", $2, state->stack_idx); + struct stack_item* it = calloc(1, sizeof(struct stack_item)); + // TODO(feliix42): error handling on failed alloc + it->crate_id = $2; + // mind we build the stack top down, which means we have to traverse it when adding a new elem + if (!state->stacks[state->stack_idx]) { + state->stacks[state->stack_idx] = it; + } else { + struct stack_item* tail = state->stacks[state->stack_idx]; + while (tail->next != NULL) { + tail = tail->next; + } + tail->next = it; + } + state->stack_idx = (state->stack_idx + 1) % NUM_PILES; + } + | SPACE NUMBER SPACE { + state->stack_idx = (state->stack_idx + 1) % NUM_PILES; + } + | SPACE SPACE SPACE { + state->stack_idx = (state->stack_idx + 1) % NUM_PILES; + } + ; + +movement + : expr NEWLINE movement + | expr NEWLINE + | NEWLINE + ; + +expr + : MOVE_OP NUMBER ORIGIN NUMBER DEST NUMBER { + // Source: $4, Dst: $6, repeat $2 times + // printf("move %lu from %lu to %lu", $2, $4, $6); + for (unsigned long i = 0; i < $2; i++) { + // get the current element + struct stack_item* it = state->stacks[$4 -1]; + + if (!it) { + // TODO(feliix42): use yyerror? + fprintf(stderr, "\033[91m[parser error] tried to pop from empty stack\n\033[0m"); + break; + } + + // delete old references + state->stacks[$4 -1] = it->next; + + // insert on new stack + it->next = state->stacks[$6 -1]; + state->stacks[$6 -1] = it; + } + } + ; + +%% + +int main(void) { + struct parser_state parser_state; + parser_state.stack_idx = 0; + + parser_state.stacks = calloc(NUM_PILES, sizeof(struct stack_item*)); + if (!parser_state.stacks) { + fprintf(stderr, "\033[91m[error] Could not initialize parser state\033[0m\n"); + return EXIT_FAILURE; + } + + 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("Top Stack IDs: "); + struct stack_item* cur; + for (int i = 0; i < NUM_PILES; i++) { + cur = parser_state.stacks[i]; + if (cur) { + printf("%c", cur->crate_id); + } else { + printf(" "); + } + } + printf("\n"); + + return 0; +}