IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Commentaires

  1. Avatar de emmesse
    • |
    • permalink
    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"
    Mis à jour 05/02/2026 à 00h48 par emmesse
  2. Avatar de unanonyme
    • |
    • permalink
    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
    1
    2
    3
    4
    ligne 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
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
     
    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.
    Mis à jour 18/09/2023 à 22h24 par f-leb (balises [CODE=Go]...[/CODE], pour la coloration syntaxique en Go)
  3. Avatar de emmesse
    • |
    • permalink
    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
    Mis à jour 15/05/2017 à 12h44 par emmesse
  4. Avatar de emmesse
    • |
    • permalink
    je voulais dire le fichier Makefile.am
  5. Avatar de emmesse
    • |
    • permalink
    On peut utiliser qt5 sous debian jessie:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ 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
    1
    2
    3
    4
    5
    bin_PROGRAMS = hello
    
    hello_CXXFLAGS=-I /usr/include/i386-linux-gnu/qt5
    
    hello_SOURCES = main.cpp
  6. Avatar de emmesse
    • |
    • permalink
    au préalable, sous Debian:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $su
    # apt-get install autoconf pkg-config qt-sdk
    Mis à jour 02/06/2016 à 18h10 par emmesse
  7. Avatar de emmesse
    • |
    • permalink
    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
    1
    2
    $ cd projet-1.0
    $ make dist-bzip2
    ce qui est meilleur car on obtient un tarball sans les fichiers inutiles
    Mis à jour 01/02/2016 à 23h59 par emmesse