Create a simple wrapper around liblex and libds.
This commit is contained in:
parent
71a441f11d
commit
7a8f46407a
50
src/lex/lexer.cr
Normal file
50
src/lex/lexer.cr
Normal file
|
@ -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
|
55
src/lex/lib.cr
Normal file
55
src/lex/lib.cr
Normal file
|
@ -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
Block a user