Lex, Yacc and C Compiler Programs

Lex Program to recognize valid arithmetic operators. Identifiers could be any integers and operators could be + and *. Count and print the ids and ops seperately

Program

Lex File

%{
    #include < stdio.h > 
    #include < stdlib.h > 
    int op_c = 0, id_c = 0, bc = -1;
    int id[10];
    char op[10],br[10];
%}
%%
[0-9]+      { id[id_c++] = atoi(yytext); }
[+\-*/]     { op[op_c++] = yytext[0]; }
"("         {br[++bc]='(';}
")"         {if(br[bc]!='('){printf("Invalid\n");exit(0);}else{--bc;}}
[\n]        {return 0;}
.           { printf("Invalid character: %s\n", yytext); }
%%
int main() {
    yylex();
    if (id_c  >  op_c && bc == -1 || (op_c==0&&id_c==0)) {
        printf("\nIdentifiers (%d): ", id_c);
        for (int i = 0; i <  id_c; i++)
            printf("%d\t", id[i]);

        printf("\nOperators (%d): ", op_c);
        for (int i = 0; i <  op_c; i++)
            printf("%c\t", op[i]);

        printf("\n");
    } else {
        printf("Invalid expression\n");
    }
    return 0;
}

YACC Program to evaluate arithmetic expressions.

Program

Yacc File

%{
            #include< stdio.h > 
            #include< stdlib.h > 
            int result;  
        %}
        
        %token NUM
        %left '+' '-'
        %left '*' '/'
        
        %%
        S:  E             {result=$1;}
        E:  E '+' E       {$$=$1+$3;}
         |  E '-' E       {$$=$1-$3;}
         |  E '*' E       {$$=$1*$3;}
         |  E '/' E       {if($3!=0)$$=$1/$3;else{printf("Invalid\n");exit(0);}}
         |  '(' E ')'     {$$=$2;}
         |  NUM;
        %%
        
        int main(){
            printf("Enter Expression:");
            yyparse();
            printf("Result: %d\n",result);
        }yyerror(){
            printf("Invalid\n");
            exit(0);
        }

Lex File

%{
            #include "y.tab.h"  
        %}
        %%
        [0-9]+  {yylval=atoi(yytext);return NUM;}
        [ \t]   ;
        \n      {return 0;}
        .       {return yytext[0];}
        %%

YACC Program to recognize a^n b.

Program

Yacc File

%{
        #include< stdio.h > 
        #include< stdlib.h >     
    %}
    
    %token A B
    %%
    S: C
    C: A C | B;
    %%
    
    int main(){
        printf("Enter String:");
        yyparse();
        printf("Valid\n");
    }yyerror(){
        printf("Invalid\n");
        exit(0);
    }

Lex File

%{
        #include "y.tab.h"    
    %}
    %%
    [a]     {return A;}
    [b]     {return B;}
    [ \t]   ;
    \n      {return 0;}
    .       {return yytext[0];}
    %%

C Program Shift Reduce Parsing.

Program

C File

#include< stdio.h > 
            #include< stdlib.h > 
            #include< string.h > 
            
            char a[20],stk[20];
            int i=0,j=0,c=0,length;
            
            void check(){
                int z;
                for(z=0;z< length;z++){
                    if(stk[z]=='i'&&stk[z+1]=='d'){
                        printf("\n$%s\t\t%s$\t\tReduce id",stk,a);
                        stk[z]='E';
                        stk[z+1]=' ';
                        j++;
                    }
                }
                for(z=0;z< length;z++){
                    if(stk[z]=='E'&&(stk[z+1]=='+'||stk[z+1]=='*')&&stk[z+2]=='E'){
                        printf("\n$%s\t\t%s$\t\tReduce %c%c%c",stk,a,stk[z],stk[z+1],stk[z+2]);
                        stk[z]='E';
                        stk[z+1]=' ';
                        stk[z+2]=' ';
                        i-=2;
                    }
                }
                for(z=0;z< length;z++){
                    if(stk[z]=='('&&stk[z+1]=='E'&&stk[z+2]==')'){
                        printf("\n$%s\t\t%s$\t\tReduce %c%c%c",stk,a,stk[z],stk[z+1],stk[z+2]);
                        stk[z]='E';
                        stk[z+1]=' ';
                        stk[z+2]=' ';
                        i-=2;
                    }
                }
            }
            
            void main(){
                printf("Given Grammar:\nE- > E+E\n  |E*E\n  |(E)\n  |id\n");
                printf("Enter input:");
                scanf("%s",a);
                length=strlen(a);
                printf("Stack\t\tInput\t\tAction");
                for(i=0,j=0;j< length;j++,i++){
                    if(a[j]=='i'&&a[j+1]=='d'){
                        printf("\n$%s\t\t%s$\t\tShift id",stk,a);
                        stk[i]=a[j];
                        stk[i+1]=a[j+1];
                        stk[i+2]='\0';
                        a[j]=' ';
                        a[j+1]=' ';
                        check();
                    }else{
                        printf("\n$%s\t\t%s$\t\tShift %c",stk,a,a[j]);
                        stk[i]=a[j];
                        stk[i+1]='\0';
                        a[j]=' ';
                        check();
                    }
                }
                printf("\n$%s\t\t%s$\n",stk,a);
            }

