#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAX 100
char stack[ MAX] [ 20 ] ; // The parser stack (each cell = a symbol like "E", "+", "id", etc.)
int top = - 1 ; // Stack pointer
void push( const char * sym)
{
top++;
}
void pop( )
{
if ( top >= 0 ) top--;
}
// Print current stack state
void printStack( const char * action)
{
for ( int i = 0 ; i <= top; i++ )
}
int tryReduce( )
{
if ( top >= 2 &&
strcmp ( stack
[ top
- 2 ] , "(" ) == 0 && strcmp ( stack
[ top
- 1 ] , "E" ) == 0 && {
pop( ) ; pop( ) ; pop( ) ;
push( "E" ) ;
printStack( "Reduce" ) ;
return 1 ;
}
if ( top >= 2 &&
strcmp ( stack
[ top
- 2 ] , "E" ) == 0 && strcmp ( stack
[ top
- 1 ] , "*" ) == 0 && {
pop( ) ; pop( ) ; pop( ) ;
push( "E" ) ;
printStack( "Reduce" ) ;
return 1 ;
}
if ( top >= 2 &&
strcmp ( stack
[ top
- 2 ] , "E" ) == 0 && strcmp ( stack
[ top
- 1 ] , "+" ) == 0 && {
pop( ) ; pop( ) ; pop( ) ;
push( "E" ) ;
printStack( "Reduce" ) ;
return 1 ;
}
// Rule: E -> id
// Top is an identifier (not a special symbol)
if ( top >= 0 &&
strcmp ( stack
[ top
] , "E" ) != 0 && strcmp ( stack
[ top
] , "+" ) != 0 && strcmp ( stack
[ top
] , "*" ) != 0 && strcmp ( stack
[ top
] , "(" ) != 0 && {
pop( ) ;
push( "E" ) ;
printStack( "Reduce" ) ;
return 1 ;
}
return 0 ; // No reduction possible
}
int nextToken( const char * input, int * pos, char * out)
{
// Skip whitespace
while ( * pos
< len
&& isspace ( ( unsigned char ) input
[ * pos
] ) ) ( * pos) ++;
if ( * pos >= len) return 0 ; // No more tokens
char ch = input[ * pos] ;
// Single-character tokens: operators and parentheses
if ( ch == '+' || ch == '*' || ch == '(' || ch == ')' )
{
out[ 0 ] = ch;
out[ 1 ] = '\0 ' ;
( * pos) ++;
return 1 ;
}
if ( isalpha ( ( unsigned char ) ch
) || ch
== '_' ) {
int start = * pos;
while ( * pos
< len
&& ( isalnum ( ( unsigned char ) input
[ * pos
] ) || input
[ * pos
] == '_' ) ) ( * pos) ++;
int tlen = * pos - start;
out[ tlen] = '\0 ' ;
return 1 ;
}
( * pos) ++;
return 0 ;
}
void shiftReduceParse( const char * input)
{
top = - 1 ;
int pos = 0 ;
char token[ 50 ] ;
while ( nextToken( input, & pos, token) )
{
push( token) ;
printStack( "Shift" ) ;
while ( tryReduce( ) ) ;
}
while ( tryReduce( ) ) ;
if ( top
== 0 && strcmp ( stack
[ 0 ] , "E" ) == 0 ) else
}
int main( )
{
char input[ 200 ] ;
printf ( "Enter an Expression:\n " ) ; fgets ( input
, 200 , stdin
) ;
if ( len > 0 && input[ len - 1 ] == '\n ' )
input[ len - 1 ] = '\0 ' ;
shiftReduceParse( input) ;
return 0 ;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGN0eXBlLmg+CiNkZWZpbmUgTUFYIDEwMAoKY2hhciBzdGFja1tNQVhdWzIwXTsgLy8gVGhlIHBhcnNlciBzdGFjayAoZWFjaCBjZWxsID0gYSBzeW1ib2wgbGlrZSAiRSIsICIrIiwgImlkIiwgZXRjLikKaW50IHRvcCA9IC0xOyAgICAgICAgLy8gU3RhY2sgcG9pbnRlcgoKCnZvaWQgcHVzaChjb25zdCBjaGFyICpzeW0pCnsKICAgIHRvcCsrOwogICAgc3RyY3B5KHN0YWNrW3RvcF0sIHN5bSk7Cn0KCnZvaWQgcG9wKCkKewogICAgaWYgKHRvcCA+PSAwKSB0b3AtLTsKfQoKLy8gUHJpbnQgY3VycmVudCBzdGFjayBzdGF0ZQp2b2lkIHByaW50U3RhY2soY29uc3QgY2hhciAqYWN0aW9uKQp7CiAgICBwcmludGYoIiVzOiAiLCBhY3Rpb24pOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPD0gdG9wOyBpKyspCiAgICAgICAgcHJpbnRmKCIlcyAiLCBzdGFja1tpXSk7CiAgICBwcmludGYoIlxuIik7Cn0KCmludCB0cnlSZWR1Y2UoKQp7CiAgICBpZiAodG9wID49IDIgJiYKICAgICAgICBzdHJjbXAoc3RhY2tbdG9wIC0gMl0sICIoIikgPT0gMCAmJgogICAgICAgIHN0cmNtcChzdGFja1t0b3AgLSAxXSwgIkUiKSA9PSAwICYmCiAgICAgICAgc3RyY21wKHN0YWNrW3RvcF0sICAgICAiKSIpID09IDApCiAgICB7CiAgICAgICAgcG9wKCk7IHBvcCgpOyBwb3AoKTsgICAgICAgIAogICAgICAgIHB1c2goIkUiKTsgICAgICAgICAgICAgICAgICAgIAogICAgICAgIHByaW50U3RhY2soIlJlZHVjZSIpOwogICAgICAgIHJldHVybiAxOwogICAgfQogICAgCiAgICBpZiAodG9wID49IDIgJiYKICAgICAgICBzdHJjbXAoc3RhY2tbdG9wIC0gMl0sICJFIikgPT0gMCAmJgogICAgICAgIHN0cmNtcChzdGFja1t0b3AgLSAxXSwgIioiKSA9PSAwICYmCiAgICAgICAgc3RyY21wKHN0YWNrW3RvcF0sICAgICAiRSIpID09IDApCiAgICB7CiAgICAgICAgcG9wKCk7IHBvcCgpOyBwb3AoKTsKICAgICAgICBwdXNoKCJFIik7CiAgICAgICAgcHJpbnRTdGFjaygiUmVkdWNlIik7CiAgICAgICAgcmV0dXJuIDE7CiAgICB9CgogICAgaWYgKHRvcCA+PSAyICYmCiAgICAgICAgc3RyY21wKHN0YWNrW3RvcCAtIDJdLCAiRSIpID09IDAgJiYKICAgICAgICBzdHJjbXAoc3RhY2tbdG9wIC0gMV0sICIrIikgPT0gMCAmJgogICAgICAgIHN0cmNtcChzdGFja1t0b3BdLCAgICAgIkUiKSA9PSAwKQogICAgewogICAgICAgIHBvcCgpOyBwb3AoKTsgcG9wKCk7CiAgICAgICAgcHVzaCgiRSIpOwogICAgICAgIHByaW50U3RhY2soIlJlZHVjZSIpOwogICAgICAgIHJldHVybiAxOwogICAgfQoKICAgIC8vIFJ1bGU6IEUgLT4gaWQKICAgIC8vIFRvcCBpcyBhbiBpZGVudGlmaWVyIChub3QgYSBzcGVjaWFsIHN5bWJvbCkKICAgIGlmICh0b3AgPj0gMCAmJgogICAgICAgIHN0cmNtcChzdGFja1t0b3BdLCAiRSIpICE9IDAgJiYKICAgICAgICBzdHJjbXAoc3RhY2tbdG9wXSwgIisiKSAhPSAwICYmCiAgICAgICAgc3RyY21wKHN0YWNrW3RvcF0sICIqIikgIT0gMCAmJgogICAgICAgIHN0cmNtcChzdGFja1t0b3BdLCAiKCIpICE9IDAgJiYKICAgICAgICBzdHJjbXAoc3RhY2tbdG9wXSwgIikiKSAhPSAwKQogICAgewogICAgICAgIHBvcCgpOwogICAgICAgIHB1c2goIkUiKTsKICAgICAgICBwcmludFN0YWNrKCJSZWR1Y2UiKTsKICAgICAgICByZXR1cm4gMTsKICAgIH0KCiAgICByZXR1cm4gMDsgLy8gTm8gcmVkdWN0aW9uIHBvc3NpYmxlCn0KCmludCBuZXh0VG9rZW4oY29uc3QgY2hhciAqaW5wdXQsIGludCAqcG9zLCBjaGFyICpvdXQpCnsKICAgIGludCBsZW4gPSBzdHJsZW4oaW5wdXQpOwoKICAgIC8vIFNraXAgd2hpdGVzcGFjZQogICAgd2hpbGUgKCpwb3MgPCBsZW4gJiYgaXNzcGFjZSgodW5zaWduZWQgY2hhcilpbnB1dFsqcG9zXSkpCiAgICAgICAgKCpwb3MpKys7CgogICAgaWYgKCpwb3MgPj0gbGVuKSByZXR1cm4gMDsgLy8gTm8gbW9yZSB0b2tlbnMKCiAgICBjaGFyIGNoID0gaW5wdXRbKnBvc107CgogICAgLy8gU2luZ2xlLWNoYXJhY3RlciB0b2tlbnM6IG9wZXJhdG9ycyBhbmQgcGFyZW50aGVzZXMKICAgIGlmIChjaCA9PSAnKycgfHwgY2ggPT0gJyonIHx8IGNoID09ICcoJyB8fCBjaCA9PSAnKScpCiAgICB7CiAgICAgICAgb3V0WzBdID0gY2g7CiAgICAgICAgb3V0WzFdID0gJ1wwJzsKICAgICAgICAoKnBvcykrKzsKICAgICAgICByZXR1cm4gMTsKICAgIH0KICAgIAogICAgaWYgKGlzYWxwaGEoKHVuc2lnbmVkIGNoYXIpY2gpIHx8IGNoID09ICdfJykKICAgIHsKICAgICAgICBpbnQgc3RhcnQgPSAqcG9zOwogICAgICAgIHdoaWxlICgqcG9zIDwgbGVuICYmIChpc2FsbnVtKCh1bnNpZ25lZCBjaGFyKWlucHV0Wypwb3NdKSB8fCBpbnB1dFsqcG9zXSA9PSAnXycpKQogICAgICAgICAgICAoKnBvcykrKzsKICAgICAgICBpbnQgdGxlbiA9ICpwb3MgLSBzdGFydDsKICAgICAgICBzdHJuY3B5KG91dCwgaW5wdXQgKyBzdGFydCwgdGxlbik7CiAgICAgICAgb3V0W3RsZW5dID0gJ1wwJzsKICAgICAgICByZXR1cm4gMTsKICAgIH0KCiAgICAoKnBvcykrKzsKICAgIHJldHVybiAwOwp9Cgp2b2lkIHNoaWZ0UmVkdWNlUGFyc2UoY29uc3QgY2hhciAqaW5wdXQpCnsKICAgIHRvcCA9IC0xOyAKCiAgICBpbnQgcG9zID0gMDsKICAgIGNoYXIgdG9rZW5bNTBdOwoKICAgIHdoaWxlIChuZXh0VG9rZW4oaW5wdXQsICZwb3MsIHRva2VuKSkKICAgIHsKICAgICAgICBwdXNoKHRva2VuKTsKICAgICAgICBwcmludFN0YWNrKCJTaGlmdCIpOwoKICAgICAgICB3aGlsZSAodHJ5UmVkdWNlKCkpOwogICAgfQoKICAgIHdoaWxlICh0cnlSZWR1Y2UoKSk7CgogICAgaWYgKHRvcCA9PSAwICYmIHN0cmNtcChzdGFja1swXSwgIkUiKSA9PSAwKQogICAgICAgIHByaW50ZigiU3RyaW5nIEFjY2VwdGVkXG4iKTsKICAgIGVsc2UKICAgICAgICBwcmludGYoIlN0cmluZyBSZWplY3RlZFxuIik7Cn0KCmludCBtYWluKCkKewogICAgY2hhciBpbnB1dFsyMDBdOwogICAgcHJpbnRmKCJFbnRlciBhbiBFeHByZXNzaW9uOlxuIik7CiAgICBmZ2V0cyhpbnB1dCwgMjAwLCBzdGRpbik7CgogICAgaW50IGxlbiA9IHN0cmxlbihpbnB1dCk7CiAgICBpZiAobGVuID4gMCAmJiBpbnB1dFtsZW4gLSAxXSA9PSAnXG4nKQogICAgICAgIGlucHV0W2xlbiAtIDFdID0gJ1wwJzsKCiAgICBzaGlmdFJlZHVjZVBhcnNlKGlucHV0KTsKCiAgICByZXR1cm4gMDsKfQ==