Pergunta

Com o seguinte gramática, eu recebo um erro de sintaxe com este tipo de entrada:

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

Eu acho que pode ter algo a ver com a forma como lookahead obras, mas esta é a minha primeira gramática e estou um pouco confuso sobre o porquê de ele não funciona desta maneira: external_cmd GT WORD é um redirecionamento, redirecionamento é um comando, comando é um comando, de modo que a entrada comandos NEWLINE deve funcionar.

Regras Top da gramática:

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);
    }
    ;

O debug / detalhado de entrada quando o token erro é gerado:

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

Update:
external_cmd é:

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;
    }
Foi útil?

Solução 3

encontrou, na minha regra de redirecionamento não é um cachimbo faltando, então ao invés de dois componentes, há um com uma ação de meados de regra, o que não é o que eu quero.

Outras dicas

O erro de sintaxe é proveniente de sua chamada segundo para yyparse. Quando você tem o redirecionamento, você gramática faz um YYACCEPT, o que faz com que o analisador para retornar imediatamente sem ler mais nada. Na segunda chamada, a primeira leitura token é uma nova linha, que casos o erro (a sua gramática não permite linhas em branco.)

Sem redirecionamento, não há YYACCEPT, de modo a gramática continuar a funcionar, a leitura da nova linha e retornando ao chegar ao fim da entrada.

  1. Você realmente realmente deve usar recursão esquerdo com LALR (1) geradores de analisador. recursão direito exige que todos os elementos ser deslocado para a pilha estado analisador antes mesmo de uma única redução pode ocorrer. Você pode imaginar o que isso faz para recuperação de erros.

  2. O que é exatamente external_cmd? É o tipo de parece que ele está sendo reduzido no início, mas é difícil dizer, porque você não incluí-lo.

  3. Por que é YYACCEPT invocado depois de qualquer redirecionamento? Se você está pretendendo para reiniciar o analisador em cada linha, então você não deve ter o coletor de entrada recursiva. Contanto que você tem isso, não faça um YYACCEPT.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top