Go Backslash within double quotes

Hello there ! So I’m a newbie in Go and I wanted to try a CodeCrafters challenge with it. The free Shell challenge was the perfect opportunity😃.
I’m currently stuck in the challenge mentioned in the title. I’ll be happy if anyone can help me because I really don’t understand my mistake.
Here is my parser :

package main

import (
	"fmt"
	"strings"
	"unicode"
)

type ParsingState string

const ( // États possibles: normal, inQuote, inDoubleQuote
	Normal      ParsingState = "normal"
	SingleQuote ParsingState = "singleQuote"
	DoubleQuote ParsingState = "doubleQuote"
)

func ParseShellWords(line string) (string, []string, error) {
	var words []string
	var word strings.Builder

	var state = Normal
	escapeNext := false // Indique si le prochain caractère doit être échappé
	inWord := false     // Indique si nous sommes en train de construire un mot

	// Parcourir la chaîne caractère par caractère
	for id, char := range line {
		// Traiter l'échappement des caractères
		if escapeNext {
			word.WriteRune(char)
			escapeNext = false
			inWord = true
			continue
		}

		// Vérifier le caractère d'échappement
		if char == '\\' {
			if state == Normal {
				escapeNext = true
				continue
			} else if state == DoubleQuote && id+1 < len(line) {
				nextChar := line[id+1]
				if isSpecialChar(nextChar) {
					escapeNext = true
					continue
				}
				word.WriteRune(char)
				continue
			} else if state == SingleQuote {
				word.WriteRune(char)
				continue
			}
		}

		// Traitement selon l'état actuel
		switch state {
		case Normal:
			if char == '"' {
				state = DoubleQuote
				inWord = true // On commence un mot ou on continue un mot existant
			} else if char == '\'' {
				state = SingleQuote
				inWord = true // On commence un mot ou on continue un mot existant
			} else if unicode.IsSpace(char) {
				// Fin d'un mot
				if inWord {
					words = append(words, word.String())
					word.Reset()
					inWord = false
				}
			} else {
				word.WriteRune(char)
				inWord = true
			}

		case SingleQuote:
			if char == '\'' {
				state = Normal
			} else {
				word.WriteRune(char)
			}

		case DoubleQuote:
			if char == '"' {
				state = Normal
			} else {
				word.WriteRune(char)
			}
		}
	}

	// Vérifier si nous avons terminé dans un état valide
	if state != Normal {
		return "", nil, fmt.Errorf("guillemets non fermés")
	}

	// Ajouter le dernier mot s'il existe
	if inWord {
		words = append(words, word.String())
	}

	if len(words) == 0 {
		return "", nil, fmt.Errorf("aucune commande trouvée")
	}

	if len(words) == 1 {
		return words[0], []string{}, nil
	}

	return words[0], words[1:], nil
}

func isSpecialChar(char uint8) bool {
	return char == '$' || char == '\n' || char == '\\' || char == '"' || char == '\'' || char == '`'
}

@WilFriite, could you upload your code to GitHub and share the link? It will be much easier to debug if I can run it directly.

Hi, here you go https://github.com/WilFriite/codecrafters-shell

@WilFriite, I tried running your code against the previous stages, but it’s actually no longer passing a previous stage #CZ2 (Handle invalid commands).

Suggestions:

  1. Use our CLI to test against previous stages by running:
codecrafters test --previous
  1. Focus on fixing the early stages first, as later stages depend on them.

Closing this thread due to inactivity. If you still need assistance, feel free to reopen or start a new discussion!

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.