0% found this document useful (0 votes)
5 views31 pages

C Programs for Lexical Analysis and Parsing

The document contains multiple C programs related to compiler design concepts such as lexical analysis, parsing, and intermediate code generation. It includes functionalities for tokenizing input, constructing NFA transitions, parsing expressions using recursive descent, and generating three-address code representations. The programs demonstrate various techniques like constant propagation, syntax error handling, and operator precedence parsing.

Uploaded by

pranavrmallia
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views31 pages

C Programs for Lexical Analysis and Parsing

The document contains multiple C programs related to compiler design concepts such as lexical analysis, parsing, and intermediate code generation. It includes functionalities for tokenizing input, constructing NFA transitions, parsing expressions using recursive descent, and generating three-address code representations. The programs demonstrate various techniques like constant propagation, syntax error handling, and operator precedence parsing.

Uploaded by

pranavrmallia
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

#include<stdio.

h>

#include<ctype.h>

#include<string.h>

int main()

FILE *input, *output;

int l=1;

int t=0;

int j=0;

int i,flag;

char ch,str[20];

input = fopen("[Link]","r");

output = fopen("[Link]","w");

char keyword[30][30] = {"int","main","if","else","do","while"};

fprintf(output,"Line no. \t Token no. \t\t Token \t\t Lexeme\n\n");

while(!feof(input))

i=0;

flag=0;

ch=fgetc(input);

if( ch=='+' || ch== '-' || ch=='*' || ch=='/' )

fprintf(output,"%7d\t\t %7d\t\t Operator\t %7c\n",l,t,ch);

t++;

}
else if( ch==';' || ch=='{' || ch=='}' || ch=='(' || ch==')' || ch=='?' ||
ch=='@' ||ch=='!' || ch=='%')

fprintf(output,"%7d\t\t %7d\t\t Special symbol\t %7c\n",l,t,ch);

t++;

else if(isdigit(ch))

fprintf(output,"%7d\t\t %7d\t\t Digit\t\t %7c\n",l,t,ch);

t++;

else if(isalpha(ch))

str[i]=ch;

i++;

ch=fgetc(input);

while(isalnum(ch) && ch!=' ')

str[i]=ch;

i++;

ch=fgetc(input);

str[i]='\0';

for(j=0;j<=30;j++)

