From 7a8f46407a1aa015339bb3db4518b72187b69b8b Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Sun, 22 Jul 2018 16:15:15 -0700 Subject: [PATCH] Create a simple wrapper around liblex and libds. --- src/lex/lexer.cr | 50 +++++++++++++++++++++++++++++++++++++++++++ src/lex/lib.cr | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 src/lex/lexer.cr create mode 100644 src/lex/lib.cr diff --git a/src/lex/lexer.cr b/src/lex/lexer.cr new file mode 100644 index 0000000..f9caec8 --- /dev/null +++ b/src/lex/lexer.cr @@ -0,0 +1,50 @@ +require "./lib.cr" + +module Lex + class Lexer + def initialize + @config = LibLex::EvalConfig.new + LibLex.eval_config_init(pointerof(@config)) + end + + def add_pattern(pattern : String, id : Int32) + LibLex.eval_config_add(pointerof(@config), pattern, id) + end + + def lex(string) + # Initialize variables + tokens = [] of Tuple(String, Int32) + list = LibDs::Ll.new + + # Initialize the list the list + LibDs.ll_init(pointerof(list)) + # Perform the lexing operation + result = LibLex.eval_all(string, 0, + pointerof(@config), + pointerof(list)) + + # Transform void* matches into actual tuples. + if result == LibLex::Result::Success + node = list.head + while node + match = node.value.data.as(LibLex::Match*) + str = string[match.value.from...match.value.to] + tokens << { str, match.value.pattern } + node = node.value.next + end + end + + # Clean up. + LibDs.ll_foreach(pointerof(list), nil, + ->LibDs.compare_always, + ->LibLex.eval_foreach_match_free) + LibDs.ll_free(pointerof(list)) + + return tokens + end + + def finalize + LibLex.eval_config_free(pointerof(@config)) + end + end +end diff --git a/src/lex/lib.cr b/src/lex/lib.cr new file mode 100644 index 0000000..1fc7b38 --- /dev/null +++ b/src/lex/lib.cr @@ -0,0 +1,55 @@ +@[Link(ldflags: "#{__DIR__}/../../external/liblex/build/external/libds/libds.a")] +lib LibDs + struct LlNode + next: LlNode* + prev: LlNode* + data: Void* + end + + struct Ll + head: LlNode* + tail: LlNode* + end + + enum Result + Success, + Malloc + end + + fun compare_always(a: Void*, b: Void*): Int32 + + fun ll_init(list: Ll*) + fun ll_foreach(list: Ll*, compare_to: Void*, + compare: Void*, Void* -> Int32, + foreach: Void*, LibC::VaList-> Int32, ...): Int32 + fun ll_free(list: Ll*) +end + +@[Link(ldflags: "#{__DIR__}/../../external/liblex/build/liblex.a #{__DIR__}/../../external/liblex/build/external/libds/libds.a")] +lib LibLex + struct EvalConfig + stats: LibDs::Ll + end + + struct Match + from: LibC::SizeT + to: LibC::SizeT + pattern: Int32 + end + + enum Result + Success, + Malloc, + Invalid, + Unrecognized + end + + fun eval_config_init(config: EvalConfig*) + fun eval_config_add(config: EvalConfig*, string: UInt8*, id: Int32): Result + fun eval_all(string: UInt8*, index: LibC::SizeT, config: EvalConfig*, + matches: LibDs::Ll*): Result + fun eval_config_remove(config: EvalConfig*, string: UInt8*, + id: Int32): Result + fun eval_config_free(config: EvalConfig*): Result + fun eval_foreach_match_free(match: Void*, args: LibC::VaList): Int32 +end