Merci @unanonyme de m'avoir indiqué le bug du caractère hors langage. Merci aissi d'avoir indiqué le bug nombre : 5. En effet, j'ai mal placé le "break;" j'ai indenté avec deux espaces par bloc (indentation automatique de l'éditeur de texte emacs) Si on met v:=,35, l'analyseur répondra par <identificateur,"v">,<deux_points_egal,>,<nombre,",35">, ce qui est exactement ce que je voulais. ",35" n'est pas erroné, c'est prévus. Sinon, les diagrammes de transition ne sont pas fait pour le "schéma mental", c'est fait pour implémenter des analyseurs lexicaux. On part d'une expression régulière et on la transforme en diagramme de transition. Il y a des techniques pour ça. les blancs dans le code source doivent être ignorés par l'analyseur lexical, car une grammaire hors contexte ne les utilise pas, cela serait trop compliqué. le \n à la fin du fichier ne doit pas être "invalid"
Bonjour, J'ai testé votre code avec quelques données d'entrées, les résultats sont inattendus, indésirable. Par exemple avec un caractère UTF-8 (Vitesse世 := 35), le programme boucle sur lui même, avec "Vitésse := 35", le programme crash. Lorsque je met une syntaxe volontairement invalide (Vitesse := ,35), la sortie est ainsi : Code : Sélectionner tout - Visualiser dans une fenêtre à part 1234ligne 1: identificateur Vitesse ligne 1: deux-points-egal ligne 1: nombre ,35 ligne 1: nombre 5 Ceci mis à part je m'interroge à savoir si je suis le seul à penser que bien que les diagrammes semblent une bonne idée, ils ne m'aident que très anecdotiquement à la construction du schéma mental. C'est bien dommage. Quoi qu'il en soit je me suis pris au jeu, à ma sauce, pas de tests, pas de commentaires, juste quelques attouchements du clavier dont on trouvera aussi à commenter, je n'en doutes pas. Puisque comme vous, l'ajustement de l'indentation me fatigue les doigts, j'ai préféré utiliser un langage outillé pour me caresser dans le sens du poil plutôt que de violer les yeux de mes éventuel relecteurs. Code Go : Sélectionner tout - Visualiser dans une fenêtre à part 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 package main import ( "fmt" "os" "unicode" ) func main() { if len(os.Args) < 2 { fmt.Fprintln(os.Stderr, "invocation incorrecte: fichier manquant") os.Exit(1) } fp := os.Args[1] b, err := os.ReadFile(fp) if err != nil { fmt.Fprintf(os.Stderr, "invocation incorrecte: %v\n", err) os.Exit(1) } data := string(b) tokens := checkers.parse(data) for _, tok := range tokens { fmt.Println(tok) } } var underscore = []rune("_")[0] var comma = []rune(",")[0] var single_quote = []rune("'")[0] var double_quote = []rune("\"")[0] var backtick = []rune("`")[0] var ( is_whitespace = tokenChecker{ kind: white_space, allowNL: true, validate: func(i int, r rune, is_escaped bool) bool { return unicode.IsSpace(r) }, } is_assignment = tokenChecker{ kind: assignment, validate: is_seq([]rune(":=")), } is_identifier = tokenChecker{ kind: identifier, validate: func(i int, r rune, is_escaped bool) bool { return (r == underscore && i > 0) || unicode.IsLetter(r) }, } is_number = tokenChecker{ kind: number, validate: func(i int, r rune, is_escaped bool) bool { return unicode.IsNumber(r) || i > 0 && r == comma }, } is_single_quote = tokenChecker{ kind: text, escape: []rune("\\"), validate: is_quote(single_quote), } is_double_quote = tokenChecker{ kind: text, escape: []rune("\\"), validate: is_quote(double_quote), } is_backtick = tokenChecker{ kind: text, allowNL: true, escape: []rune("\\"), validate: is_quote(backtick), } checkers = tokenCheckers{ is_whitespace, is_assignment, is_identifier, is_number, is_single_quote, is_double_quote, is_backtick, } ) type tokenCheckers []tokenChecker func (t tokenCheckers) parse(data string) []token { input := []rune(data) var out []token line := 0 pos := 0 for pos < len(input) { tok := t.next_token(input, line, pos) line = tok.end_line pos = tok.pos + len(tok.data) if tok.kind == invalid && len(out) > 0 && out[len(out)-1].kind == invalid { out[len(out)-1].end_line = line out[len(out)-1].data = append(out[len(out)-1].data, tok.data...) } else { out = append(out, tok) } } return out } func (t tokenCheckers) next_token(input []rune, line, pos int) token { for _, checker := range t { tok, ok := checker.read_token(input[pos:], line, pos) if ok { return tok } } return token{ kind: invalid, start_line: line, end_line: line, pos: pos, data: []rune{input[pos]}, } } func (c tokenChecker) read_token(input []rune, line, start_pos int) (token, bool) { data := []rune{} end_line := line is_escaped := false for i := 0; i < len(input); i++ { one := input[i] if (!c.allowNL && one == new_line) || !c.validate(i, one, is_escaped) { if len(data) < 1 { break } if len(c.escape) > 0 && one != new_line { data = append(data, one) } return token{ kind: c.kind, start_line: line, end_line: end_line, pos: start_pos, data: data, }, true } if c.allowNL && one == new_line { end_line++ } data = append(data, one) if len(c.escape) > 0 && one == c.escape[0] { is_escaped = !is_escaped } else { is_escaped = false } } return token{}, false } var new_line = []rune("\n")[0] func is_quote(quote rune) func(i int, r rune, is_escaped bool) bool { return func(i int, r rune, is_escaped bool) bool { if i == 0 { return r == quote } return (is_escaped && r == quote) || (r != quote) } } func is_seq(seq []rune) func(i int, r rune, is_escaped bool) bool { return func(i int, r rune, is_escaped bool) bool { if i >= len(seq) { return false } return seq[i] == r } } type token struct { kind tokenKind start_line int end_line int pos int data []rune } func (t token) Eq(other token) bool { return t.kind == other.kind && t.start_line == other.start_line && t.end_line == other.end_line && t.pos == other.pos && string(t.data) == string(other.data) } func (t token) String() string { return fmt.Sprintf("[%2v-%-2v:%2v-%-2v] %-14v %q", t.start_line, t.end_line, t.pos, t.pos+len(t.data), t.kind, string(t.data), ) } type tokenKind string const ( invalid tokenKind = "invalid" identifier tokenKind = "identifier" assignment tokenKind = "assignment" number tokenKind = "number" white_space tokenKind = "white_space" text tokenKind = "text" ) type tokenChecker struct { kind tokenKind allowNL bool escape []rune validate func(i int, r rune, is_escaped bool) bool } func (t tokenChecker) String() string { return string(t.kind) } Bonne journée.
ligne 1: identificateur Vitesse ligne 1: deux-points-egal ligne 1: nombre ,35 ligne 1: nombre 5
package main import ( "fmt" "os" "unicode" ) func main() { if len(os.Args) < 2 { fmt.Fprintln(os.Stderr, "invocation incorrecte: fichier manquant") os.Exit(1) } fp := os.Args[1] b, err := os.ReadFile(fp) if err != nil { fmt.Fprintf(os.Stderr, "invocation incorrecte: %v\n", err) os.Exit(1) } data := string(b) tokens := checkers.parse(data) for _, tok := range tokens { fmt.Println(tok) } } var underscore = []rune("_")[0] var comma = []rune(",")[0] var single_quote = []rune("'")[0] var double_quote = []rune("\"")[0] var backtick = []rune("`")[0] var ( is_whitespace = tokenChecker{ kind: white_space, allowNL: true, validate: func(i int, r rune, is_escaped bool) bool { return unicode.IsSpace(r) }, } is_assignment = tokenChecker{ kind: assignment, validate: is_seq([]rune(":=")), } is_identifier = tokenChecker{ kind: identifier, validate: func(i int, r rune, is_escaped bool) bool { return (r == underscore && i > 0) || unicode.IsLetter(r) }, } is_number = tokenChecker{ kind: number, validate: func(i int, r rune, is_escaped bool) bool { return unicode.IsNumber(r) || i > 0 && r == comma }, } is_single_quote = tokenChecker{ kind: text, escape: []rune("\\"), validate: is_quote(single_quote), } is_double_quote = tokenChecker{ kind: text, escape: []rune("\\"), validate: is_quote(double_quote), } is_backtick = tokenChecker{ kind: text, allowNL: true, escape: []rune("\\"), validate: is_quote(backtick), } checkers = tokenCheckers{ is_whitespace, is_assignment, is_identifier, is_number, is_single_quote, is_double_quote, is_backtick, } ) type tokenCheckers []tokenChecker func (t tokenCheckers) parse(data string) []token { input := []rune(data) var out []token line := 0 pos := 0 for pos < len(input) { tok := t.next_token(input, line, pos) line = tok.end_line pos = tok.pos + len(tok.data) if tok.kind == invalid && len(out) > 0 && out[len(out)-1].kind == invalid { out[len(out)-1].end_line = line out[len(out)-1].data = append(out[len(out)-1].data, tok.data...) } else { out = append(out, tok) } } return out } func (t tokenCheckers) next_token(input []rune, line, pos int) token { for _, checker := range t { tok, ok := checker.read_token(input[pos:], line, pos) if ok { return tok } } return token{ kind: invalid, start_line: line, end_line: line, pos: pos, data: []rune{input[pos]}, } } func (c tokenChecker) read_token(input []rune, line, start_pos int) (token, bool) { data := []rune{} end_line := line is_escaped := false for i := 0; i < len(input); i++ { one := input[i] if (!c.allowNL && one == new_line) || !c.validate(i, one, is_escaped) { if len(data) < 1 { break } if len(c.escape) > 0 && one != new_line { data = append(data, one) } return token{ kind: c.kind, start_line: line, end_line: end_line, pos: start_pos, data: data, }, true } if c.allowNL && one == new_line { end_line++ } data = append(data, one) if len(c.escape) > 0 && one == c.escape[0] { is_escaped = !is_escaped } else { is_escaped = false } } return token{}, false } var new_line = []rune("\n")[0] func is_quote(quote rune) func(i int, r rune, is_escaped bool) bool { return func(i int, r rune, is_escaped bool) bool { if i == 0 { return r == quote } return (is_escaped && r == quote) || (r != quote) } } func is_seq(seq []rune) func(i int, r rune, is_escaped bool) bool { return func(i int, r rune, is_escaped bool) bool { if i >= len(seq) { return false } return seq[i] == r } } type token struct { kind tokenKind start_line int end_line int pos int data []rune } func (t token) Eq(other token) bool { return t.kind == other.kind && t.start_line == other.start_line && t.end_line == other.end_line && t.pos == other.pos && string(t.data) == string(other.data) } func (t token) String() string { return fmt.Sprintf("[%2v-%-2v:%2v-%-2v] %-14v %q", t.start_line, t.end_line, t.pos, t.pos+len(t.data), t.kind, string(t.data), ) } type tokenKind string const ( invalid tokenKind = "invalid" identifier tokenKind = "identifier" assignment tokenKind = "assignment" number tokenKind = "number" white_space tokenKind = "white_space" text tokenKind = "text" ) type tokenChecker struct { kind tokenKind allowNL bool escape []rune validate func(i int, r rune, is_escaped bool) bool } func (t tokenChecker) String() string { return string(t.kind) }
avec ubuntu il faut installer automake et non pas automake1.11, sinon aclocal ne fonctionnera pas Code : Sélectionner tout - Visualiser dans une fenêtre à part sudo apt install automake
sudo apt install automake
je voulais dire le fichier Makefile.am
On peut utiliser qt5 sous debian jessie: Code : Sélectionner tout - Visualiser dans une fenêtre à part 12$ su # apt-get install qt5-default build-essential g++ pkg-config le fichier src/Makefile sera alors: Code : Sélectionner tout - Visualiser dans une fenêtre à part 12345bin_PROGRAMS = hello hello_CXXFLAGS=-I /usr/include/i386-linux-gnu/qt5 hello_SOURCES = main.cpp
$ su # apt-get install qt5-default build-essential g++ pkg-config
bin_PROGRAMS = hello hello_CXXFLAGS=-I /usr/include/i386-linux-gnu/qt5 hello_SOURCES = main.cpp
au préalable, sous Debian: Code : Sélectionner tout - Visualiser dans une fenêtre à part 12$su # apt-get install autoconf pkg-config qt-sdk
$su # apt-get install autoconf pkg-config qt-sdk
bonjour, pour coriger la fin: pour faire un tarball en bz2, on utilisera plutôt make dist-bzip2 Code : Sélectionner tout - Visualiser dans une fenêtre à part 12$ cd projet-1.0 $ make dist-bzip2 ce qui est meilleur car on obtient un tarball sans les fichiers inutiles
$ cd projet-1.0 $ make dist-bzip2