Question

Avec les éléments suivants grammaire, je reçois une erreur de syntaxe avec ce type d'entrée:

ls /home > foo #Runs and works okay, but raises error token
ls /home /foo /bar /etc #works okay

Je pense qu'il peut avoir quelque chose à voir avec la façon dont fonctionne lookahead, mais ceci est ma première grammaire et je suis un peu confus au sujet de pourquoi il ne fonctionne pas de cette façon: MOT external_cmd GT est une redirection, redirection est une commande, commande est une commande, de sorte que les commandes d'entrée NEWLINE devrait fonctionner.

Top règles de la grammaire:

input:
    error NEWLINE {
        printf("Error Triggered\n");
        yyclearin;
        yyerrok; 
        prompt(); 
    } |
    input NEWLINE {
        prompt();
    } | 
    input commands NEWLINE {
        prompt (); 
    } | 
    /* empty */
    ;   

commands: 
    command |   
    command SEMI | 
    command SEMI commands
    ;   

command:
    builtin_cmd |
    redirect |
    external_cmd { 
        execute_command($1, 0, NULL);
    }
    ;

redirect:
    external_cmd GT WORD  {
        printf("Redirecting stdout of %s to %s\n", $1->cmd, $3);
        //printf("DEBUG: GT\n");
        execute_command($1, STDOUT_FILENO, $3);
    }
    external_cmd LT WORD {
        printf("Redirecting stin of %s to %s\n", $1->cmd, $3);
        //printf("DEBUG: GT\n");
        execute_command($1, STDIN_FILENO, $3);
    }
    ;

Le débogage / entrée détaillé du moment où le jeton d'erreur est générée:

Next token is token WORD ()
Shifting token WORD ()
Entering state 6
Reading a token: Next token is token WORD ()
Shifting token WORD ()
Entering state 24
Reading a token: Next token is token GT ()
Reducing stack by rule 22 (line 115):
   $1 = token WORD ()
-> $$ = nterm arg_list ()
Stack now 0 2 6
Entering state 26
Reducing stack by rule 19 (line 91):
   $1 = token WORD ()
   $2 = nterm arg_list ()
-> $$ = nterm external_cmd ()
Stack now 0 2
Entering state 16
Next token is token GT ()
Shifting token GT ()
Entering state 29
Reading a token: Next token is token WORD ()
Shifting token WORD ()
Entering state 33
Reducing stack by rule 11 (line 68):
Redirecting stdout of ls to foo
DEBUG: redirect mode is 1
DEBUG: Command to run is ls
DEBUG: Adding Argument /home
admin  kbrandt  tempuser
-> $$ = nterm @1 ()
Stack now 0 2 16 29 33
Entering state 34
Reading a token: Next token is token NEWLINE ()
syntax error
Error: popping nterm @1 ()
Stack now 0 2 16 29 33
Error: popping token WORD ()
Stack now 0 2 16 29
Error: popping token GT ()
Stack now 0 2 16
Error: popping nterm external_cmd ()
Stack now 0 2
Error: popping nterm input ()
Stack now 0
Shifting token error ()
Entering state 1
Next token is token NEWLINE ()
Shifting token NEWLINE ()
Entering state 3
Reducing stack by rule 1 (line 38):
   $1 = token error ()
   $2 = token NEWLINE ()
Error Triggered
-> $$ = nterm input ()
Stack now 0
Entering state 2

Mise à jour:
external_cmd est:

external_cmd:
    WORD arg_list {
        $$ = malloc( sizeof(struct ext_cmd) );
        if ( $$ == NULL)
            printf("Memory Allocation Error\n");
        $$->cmd = $1;
        $$->args_pp = $2;
    } |
    WORD    {
        $$ = malloc( sizeof(struct ext_cmd) );
        if ( $$ == NULL)
            printf("Memory Allocation Error\n");
        $$->cmd = $<string>1;
        $$->args_pp = NULL;
    }
Était-ce utile?

La solution 3

trouvé, dans ma règle de redirection il y a un tuyau manquant, donc au lieu de deux composants, il y a un avec une action mi-règle, ce qui est pas ce que je veux.

Autres conseils

L'erreur de syntaxe vient de votre appel DEUXIÈME à yyparse. Lorsque vous avez la redirection, vous grammaire fait un YYACCEPT, ce qui provoque l'analyseur pour revenir immédiatement sans rien lire plus. Au deuxième appel, le premier jeton lu est une nouvelle ligne, quels cas l'erreur (votre grammaire ne permet pas de lignes vides.)

Sans redirection, il n'y a pas YYACCEPT, de sorte que la grammaire continue à courir, lire la nouvelle ligne et le retour en arrivant à la fin de l'entrée.

  1. Vous avez vraiment vraiment devraient utiliser la récursivité gauche avec des générateurs d'analyseur LALR (1). récursion droit exige que tous les éléments soient décalés sur la pile d'état de l'analyseur avant même qu'une seule réduction peut se produire. Vous pouvez imaginer ce que cela fait à la récupération d'erreur.

  2. Qu'est-ce external_cmd exactement? Il semble un peu comme il est réduit au début, mais il est difficile de dire parce que vous ne l'inclut pas.

  3. Pourquoi YYACCEPT invoqué après une redirection? Si vous avez l'intention de redémarrer l'analyseur sur chaque ligne, alors vous ne devriez pas avoir le collecteur d'entrée récursive. Tant que vous ne l'avez, ne pas faire YYACCEPT.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top