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