if(strcmp(str,keyword[j])==0)
{

flag=1;

break;

if(flag==1)

fprintf(output,"%7d\t\t %7d\t\t Keyword\t %7s\n",l,t,str);

t++;

else

fprintf(output,"%7d\t\t %7d\t\t Identifier\t %7s\n",l,t,str);

t++;

else if(ch=='\n')

l++;

fclose(input);

fclose(output);

return 0;

#include <stdio.h>

#include <string.h>
#define MAX 20

int e[MAX][MAX];

int vis[MAX];

int states;

void dfs(int state) {

vis[state] = 1;

for (int i = 0; i < states; i++) {

if (e[state][i] && !vis[i])

dfs(i);

int main() {

int i, j, n;

printf("Enter number of states in NFA: ");

scanf("%d", &states);

memset(e, 0, sizeof(e));

printf("Enter number of epsilon transitions: ");

scanf("%d", &n);

printf("Enter transitions:\n");

for (i = 0; i < n; i++) {

int from, to;


scanf("%d %d", &from, &to);

e[from][to] = 1;

for (i = 0; i < states; i++) {

memset(vis, 0, sizeof(vis));

dfs(i);

printf("E-closure(%d): ", i);

for (j = 0; j < states; j++) {

if (vis[j])

printf("%d ", j);

printf("\n");

return 0;

//exp 7:

#include <stdio.h>
#include <stdlib.h>

#include <ctype.h>

char *input;

char lookahead;

void error() {

printf("Syntax Error\n");

exit(1);

void match(char t) {

if (lookahead == t) {

lookahead = *++input; // move to next character

} else {

error();

// Grammar functions

void E(); // Expression

void E_();

void T(); // Term

void T_();

void F(); // Factor

void E() {

T();

E_();
}

void E_() {

if (lookahead == '+' || lookahead == '-') {

match(lookahead);

T();

E_();

// epsilon → do nothing

void T() {

F();

T_();

void T_() {

if (lookahead == '*' || lookahead == '/') {

match(lookahead);

F();

T_();

// epsilon → do nothing

void F() {

if (isalpha(lookahead)) { // variable (id)

match(lookahead);

} else if (isdigit(lookahead)) { // single digit number


match(lookahead);

} else if (lookahead == '(') { // (E)

match('(');

E();

match(')');

} else {

error();

int main() {

char expr[100];

printf("Enter an expression: ");

scanf("%s", expr);

input = expr;

lookahead = *input;

E();

if (lookahead == '\0')

printf("Parsing successful\n");

else

printf("Syntax Error\n");

return 0;

}
10) #include <stdio.h>

#include <string.h>

struct Quadruple {

char op[5];

char arg1[10];

char arg2[10];

char result[10];

};

struct Triple {

char op[5];

char arg1[10];

char arg2[10];

};

int main() {

int n, i;

struct Quadruple Q[20];

struct Triple T[20];

printf("Enter number of three address code statements: ");

scanf("%d", &n);

printf("\nEnter TAC in the form: result = arg1 op arg2\n");

printf("(Use '_' if operand is not present)\n");

for(i = 0; i < n; i++) {

printf("\nStatement %d:\n", i+1);

printf("Operator: ");

scanf("%s", Q[i].op);

printf("Arg1: ");

scanf("%s", Q[i].arg1);

printf("Arg2: ");

scanf("%s", Q[i].arg2);
printf("Result: ");

scanf("%s", Q[i].result);

strcpy(T[i].op, Q[i].op);

strcpy(T[i].arg1, Q[i].arg1);

strcpy(T[i].arg2, Q[i].arg2);

printf("\n--- Quadruple Representation ---\n");

printf("Op\tArg1\tArg2\tResult\n");

for(i = 0; i < n; i++) {

printf("%s\t%s\t%s\t%s\n",

Q[i].op, Q[i].arg1, Q[i].arg2,

Q[i].result);

printf("\n--- Triple Representation ---\n");

printf("Index\tOp\tArg1\tArg2\n");

for(i = 0; i < n; i++) {

printf("%d\t%s\t%s\t%s\n", i,

T[i].op, T[i].arg1, T[i].arg2);

} return 0;

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <ctype.h>

typedef struct {

int value;

int is_const;
} Variable;

int main() {

Variable vars[26] = {0};

int n;

printf("Enter number of statements: ");

scanf("%d", &n);

getchar();

char statements[100][100];

printf("Enter all statements (one per line):\n");

for (int i = 0; i < n; i++) {

fgets(statements[i], sizeof(statements[i]), stdin);

statements[i][strcspn(statements[i], "\n")] = '\0';

printf("\nAfter Constant Propagation:\n");

for (int i = 0; i < n; i++) {

char line[100];

strcpy(line, statements[i]);

char tokens[5][20];

int t = 0;

char *tok = strtok(line, " =\t");

while (tok != NULL) {

strcpy(tokens[t++], tok);

tok = strtok(NULL, " =\t");

}
if (t < 2)

continue;

char dest = tokens[0][0];

// Case 1: Simple assignment (a = 5 or a = b)

if (t == 2) {

if (isdigit(tokens[1][0])) {

vars[dest - 'a'].value = atoi(tokens[1]);

vars[dest - 'a'].is_const = 1;

printf("%c = %d\n", dest, vars[dest - 'a'].value);

} else {

char src = tokens[1][0];

vars[dest - 'a'].value = vars[src - 'a'].value;

vars[dest - 'a'].is_const = vars[src - 'a'].is_const;

if (vars[src - 'a'].is_const)

printf("%c = %d\n", dest, vars[dest - 'a'].value);

else

printf("%c = %c\n", dest, src);

// Case 2: Arithmetic operation (a = b + c)

else if (t == 4) {

char *op1 = tokens[1];

char oper = tokens[2][0];

char *op2 = tokens[3];

int v1 = isdigit(op1[0]) ? atoi(op1) : vars[op1[0] - 'a'].value;

int v2 = isdigit(op2[0]) ? atoi(op2) : vars[op2[0] - 'a'].value;


int c1 = isdigit(op1[0]) ? 1 : vars[op1[0] - 'a'].is_const;

int c2 = isdigit(op2[0]) ? 1 : vars[op2[0] - 'a'].is_const;

if (c1 && c2) {

int result = 0;

switch (oper) {

case '+': result = v1 + v2; break;

case '-': result = v1 - v2; break;

case '*': result = v1 * v2; break;

case '/':

if (v2 == 0) {

printf("Error: Division by zero in %c = %s / %s\n", dest,


op1, op2);

continue;

result = v1 / v2;

break;

vars[dest - 'a'].value = result;

vars[dest - 'a'].is_const = 1;

printf("%c = %d\n", dest, result);

} else {

vars[dest - 'a'].is_const = 0;

// Substitute constants where possible

char left[20], right[20];

if (c1)

sprintf(left, "%d", v1);

else
sprintf(left, "%s", op1);

if (c2)

sprintf(right, "%d", v2);

else

sprintf(right, "%s", op2);

printf("%c = %s %c %s\n", dest, left, oper, right);

return 0;

#include<stdio.h>

#include<string.h>

#define MAX 100

char symbols[]={'i','+','-','*','/','(',')','$'};

char precedence[8][8] = {

/* id + - * / ( ) $ */

/* id */ { 'e','>','>','>','>','e','>','>' },

/* + */ { '<','>','>','<','<','<','>','>' },
/* - */ { '<','>','>','<','<','<','>','>' },

/* * */ { '<','>','>','>','>','<','>','>' },

/* / */ { '<','>','>','>','>','<','>','>' },

/* ( */ { '<','<','<','<','<','<','=','e' },

/* ) */ { 'e','>','>','>','<','e','>','>' },

/* $ */ { '<','<','<','<','<','<','e','a' },

};

int getIndex(char c){

for (int i = 0; i < 8; i++ ){

if (symbols[i]==c)

return i;

return -1;

void printStack(char stack[], int top) {

for (int i = 0; i <= top; i++)

printf("%c", stack[i]);

int main(){

char input[MAX],stack[MAX];

int top=0, ip=0;

printf("Enter the expression:");

scanf("%s",input);

strcat(input,"$");
stack[top]='$';

printf("\n%-15s %-15s %-15s\n","Stack","Input","Action");

while(1){

printStack(stack, top);

for(int k=0; k<15-top;k++)

printf(" ");

printf("%s",&input[ip]);

for(int k=0;k<16-strlen(&input[ip]);k++)

printf(" ");

int i;

if(stack[top]=='E' && top>0)

i=getIndex(stack[top-1]);

else

i=getIndex(stack[top]);

int j=getIndex(input[ip]);

if(i == -1 || j == -1){

printf("Invalid symbol\n");

break;

char relation=precedence[i][j];

if(relation == '<' || relation == '='){

stack[++top]=input[ip++];
printf("Shift\n");

else if(relation == '>'){

if(stack[top]=='i'){

stack[top]='E';

printf("Reduce by production: E -> id\n");

else if( top>=2 && stack[top]==')'&& stack[top-1]=='E' &&


stack[top-2]=='('){

top-=2;

stack[top]='E';

printf("Reduce by production: E -> (E)\n");

else if (top >= 2 && stack[top] == 'E' &&(stack[top-1] == '+' ||


stack[top-1] == '-' ||stack[top-1] == '*' || stack[top-1] == '/')
&&stack[top-2] == 'E') {

char op=stack[top-1];

top-=2;

stack[top] = 'E'; // reduce to E

if (op == '+')

printf("Reduce by production: E -> E + E\n");

else if (op == '-')

printf("Reduce by production: E -> E - E\n");

else if (op == '*')

printf("Reduce by production: E -> E * E\n");

else if (op == '/')

printf("Reduce by production: E -> E / E\n");

}
else{

printf("Error invalid handle\n");

break;

else if (relation =='a'){

if (stack[top] == 'E' && input[ip] == '$') {

printf("ACCEPT\n");

break;

} else {

printf("ERROR: Invalid accept state\n");

break;

else{

printf("ERROR: Invalid precedence\n");

break;

return 0;

9)

#include <stdio.h>

#include <string.h>

#include <ctype.h>

int tempCount = 1;

void newTemp(char *temp){


sprintf(temp, "t%d", tempCount++);

int precedence(char op){

if (op == '*' || op == '/')

return 2;

if (op == '+' || op == '-')

return 1;

return 0;

void generateTAC(char exp[]) {

char stack[100], post[100];

int top = -1, k = 0;

for (int i = 0; exp[i]; i++) {

char c = exp[i];

if (isalnum(c)) {

post[k++] = c;

else if (c == '(') {

stack[++top] = c;

else if (c == ')') {

while (top != -1 && stack[top] != '(') {

post[k++] = stack[top--];

top--;

else {

while (top != -1 && precedence(stack[top]) >= precedence(c)) {

post[k++] = stack[top--];
}

stack[++top] = c;

while (top != -1) {

post[k++] = stack[top--];

post[k] = '\0';

char tacStack[100][10];

int tacTop = -1;

int idx=0;

for (int i = 0; i < k; i++) {

char c = post[i];

if (isalnum(c)) {

char operand[2] = {c, '\0'};

strcpy(tacStack[++tacTop], operand);

else {

char op2[10], op1[10], result[10];

strcpy(op2, tacStack[tacTop--]);

strcpy(op1, tacStack[tacTop--]);

newTemp(result);

printf("%s=%s%c%s\n", result, op1, c, op2);

strcpy(tacStack[++tacTop], result);

int main(){

char exp[100];
printf("Enter an expression: ");

scanf("%s", exp);

printf("\nThree Address Code:\n");

generateTAC(exp);

return 0;

%{

#include <stdio.h>

int line = 1; // Line count (start from 1)

int words = 0; // Word count

int chars = 0; // Character count

%}

/* Define a regular expression for a 'word' */

word [a-zA-Z0-9]+

%%

{word} { words++; chars += yyleng; } // Count words and characters

\n { line++; chars++; } // Increment line and character count

. { chars++; } // Count every other character


%%

int yywrap() {

return 1;

int main() {

FILE *fp = fopen("[Link]", "r");

if (!fp) {

printf("Error: Could not open file.\n");

return 1;

yyin = fp; // Set input file for lex

yylex(); // Start lexical analysis

fclose(fp); // Close file

printf("\nNumber of words : %d", words);

printf("\nNumber of lines : %d", line);

printf("\nNumber of characters : %d\n", chars);

return 0;

%{

#include<stdio.h>

int vowel = 0;
int consonant = 0;

%}

%%

[aAeEiIoOuU] {vowel++;}

[a-zA-Z] {consonant++;}

,;

%%

int yywrap() {

return 1;

int main() {

printf("Enter string:");

yylex();

printf("Consonant : %d\n", consonant);

printf("Vowel : %d\n", vowel);

return 0;

%{
#include<stdio.h>

%}

%%

"abc" {printf("ABC");}

.\n {ECHO;}

%%

int yywrap(){

return 1;

int main(){

printf("Enter String:");

yylex();

return 0;

%{

#include<stdio.h>

%}

letter [a-zA-Z]

digit [0-9]

%%
"#".* {printf("Pre Processor Directive: %s\n",yytext);}

"void"|"main"|"if"|"else"|"int"|"char"|"float"|"switch"|"for"|"printf"|"while"
{printf("Keyword: %s\n",yytext);}

{letter}({letter}|{digit}|"_")* {printf("Identifier: %s\n",yytext);}

"*"|"+"|"-"|"%"|"^" {printf("Arithmetic Operator: %s\n",yytext);}

\"([^\\"]|\\.)*\" {printf("Literal :%s\n",yytext);}

"=" {printf("Assignment Operator: %s\n",yytext);}

"{"|"}"|","|";"|")"|"(" {printf("Punctuator : %s\n",yytext);}

">"|">="|"<"|"<="|"==" {printf("Relational Operator :%s\n",yytext);}

{digit}+(["."]?{digit}*) {printf("Number :%s\n",yytext);}

[ \t\n]+ { /* skip whitespace */ }

%%

int yywrap(){

return 1;

int main(){
yyin=fopen("input.c","r");

yylex();

fclose(yyin);

return 0;

%{

#include<stdio.h>

int count_zero=0;

int valid =1;

%}

%%

0 {count_zero++; if(count_zero>3) valid=0;}

1;

[^01\n]+ {valid=0;}

\n {return 0;}

%%

int yywrap(){

return 0;

int main(){

printf("Enter string : ");

yylex();
if(valid){

printf("Accepted\n");

else{

printf("Rejected\n");

return 0;

%{

#include <stdio.h>

#include <string.h>

char prev = '\0', curr = '\0';

int valid = 1;

%}

%%

[01] {

prev = curr;

curr = yytext[0];

[^01\n]+ {valid = 0;}

\n {return 0;}

%%
int yywrap() {

return 1;

int main() {

printf("Enter string: ");

yylex();

if (!valid) {

printf("Rejected (Invalid characters)\n");

} else if (prev == '\0') {

printf("Rejected (Too short)\n");

} else if (prev == curr) {

printf("Accepted\n");

} else {

printf("Rejected (Last two symbols differ)\n");

return 0;

%{

#include <stdio.h>

char last[3] = {'\0', '\0', '\0'};

int valid = 1;

int len = 0;
%}

%%

[01] {

last[0] = last[1];

last[1] = last[2];

last[2] = yytext[0];

len++;

[^01\n]+ {

valid = 0;

\n {

return 0;

%%

int yywrap() {

return 1;

int main() {

printf("Enter string: ");

yylex();
if (!valid) {

printf("Rejected (Invalid characters)\n");

} else if (len < 2) {

printf("Rejected (Too short)\n");

} else if (last[0] == '1' || last[1] == '1') {

printf("Accepted\n");

} else {

printf("Rejected\n");

return 0;

%{

#include<stdio.h>

int count_a=0;

int count_b=0;

int valid =1;

int seen_b=0;

%}

%%

a {count_a++; if(seen_b)valid=0;}

b {seen_b=1; count_b++;}

[^ab\n]+ {valid=0;}

\n {return 0;}
%%

int yywrap(){

return 0;

int main(){

printf("Enter string : ");

yylex();

if(!valid){

printf("Invalid String\n");

else if(count_a%2==0 && count_b%2!=0){

printf("Accepted\n");

else{

printf("Rejected\n");

return 0;

You might also like