lex/src/lex/lexer.cr

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