Does the DFS algorithm differentiate between an ancestor and a parent while computing back edges?
The algorithm you describe works on directed graphs. In such a graph, an edge $(u, v)$ does not imply an edge $(v, u)$. Your confusion arises because you are probably trying it for undirected graphs.

For undirected graphs, the algorithm has to be modified slightly. Again, the modification will depend on whether this graph is a simple undirected graph or a multigraph. I will use the same variable names used that you use in your algorithm:


Simple Graph: When checking the colour of the adjacent vertex $a$ of a vertex $v$, if the colour is grey and the vertex $a$ is not a parent of $v$, then it is a back-edge. Ignore if $a$ is the parent.
Multigraph: If the colour of $a$ is grey and it is a parent of $v$, you need to check if $a$ occurs more than once in the adjacency list of $v$. This indicates multiple edges between $a$ and $v$, and one of them can be considered as a tree edge while the rest will be back edges. If there is only one edge between the two, it is a tree edge and has already been considered, so do nothing. Loops (edge from $v$ to $v$, that is, $a$ = $v$) are always back edges.


You are basically finding a spanning tree of the graph, and so try to go by the definitions and see how the algorithm should be modified for various cases. And how a tree-edge or a back edge are informally defined for various types of graphs.