Sim, embora seja muito simples, a lib consegue ser bem generalista.
O workflow dela é bem simples:
Primeiro você define um LexTypeArray, que contem as regras pra cada token. Cada regra é basicamente uma função q lê a entrada e retorna o tamanho da match. A própria lib ja vem com algumas prontas pra coisas comuns tipo white-space e identificadores.
So com isso, tu ja cria o lexer:
Lex lex = lex_init(tkarray, "codigo a ser tokenizado");
Pra consumir os tokes é bem simples, tem basicamente 3 funções:
primeiro tu usa lex_current pra obter um token. essa função vai dar false se chegar no fim do arquivo, ou se houver erro.
Depois q vc ja tem o token, vc pode usar lex_consume ou lex_skip para consumir determinados tipos de token (isso é util pra fazer parsing). Essas funções meio q são um filtro, q condicionalmente pulam pro próximo token.
E por fim, vc pode usar lex_move para mover pro próximo token (esse é sem condições).
A lib em si foca muito em facilitar a criação das regras, com um monte de funções para fazer matching (lex_match_*), ou mesmo para trabalhar direto com o cursor (lex_cur*).
Além disso, para fazer debug, existe o lex_print_hl, q faz meio q um sintax-highligher automatico pra vc ver como o lex ta entendendo cada token.
Nos últimos commits eu fiz o lex_print_profiler também, q mostra estatísticas da lib, o q é muito util para otimizar. So q para usar tem q habilitar com um define antes de incluir a lib:
#define LEX_PROFILER
E melhor de tudo: super rápida e totalmente na stack. não precisa fazer free em nada.