let rec lexer_of_matrix ?(print_trace = false) ?(automaton = default_automaton) (matrix : string array array) : t_token list = let rec aux (acc : t_token list) (state : t_state) (row : int) (col : int) (stack : t_stack) = if state = automaton.end_state then acc else let symbol = symbol_of_matrix row col matrix in match automaton.transition state symbol stack with |action, next_state, token_opt, next_stack -> let _ : unit = if print_trace then trace state row col symbol token_opt next_stack else () in let next_row, next_col = match action with |Up -> row-1, col |Down -> row+1, col |Left -> row, col-1 |Right -> row, col+1 |Stay -> row, col in match token_opt with |None -> aux acc next_state next_row next_col next_stack |Some token -> aux (token::acc) next_state next_row next_col next_stack in match last_non_empty_row_of_matrix matrix with |None -> raise (Error "empty matrix") |Some i -> List.rev (aux [] (State 0) i 0 (Stack []))