Shift Reduce Parser en Compilador

Requisito previo: análisis | Conjunto 2 (Analizadores de reducción de desplazamiento o de abajo hacia arriba)

Shift Reduce los intentos del analizador para la construcción del análisis de una manera similar a como se hace en el análisis de abajo hacia arriba, es decir, el árbol de análisis se construye desde las hojas (abajo) hasta la raíz (arriba). Una forma más general del analizador shift-reduce es el analizador LR. 

Este analizador requiere algunas estructuras de datos, es decir 

  • Un búfer de entrada para almacenar la string de entrada.
  • Una pila para almacenar y acceder a las reglas de producción.

Operaciones básicas – 

  • Desplazamiento: implica mover símbolos del búfer de entrada a la pila.
  • Reducir: si el identificador aparece en la parte superior de la pila, se realiza su reducción mediante el uso de la regla de producción adecuada, es decir, el lado derecho de una regla de producción se saca de una pila y el lado izquierdo de una regla de producción se coloca en la pila.
  • Aceptar: si solo el símbolo de inicio está presente en la pila y el búfer de entrada está vacío, la acción de análisis se llama aceptar. Cuando se obtiene la acción aceptada, significa que se realizó un análisis sintáctico exitoso.
  • Error: esta es la situación en la que el analizador no puede realizar la acción de cambio ni reducir la acción y ni siquiera aceptar la acción.

Ejemplo 1 – Considere la gramática 
        S –> S + S 
        S –> S * S 
        S –> id 

Realice el análisis Shift Reduce para la string de entrada «id + id + id».  

Ejemplo 2: Considere la gramática 
        E –> 2E2 
        E –> 3E3 
        E –> 4 
Realice el análisis Shift Reduce para la string de entrada “32423”. 

Ejemplo 3 – Considere la gramática
                         S –> ( L ) | una        
                         L –> L , S | S    
Realice el análisis Shift Reduce para la string de entrada “( a, ( a, a ) ) “.  

                        Pila                                                    Búfer de entrada                                                    Acción de análisis                              