C Program to convert to Machine Code.

Program

C File

#include < stdio.h > 
            #include < stdlib.h > 
            #include < string.h > 
            
            int main() {
                char res[32], arg1[32], op[32], arg2[32];
                FILE *inFile = fopen("in.txt", "r");
                FILE *outFile = fopen("out.txt", "w");
                while (1) {
                    fscanf(inFile, "%s %s %s %s", res, arg1, op, arg2);
                    if (!strcmp(res, "----")) break;
                    if (!strcmp(op, "=")) {
                        fprintf(outFile, "MOV R0, %s\n", arg1);
                        fprintf(outFile, "MOV %s, R0\n", res);
                    } else {
                        fprintf(outFile, "MOV R0, %s\n", arg1);
            
                        if (!strcmp(op, "+")) {
                            fprintf(outFile, "ADD R0, %s\n", arg2);
                        } else if (!strcmp(op, "-")) {
                            fprintf(outFile, "SUB R0, %s\n", arg2);
                        } else if (!strcmp(op, "*")) {
                            fprintf(outFile, "MUL R0, %s\n", arg2);
                        } else if (!strcmp(op, "/")) {
                            fprintf(outFile, "DIV R0, %s\n", arg2);
                        }
            
                        fprintf(outFile, "MOV %s, R0\n", res);
                    }
                }
            
                fclose(inFile);
                fclose(outFile);
                return 0;
            }
            

in.txt File

T1 -B = ?
            T2 C + D
            T3 T1 * T2
            A T3 = ?
            ----

Lex Program to eliminate comments.

Program

Lex File

%{
            #include< stdio.h > 
            #include< string.h > 
            int count=0;
        %}
        %%
        "//".*              {count++;}
        ("/*"(.|\n)*"*/")   {count++;}
        .                   {fprintf(yyout,"%s",yytext);}
        %%
        int main(){
            char inFile[20],outFile[20];
            strcpy(inFile,"in.c");
            strcpy(outFile,"out.c");
            yyin=fopen(inFile,"r");
            yyout=fopen(outFile,"w");
            yylex();
            printf("%d Comments removed from %s and written to %s\n",count,inFile,outFile);
        }

in.c File

#include 

            /*
             * This program calculates the factorial of a number
             * entered by the user.
             * It uses a loop (iterative approach) to compute the factorial.
             */
            
            int factorial(int n) {
                int result = 1;
            
                // Multiply result by all numbers from 1 to n
                for (int i = 1; i < = n; i++) {
                    result *= i;  // result = result * i
                }
            
                return result;  // Return the final factorial value
            }
            
            int main() {
                int number;
            
                // Prompt user for input
                printf("Enter a positive integer: ");
                scanf("%d", &number);
            
                // Validate input
                if (number <  0) {
                    // Negative numbers do not have factorials
                    printf("Factorial is not defined for negative numbers.\n");
                } else {
                    // Display the factorial result
                    printf("Factorial of %d is %d\n", number, factorial(number));
                }
            
                return 0;  // Exit the program
            }
            

YACC Program to recognize valid Identifiers,keywords and operators in a file.

Program

Yacc File

%{
            #include< stdio.h > 
            #include< stdlib.h > 
            int k=0,i=0,o=0,d=0;
            extern FILE *yyin;    
        %}
        %token KEY OP DIGIT ID
        %%
        S: KEY S    {k++;}
         | ID S     {i++;}
         | DIGIT S  {d++;}
         | OP S     {o++;}
         | OP       {o++;}
         | ID       {i++;}
         | KEY      {k++;}
         | DIGIT    {d++;}
        %%
        int main(){
            yyin=fopen("input.c","r");
            do{
                yyparse();
            }while(!feof(yyin));
            printf("K:%d\nI:%d\nD:%d\nO:%d\n",k,i,d,o);
        }yyerror(){
            printf("Invalid");
            exit(0);
        }

Lex File

%{
            #include "y.tab.h"
        %}
        %%
        "if"|"int"|"else"|"return"|"printf"|"void"|"main"|"for"|"while" {printf("Keyword is %s\n",yytext);return KEY;}
        [a-zA-Z_][a-zA-Z_0-9]* {printf("Identifier is %s\n",yytext);return ID;}
        [0-9]+  {yylval=atoi(yytext);printf("Digit is %d\n",yylval),return DIGIT;}
        [ > < \+\-\*\/\=\(\)] {printf("Operator is %s\n",yytext);return OP;}
        .|\n ;
        %%

input.c File

#include < stdio.h > 

            void main() {
                int i;
            
                for(i = 0; i <  5; i++) {
                    if(i % 2 == 0) {
                        printf("Even\n");
                    } else {
                        printf("Odd\n");
                    }
                }
            
                return;
            }