else, that caused NORMAL_CODE to fall through to SINGLE_QUOTED. Remove the extra else, and the code seems to work.
You see, the loop iteration always begins by reading the next character. The first ' in NORMAL_CODE state causes the state to change to SINGLE_QUOTED, but by the time you get to the relevant case statement, the c now refers to a new character because it was read in the loop condition. Since there is no transition to NORMAL_CODE unless there is an end of input (which ends the loop) or a ', single-quoted input is consumed witihin that state.
Note that this code is only intended to scan, not fix, any input.