From 90c7998470f6e1c43011fd9a0892cff90b32105e Mon Sep 17 00:00:00 2001 From: jacekpoz Date: Sun, 3 Nov 2024 22:05:19 +0100 Subject: [PATCH] l2 --- flake.lock | 16 ---- flake.nix | 25 +------ l2/.gitignore | 1 + l2/1.l | 29 ++++++++ l2/2.l | 20 +++++ l2/3.l | 65 +++++++++++++++++ l2/4.l | 197 ++++++++++++++++++++++++++++++++++++++++++++++++++ l2/Makefile | 16 ++++ 8 files changed, 330 insertions(+), 39 deletions(-) create mode 100644 l2/.gitignore create mode 100644 l2/1.l create mode 100644 l2/2.l create mode 100644 l2/3.l create mode 100644 l2/4.l create mode 100644 l2/Makefile diff --git a/flake.lock b/flake.lock index febc559..0dbed83 100644 --- a/flake.lock +++ b/flake.lock @@ -1,20 +1,5 @@ { "nodes": { - "crane": { - "locked": { - "lastModified": 1729273024, - "narHash": "sha256-Mb5SemVsootkn4Q2IiY0rr9vrXdCCpQ9HnZeD/J3uXs=", - "owner": "ipetkov", - "repo": "crane", - "rev": "fa8b7445ddadc37850ed222718ca86622be01967", - "type": "github" - }, - "original": { - "owner": "ipetkov", - "repo": "crane", - "type": "github" - } - }, "fenix": { "inputs": { "nixpkgs": [ @@ -54,7 +39,6 @@ }, "root": { "inputs": { - "crane": "crane", "fenix": "fenix", "nixpkgs": "nixpkgs", "systems": "systems" diff --git a/flake.nix b/flake.nix index e16e104..01bfa87 100644 --- a/flake.nix +++ b/flake.nix @@ -4,7 +4,6 @@ inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; systems.url = "github:nix-systems/default"; - crane.url = "github:ipetkov/crane"; fenix = { url = "github:nix-community/fenix"; inputs.nixpkgs.follows = "nixpkgs"; @@ -12,31 +11,12 @@ }; }; - outputs = { self, nixpkgs, systems, crane, fenix, ... }: let + outputs = { nixpkgs, systems, fenix, ... }: let name = "jftt"; forEachSystem = nixpkgs.lib.genAttrs (import systems); pkgsForEach = nixpkgs.legacyPackages; in { - # packages = forEachSystem ( - # system: let - # pkgs = pkgsForEach.${system}; - # craneLib = (crane.mkLib pkgs).overrideToolchain ( - # fenix.packages.${system}.complete.withComponents [ - # "cargo" - # "rustc" - # "rust-src" - # ] - # ); - # in { - # default = craneLib.buildPackage { - # pname = name; - # version = "0.1.0"; - # src = craneLib.cleanCargoSource ./.; - # }; - # } - # ); - devShells = forEachSystem ( system: let pkgs = pkgsForEach.${system}; @@ -51,9 +31,8 @@ "rustc" "rust-src" ]) + flex ]; - - # inputsFrom = [ self.packages.${system}.default ]; }; } ); diff --git a/l2/.gitignore b/l2/.gitignore new file mode 100644 index 0000000..2f7896d --- /dev/null +++ b/l2/.gitignore @@ -0,0 +1 @@ +target/ diff --git a/l2/1.l b/l2/1.l new file mode 100644 index 0000000..547f578 --- /dev/null +++ b/l2/1.l @@ -0,0 +1,29 @@ +%{ + #include + + uint32_t line_count = 0; + uint32_t word_count = 0; +%} + +%% +^[[:blank:]]*\n +[[:blank:]]+$ +^[[:blank:]]+ +[[:blank:]]+ { putchar(' '); } +\n { line_count += 1; ECHO; } +[[:^space:]]+ { word_count += 1; ECHO; } +. { ECHO; } +%% + +// https://westes.github.io/flex/manual/Patterns.html + +#include + +int main(void) { + + yylex(); + + printf("%d %d\n", line_count, word_count); + + return EXIT_SUCCESS; +} diff --git a/l2/2.l b/l2/2.l new file mode 100644 index 0000000..e85f7b7 --- /dev/null +++ b/l2/2.l @@ -0,0 +1,20 @@ +%x COMMENT + +%% +"--" { BEGIN(COMMENT); } +"\n" { ECHO; BEGIN(INITIAL); } + +. { ECHO; } +. { } +%% + +// https://westes.github.io/flex/manual/Start-Conditions.html + +#include + +int main(void) { + + yylex(); + + return EXIT_SUCCESS; +} diff --git a/l2/3.l b/l2/3.l new file mode 100644 index 0000000..5a6d260 --- /dev/null +++ b/l2/3.l @@ -0,0 +1,65 @@ +%{ + #include + + bool leave_docs = false; +%} + +%x SINGLE_LINE +%x MULTI_LINE + +%% +"///"|"//!" { + if (leave_docs) { + ECHO; + } else { + BEGIN(SINGLE_LINE); + } +} + +"/**"|"/*!" { + if (leave_docs) { + ECHO; + } else { + BEGIN(MULTI_LINE); + } +} + +"//" { BEGIN(SINGLE_LINE); } +. { ECHO; } +\n { BEGIN(INITIAL); } +. { } + +"/*" { BEGIN(MULTI_LINE); } +"*/" { BEGIN(INITIAL); } +. { } +%% + +// single line comment + +/* + * multi line comment + */ + +/// single line doc 1 + +//! single line doc 2 + +/** + * multi line doc 1 + */ + +/*! + * multi line doc 2 + */ + +#include + +int main(int argc, char *argv[]) { + if (argc > 1) { + leave_docs = true; + } + + yylex(); + + return EXIT_SUCCESS; +} diff --git a/l2/4.l b/l2/4.l new file mode 100644 index 0000000..e190f76 --- /dev/null +++ b/l2/4.l @@ -0,0 +1,197 @@ +%{ +#include +#include +#include +#include +#include +#include + +typedef struct { + int64_t value; + bool exists; +} Option; + +uint64_t allocated = 0; +int64_t *bottom; +int64_t *top; + +void reset(void) { + top = bottom; +} + +void push(int64_t x) { + if (top >= bottom + allocated) { + errno = 0; + bottom = realloc(bottom, allocated * 2); + + if (errno == ENOMEM) { + fprintf(stderr, "failed reallocating stack!\n"); + exit(EXIT_FAILURE); + } + } + + *top = x; + top += 1; +} + +Option pop(void) { + if (top == bottom) { + printf("Błąd: za mała liczba argumentów\n"); + + reset(); + + return (Option){ + .value = 0, + .exists = false, + }; + } + + top -= 1; + return (Option){ + .value = *top, + .exists = true, + }; +} +%} + +%x ERROR + +%% +{ + -?[[:digit:]]+ { + errno = 0; + int64_t x = strtoll(yytext, NULL, 10); + + if (errno == ERANGE) { + if (x == LLONG_MIN) { + printf("Błąd: zbyt mała liczba\n"); + } else if (x == LLONG_MAX) { + printf("Błąd: zbyt duża liczba\n"); + } + reset(); + } else { + push(x); + } + } + + "+" { + Option x = pop(); + Option y = pop(); + + if (!x.exists || !y.exists) { + reset(); + BEGIN(ERROR); + } else { + push(y.value + x.value); + } + } + + "-" { + Option x = pop(); + Option y = pop(); + + if (!x.exists || !y.exists) { + reset(); + BEGIN(ERROR); + } else { + push(y.value - x.value); + } + } + + "*" { + Option x = pop(); + Option y = pop(); + + if (!x.exists || !y.exists) { + reset(); + BEGIN(ERROR); + } else { + push(y.value * x.value); + } + } + + "/" { + Option x = pop(); + Option y = pop(); + + if (!x.exists || !y.exists) { + reset(); + BEGIN(ERROR); + } else { + push(y.value / x.value); + } + } + + "%" { + Option x = pop(); + Option y = pop(); + + if (!x.exists || !y.exists) { + reset(); + BEGIN(ERROR); + } else { + push(y.value % x.value); + } + } + + "^" { + Option x = pop(); + Option y = pop(); + + if (!x.exists || !y.exists) { + reset(); + BEGIN(ERROR); + } else { + push((int64_t)powl((long double)y.value, (long double)x.value)); + } + } + + \n { + if (top > bottom + 1) { + printf("Błąd: za mała liczba operatorów\n"); + + reset(); + } else { + Option x = pop(); + + if (!x.exists) { + reset(); + BEGIN(ERROR); + } else { + printf("= %" PRId64 "\n", x.value); + } + } + } + + [[:blank:]]+ {} + + . { + printf("Błąd: zły symbol \"%s\"\n", yytext); + reset(); + BEGIN(ERROR); + } +} + +{ + \n { BEGIN(INITIAL); } + . { } +} +%% + +int main(void) { + allocated = 8; + bottom = (int64_t *)malloc(allocated * sizeof(int64_t)); + + if (bottom == NULL) { + fprintf(stderr, "failed allocating stack!\n"); + return EXIT_FAILURE; + } + + top = bottom; + + yylex(); + + free(bottom); + + return EXIT_SUCCESS; +} diff --git a/l2/Makefile b/l2/Makefile new file mode 100644 index 0000000..a3eed42 --- /dev/null +++ b/l2/Makefile @@ -0,0 +1,16 @@ +FLEX = flex +CC = gcc + +BIN = target + +all: dirs 1 2 3 4 + +dirs: + mkdir -p $(BIN) + +%: %.l + $(FLEX) -o $(BIN)/$@.lex.yy.c $< + $(CC) $(BIN)/$@.lex.yy.c -lfl -lm -o $(BIN)/$@ + +clean: + rm -rfv $(BIN)