ps   ( un , ( un , un ) ) $ Cambio
ps   un , ( un , un ) ) $ Cambio
$( un  , ( un , un ) ) $ Reducir S → a
$( S  , ( un , un ) ) $ Reducir L → S
$( L  , ( un , un ) ) $ Cambio
$( L ,  ( un , un ) ) $ Cambio
$( L , (  a , a ) ) $ Cambio
$( L , ( un  , a ) ) $ Reducir S → a
$( L , ( S  , a ) ) $ Reducir L → S
$( L , ( L  , a ) ) $ Cambio
$( L , ( L ,  a ) ) $ Cambio
$( L , ( L , un  ps Reducir S → a
$(L, (L, S)  ps Reducir L →L, S
$( L, ( L  ps Cambio
$(L, (L)  ps Reducir S → (L)
$(L, S  ps Reducir L → L, S
$( L  ps Cambio
$(L)  ps Reducir S → (L)
$S  ps Aceptar

A continuación se muestra la implementación-

C++

// Including Libraries
#include <bits/stdc++.h>
using namespace std;
   
// Global Variables
int z = 0, i = 0, j = 0, c = 0;
   
// Modify array size to increase 
// length of string to be parsed
char a[16], ac[20], stk[15], act[10]; 
   
// This Function will check whether
// the stack contain a production rule 
// which is to be Reduce.
// Rules can be E->2E2 , E->3E3 , E->4
void check()
{
    // Copying string to be printed as action
    strcpy(ac,"REDUCE TO E -> ");  
       
    // c=length of input string
    for(z = 0; z < c; z++) 
    {
        // checking for producing rule E->4
        if(stk[z] == '4') 
        {
            printf("%s4", ac);
            stk[z] = 'E';
            stk[z + 1] = '\0';
               
            //printing action
            printf("\n$%s\t%s$\t", stk, a); 
        }
    }
           
    for(z = 0; z < c - 2; z++)
    {
        // checking for another production
        if(stk[z] == '2' && stk[z + 1] == 'E' && 
                                stk[z + 2] == '2') 
        {
            printf("%s2E2", ac);
            stk[z] = 'E';
            stk[z + 1] = '\0';
            stk[z + 2] = '\0';
            printf("\n$%s\t%s$\t", stk, a);
            i = i - 2;
        }
           
    }
           
    for(z = 0; z < c - 2; z++)
    {
        //checking for E->3E3
        if(stk[z] == '3' && stk[z + 1] == 'E' && 
                                stk[z + 2] == '3') 
        {
            printf("%s3E3", ac);
            stk[z]='E';
            stk[z + 1]='\0';
            stk[z + 1]='\0';
            printf("\n$%s\t%s$\t", stk, a);
            i = i - 2;
        }
    }
    return ; // return to main
}
   
// Driver Function
int main()
{
    printf("GRAMMAR is -\nE->2E2 \nE->3E3 \nE->4\n");    
       
    // a is input string
    strcpy(a,"32423"); 
       
    // strlen(a) will return the length of a to c
    c=strlen(a); 
       
    // "SHIFT" is copied to act to be printed
    strcpy(act,"SHIFT"); 
       
    // This will print Labels (column name)
    printf("\nstack \t input \t action"); 
       
    // This will print the initial 
    // values of stack and input
    printf("\n$\t%s$\t", a); 
       
    // This will Run upto length of input string
    for(i = 0; j < c; i++, j++) 
    {
        // Printing action
        printf("%s", act); 
           
        // Pushing into stack
        stk[i] = a[j];     
        stk[i + 1] = '\0';
           
        // Moving the pointer
        a[j]=' ';
           
        // Printing action
        printf("\n$%s\t%s$\t", stk, a); 
           
        // Call check function ..which will 
        // check the stack whether its contain
        // any production or not
        check(); 
    }
       
    // Rechecking last time if contain
    // any valid production then it will
    // replace otherwise invalid
    check(); 
       
    // if top of the stack is E(starting symbol)
    // then it will accept the input
    if(stk[0] == 'E' && stk[1] == '\0') 
        printf("Accept\n");
    else //else reject
        printf("Reject\n");
}
// This code is contributed by Shubhamsingh10

C

//Including Libraries
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
 
//Global Variables
int z = 0, i = 0, j = 0, c = 0;
 
// Modify array size to increase
// length of string to be parsed
char a[16], ac[20], stk[15], act[10];
 
// This Function will check whether
// the stack contain a production rule
// which is to be Reduce.
// Rules can be E->2E2 , E->3E3 , E->4
void check()
{
    // Copying string to be printed as action
    strcpy(ac,"REDUCE TO E -> "); 
     
    // c=length of input string
    for(z = 0; z < c; z++)
    {
        //checking for producing rule E->4
        if(stk[z] == '4')
        {
            printf("%s4", ac);
            stk[z] = 'E';
            stk[z + 1] = '\0';
             
            //printing action
            printf("\n$%s\t%s$\t", stk, a);
        }
    }
         
    for(z = 0; z < c - 2; z++)
    {
        //checking for another production
        if(stk[z] == '2' && stk[z + 1] == 'E' &&
                                stk[z + 2] == '2')
        {
            printf("%s2E2", ac);
            stk[z] = 'E';
            stk[z + 1] = '\0';
            stk[z + 2] = '\0';
            printf("\n$%s\t%s$\t", stk, a);
            i = i - 2;
        }
         
    }
         
    for(z=0; z<c-2; z++)
    {
        //checking for E->3E3
        if(stk[z] == '3' && stk[z + 1] == 'E' &&
                                stk[z + 2] == '3')
        {
            printf("%s3E3", ac);
            stk[z]='E';
            stk[z + 1]='\0';
            stk[z + 1]='\0';
            printf("\n$%s\t%s$\t", stk, a);
            i = i - 2;
        }
    }
    return ; //return to main
}
 
//Driver Function
int main()
{
    printf("GRAMMAR is -\nE->2E2 \nE->3E3 \nE->4\n");   
     
    // a is input string
    strcpy(a,"32423");
     
    // strlen(a) will return the length of a to c
    c=strlen(a);
     
    // "SHIFT" is copied to act to be printed
    strcpy(act,"SHIFT");
     
    // This will print Labels (column name)
    printf("\nstack \t input \t action");
     
    // This will print the initial
    // values of stack and input
    printf("\n$\t%s$\t", a);
     
    // This will Run upto length of input string
    for(i = 0; j < c; i++, j++)
    {
        // Printing action
        printf("%s", act);
         
        // Pushing into stack
        stk[i] = a[j];    
        stk[i + 1] = '\0';
         
        // Moving the pointer
        a[j]=' ';
         
        // Printing action
        printf("\n$%s\t%s$\t", stk, a);
         
        // Call check function ..which will
        // check the stack whether its contain
        // any production or not
        check();
    }
     
    // Rechecking last time if contain
    // any valid production then it will
    // replace otherwise invalid
    check();
     
    // if top of the stack is E(starting symbol)
    // then it will accept the input
    if(stk[0] == 'E' && stk[1] == '\0')
        printf("Accept\n");
    else //else reject
        printf("Reject\n");
}
// This code is contributed by Ritesh Aggarwal

Producción –

GRAMMAR is -
E->2E2 
E->3E3 
E->4

stack      input      action
$    32423$    SHIFT
$3     2423$    SHIFT
$32      423$    SHIFT
$324       23$    REDUCE TO E -> 4
$32E       23$    SHIFT
$32E2        3$    REDUCE TO E -> 2E2
$3E        3$    SHIFT
$3E3         $    REDUCE TO E -> 3E3
$E         $    Accept

Publicación traducida automáticamente

Artículo escrito por Ankit87 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *