Bonjour, je suis actuellement étudiant en 1ere année d’une école d’informatique et je suis devant un exercice qui nécessite d’implémenter un arbre de syntaxe abstraite.

L’exercice consiste à programmer un minishell avec des règles précises. Le comportement de référence du minishell est basé sur celui de bash.
Pour le moment, j’ai un lexer qui prend l’entrée standard et initialise une liste chainée de token, voici ce dont j’ai besoin :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
typedef	enum e_token_type
{
	TOK_INFILE_REDIR = 1, // '<'
	TOK_OUTFILE_REDIR, // '>'
	TOK_HERE_DOC, // ">>"
	TOK_APP_OUT_REDIR, // "<<"
	TOK_STRING, // text 'text' "text"
	TOK_AND, // "&&"
	TOK_OR, // "||"
	TOK_PIPE, // '|'
	TOK_L_PARENTHESIS, // '('
	TOK_R_PARENTHESIS // ')'
}	t_token_type;
Les token string ne contiennent qu’un argument au lieu de contenir une liste d’argument, aurait-il été préférable de mettre une suite de string dans le même token et ainsi alléger la liste ?

Je veux maintenant mettre en place un arbre de syntaxe mais avant de foncer tête baisser dans le code j’aimerais faire évaluer l’algorithme récursif que j’ai mis en place.
Les règles de grammaire de bash sont assez difficiles à mettre en évidence et j’ai peut-être eu tendance à mettre trop de règles par « précaution ». La documentation de GNU m’a été utile pour définir l’ordre de priorité mais j’ignore si je l’ai bien utilisé notamment dans la gestion des parenthèses.

J’ai utilisé la forme Backus-Naur pour définir la grammaire de mon programme :

Code : 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
/**
 *
        <list>                      ::=     '(' <command line> ')'   '||'     <list>
                                            |   '(' <command line> ')'  '&&'    <list>
                                            |   '(' <command line> ')'   '<'     <list>
                                            |   '(' <command line> ')'   '>'     <list>
                                            |   '(' <command line> ')'  '>>'    <list>
                                            |   '(' <command line> ')'  '<<'    <list>
                                            |   '(' <command line> ')'    '|'     <list>
                                            |   '(' <command line> ')'
                                            |   <command line>
    
    <command line>             ::=      <job>        '||'       <command line>
                                            |   <job>       '&&'      <command line>
                                                <job>
 
        <job>                 ::=       <command>   '|'     <job>
                                            |   <command>   '||'    <job>
                                            |   <command>  '&&'   <job>
                                            |   <command>
 
        <command>           ::= <simple command>   '<'    <filename>
                                            |   <simple command>   '>'    <filename>
                                            |   <simple command>  '>>'   <filename>
                                            |   <simple command>  '<<'   <EOF>
                                            |   <simple command>
 
        <simple command>::=     <pathname> <token list>
 
        <token list>         ::=        <token> <token list>
                                            |   (EMPTY)
 *
**/
Pour ce qui est de l’arbre j’ai suivi le cours https://rperrot.developpez.com/artic...ctures/arbres/ et je m’apprête à regarder celui ci https://sjrd.developpez.com/algorith...xiques/#Lno-IX. Si quelqu’un à des ressources supplémentaires je suis preneur.

A première vu je réserverais bien les branches de gauche pour y mettre les arguments et opérateurs entre parenthèse qui eux même se déploieront sur leur propre nœud. Je redoute seulement que ce ne soit pas bien optimisé dans le cas où l’entrée serait une grande suite de commande sans parenthèse qui ne se développe que sur les branches de droites. Dans le cadre d’un minishell il semble qu’il n’est pas nécessaire de s’en inquiéter mais on doit anticiper le maximum de situations compromettantes.

Si quelqu’un peut m’éclairer sur le sujet, je l’en remercie d’avance.