#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAX 100
char stack[ MAX] [ 20 ] ;
int top = - 1 ;
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+CiNkZWZpbmUgTUFYIDEwMAoKY2hhciBzdGFja1tNQVhdWzIwXTsgCmludCB0b3AgPSAtMTsgICAgICAKCgp2b2lkIHB1c2goY29uc3QgY2hhciAqc3ltKQp7CiAgICB0b3ArKzsKICAgIHN0cmNweShzdGFja1t0b3BdLCBzeW0pOwp9Cgp2b2lkIHBvcCgpCnsKICAgIGlmICh0b3AgPj0gMCkgdG9wLS07Cn0KCi8vIFByaW50IGN1cnJlbnQgc3RhY2sgc3RhdGUKdm9pZCBwcmludFN0YWNrKGNvbnN0IGNoYXIgKmFjdGlvbikKewogICAgcHJpbnRmKCIlczogIiwgYWN0aW9uKTsKICAgIGZvciAoaW50IGkgPSAwOyBpIDw9IHRvcDsgaSsrKQogICAgICAgIHByaW50ZigiJXMgIiwgc3RhY2tbaV0pOwogICAgcHJpbnRmKCJcbiIpOwp9CgppbnQgdHJ5UmVkdWNlKCkKewogICAgaWYgKHRvcCA+PSAyICYmCiAgICAgICAgc3RyY21wKHN0YWNrW3RvcCAtIDJdLCAiKCIpID09IDAgJiYKICAgICAgICBzdHJjbXAoc3RhY2tbdG9wIC0gMV0sICJFIikgPT0gMCAmJgogICAgICAgIHN0cmNtcChzdGFja1t0b3BdLCAgICAgIikiKSA9PSAwKQogICAgewogICAgICAgIHBvcCgpOyBwb3AoKTsgcG9wKCk7ICAgICAgICAKICAgICAgICBwdXNoKCJFIik7ICAgICAgICAgICAgICAgICAgICAKICAgICAgICBwcmludFN0YWNrKCJSZWR1Y2UiKTsKICAgICAgICByZXR1cm4gMTsKICAgIH0KICAgIAogICAgaWYgKHRvcCA+PSAyICYmCiAgICAgICAgc3RyY21wKHN0YWNrW3RvcCAtIDJdLCAiRSIpID09IDAgJiYKICAgICAgICBzdHJjbXAoc3RhY2tbdG9wIC0gMV0sICIqIikgPT0gMCAmJgogICAgICAgIHN0cmNtcChzdGFja1t0b3BdLCAgICAgIkUiKSA9PSAwKQogICAgewogICAgICAgIHBvcCgpOyBwb3AoKTsgcG9wKCk7CiAgICAgICAgcHVzaCgiRSIpOwogICAgICAgIHByaW50U3RhY2soIlJlZHVjZSIpOwogICAgICAgIHJldHVybiAxOwogICAgfQoKICAgIGlmICh0b3AgPj0gMiAmJgogICAgICAgIHN0cmNtcChzdGFja1t0b3AgLSAyXSwgIkUiKSA9PSAwICYmCiAgICAgICAgc3RyY21wKHN0YWNrW3RvcCAtIDFdLCAiKyIpID09IDAgJiYKICAgICAgICBzdHJjbXAoc3RhY2tbdG9wXSwgICAgICJFIikgPT0gMCkKICAgIHsKICAgICAgICBwb3AoKTsgcG9wKCk7IHBvcCgpOwogICAgICAgIHB1c2goIkUiKTsKICAgICAgICBwcmludFN0YWNrKCJSZWR1Y2UiKTsKICAgICAgICByZXR1cm4gMTsKICAgIH0KCiAgICAvLyBSdWxlOiBFIC0+IGlkCiAgICAvLyBUb3AgaXMgYW4gaWRlbnRpZmllciAobm90IGEgc3BlY2lhbCBzeW1ib2wpCiAgICBpZiAodG9wID49IDAgJiYKICAgICAgICBzdHJjbXAoc3RhY2tbdG9wXSwgIkUiKSAhPSAwICYmCiAgICAgICAgc3RyY21wKHN0YWNrW3RvcF0sICIrIikgIT0gMCAmJgogICAgICAgIHN0cmNtcChzdGFja1t0b3BdLCAiKiIpICE9IDAgJiYKICAgICAgICBzdHJjbXAoc3RhY2tbdG9wXSwgIigiKSAhPSAwICYmCiAgICAgICAgc3RyY21wKHN0YWNrW3RvcF0sICIpIikgIT0gMCkKICAgIHsKICAgICAgICBwb3AoKTsKICAgICAgICBwdXNoKCJFIik7CiAgICAgICAgcHJpbnRTdGFjaygiUmVkdWNlIik7CiAgICAgICAgcmV0dXJuIDE7CiAgICB9CgogICAgcmV0dXJuIDA7IC8vIE5vIHJlZHVjdGlvbiBwb3NzaWJsZQp9CgppbnQgbmV4dFRva2VuKGNvbnN0IGNoYXIgKmlucHV0LCBpbnQgKnBvcywgY2hhciAqb3V0KQp7CiAgICBpbnQgbGVuID0gc3RybGVuKGlucHV0KTsKCiAgICAvLyBTa2lwIHdoaXRlc3BhY2UKICAgIHdoaWxlICgqcG9zIDwgbGVuICYmIGlzc3BhY2UoKHVuc2lnbmVkIGNoYXIpaW5wdXRbKnBvc10pKQogICAgICAgICgqcG9zKSsrOwoKICAgIGlmICgqcG9zID49IGxlbikgcmV0dXJuIDA7IC8vIE5vIG1vcmUgdG9rZW5zCgogICAgY2hhciBjaCA9IGlucHV0Wypwb3NdOwoKICAgIC8vIFNpbmdsZS1jaGFyYWN0ZXIgdG9rZW5zOiBvcGVyYXRvcnMgYW5kIHBhcmVudGhlc2VzCiAgICBpZiAoY2ggPT0gJysnIHx8IGNoID09ICcqJyB8fCBjaCA9PSAnKCcgfHwgY2ggPT0gJyknKQogICAgewogICAgICAgIG91dFswXSA9IGNoOwogICAgICAgIG91dFsxXSA9ICdcMCc7CiAgICAgICAgKCpwb3MpKys7CiAgICAgICAgcmV0dXJuIDE7CiAgICB9CiAgICAKICAgIGlmIChpc2FscGhhKCh1bnNpZ25lZCBjaGFyKWNoKSB8fCBjaCA9PSAnXycpCiAgICB7CiAgICAgICAgaW50IHN0YXJ0ID0gKnBvczsKICAgICAgICB3aGlsZSAoKnBvcyA8IGxlbiAmJiAoaXNhbG51bSgodW5zaWduZWQgY2hhcilpbnB1dFsqcG9zXSkgfHwgaW5wdXRbKnBvc10gPT0gJ18nKSkKICAgICAgICAgICAgKCpwb3MpKys7CiAgICAgICAgaW50IHRsZW4gPSAqcG9zIC0gc3RhcnQ7CiAgICAgICAgc3RybmNweShvdXQsIGlucHV0ICsgc3RhcnQsIHRsZW4pOwogICAgICAgIG91dFt0bGVuXSA9ICdcMCc7CiAgICAgICAgcmV0dXJuIDE7CiAgICB9CgogICAgKCpwb3MpKys7CiAgICByZXR1cm4gMDsKfQoKdm9pZCBzaGlmdFJlZHVjZVBhcnNlKGNvbnN0IGNoYXIgKmlucHV0KQp7CiAgICB0b3AgPSAtMTsgCgogICAgaW50IHBvcyA9IDA7CiAgICBjaGFyIHRva2VuWzUwXTsKCiAgICB3aGlsZSAobmV4dFRva2VuKGlucHV0LCAmcG9zLCB0b2tlbikpCiAgICB7CiAgICAgICAgcHVzaCh0b2tlbik7CiAgICAgICAgcHJpbnRTdGFjaygiU2hpZnQiKTsKCiAgICAgICAgd2hpbGUgKHRyeVJlZHVjZSgpKTsKICAgIH0KCiAgICB3aGlsZSAodHJ5UmVkdWNlKCkpOwoKICAgIGlmICh0b3AgPT0gMCAmJiBzdHJjbXAoc3RhY2tbMF0sICJFIikgPT0gMCkKICAgICAgICBwcmludGYoIlN0cmluZyBBY2NlcHRlZFxuIik7CiAgICBlbHNlCiAgICAgICAgcHJpbnRmKCJTdHJpbmcgUmVqZWN0ZWRcbiIpOwp9CgppbnQgbWFpbigpCnsKICAgIGNoYXIgaW5wdXRbMjAwXTsKICAgIHByaW50ZigiRW50ZXIgYW4gRXhwcmVzc2lvbjpcbiIpOwogICAgZmdldHMoaW5wdXQsIDIwMCwgc3RkaW4pOwoKICAgIGludCBsZW4gPSBzdHJsZW4oaW5wdXQpOwogICAgaWYgKGxlbiA+IDAgJiYgaW5wdXRbbGVuIC0gMV0gPT0gJ1xuJykKICAgICAgICBpbnB1dFtsZW4gLSAxXSA9ICdcMCc7CgogICAgc2hpZnRSZWR1Y2VQYXJzZShpbnB1dCk7CgogICAgcmV0dXJuIDA7Cn0=