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 == '`'
}