// Simple Shift Reduce parsing for E → E + E | id
#include <stdio.h>
#include <string.h>
#include <ctype.h>
// Stack to hold tokens and non-terminals during parsing
char stack[100][10];
int top = -1;      // Points to the top of the stack
int index1 = 0;        // Input pointer/index
char input[100];   // Holds the input string (e.g., "a+b+c")

// Push a symbol (token or non-terminal) onto the stack
void push(const char *s)
{
    strcpy(stack[++top], s);
}
// Pop the top of the stack
void pop()
{
    top--;
}
// Print current stack contents
void printStack()
{
    for (int i = 0; i <= top; i++) printf("%s", stack[i]);
    printf("\n");
}


// Try to apply a reduction rule to the  top of the stack
int reduce()
{
    // Rule 1: E → E + E
    if (top >= 2 &&
            strcmp(stack[top-2], "E")==0 &&
            (strcmp(stack[top-1], "+")==0||strcmp(stack[top-1], "*")==0) &&
            strcmp(stack[top], "E")==0)
    {
        pop();
        pop();
        pop();   // Remove "E + E" (3 pops)
        push("E");           // Push "E" onto the stack
        return 1;               // Indicate that a reduction occurred
    }

    // Rule 2: E → id
    if (top!=-1 && stack[top][0]>='a'&&stack[top][0]<='z')
    {
        pop();  // Remove "id" (1 pop)
        push("E");  // Push "E" onto the stack
        return 1;
    }
    
    //Rule 3: (E) -> E
    if(top>=2&&strcmp(stack[top-2], "(")==0&&strcmp(stack[top-1], "E")==0&&strcmp(stack[top], ")")==0){
        pop();
        pop();
        pop();
        push("E");
        return 1;
    }
   

    return 0; // No reduction matched
}


int main()
{
    // Read input string (e.g., a+b+c)
    fgets(input, sizeof(input), stdin); //input string must not include white spaces
    input[strcspn(input, "\n")] = '\0';//this one will scan all input untill it reach "\n" then will return index
    // so if input is a + b
    //it will present a + b\n\0
    //in this case strcspn will return 5
    //then input[5]will = "\0"which mean endofstring

    //E+a
    // Main parsing loop: continue until input ends and no more reductions are possible
    while (input[index1] != '\0')
    {
        if(input[index1] == ' '){//to ignore white spaces
            index1++;
            continue;
        }
        // SHIFT step: if input is not yet fully consumed
        // Check for "id" token
        char temp[2] = {input[index1], '\0'};  // turn character into string
        push(temp);                           // push actual character (like 'x')
        index1 ++;        // Move input pointer ahead by 1

        // Print stack after shift
        printf("Shift: ");
        printStack();


        // REDUCE step: apply all possible reductions after shift
        while (reduce())
        {
            printf("Reduce: ");
            printStack();

        }
    }

    // Final check: input is accepted if the stack has a single symbol "E"
    if (top == 0 && strcmp(stack[0], "E")==0)
        printf("String Accepted\n");
    else
        printf("String Rejected\n");

    return 0;
}