51 lines
1.5 KiB
Crystal
51 lines
1.5 KiB
Crystal
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
|