2 changed files with 105 additions and 0 deletions
@ -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 |
@ -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 |
Loading…
Reference in new issue