0% found this document useful (0 votes)
9 views22 pages

Compiler Design: Lex & YACC Practical Guide

The document outlines various practical implementations in Compiler Design, including finite automata, lexical analysis using Lex, and parsing with YACC. It provides code examples for string validation, keyword identification, comment extraction, and arithmetic expression evaluation. Additionally, it covers the integration of Lex and YACC for building a simple calculator and analyzing text files for character, word, and line counts.

Uploaded by

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

Compiler Design: Lex & YACC Practical Guide

The document outlines various practical implementations in Compiler Design, including finite automata, lexical analysis using Lex, and parsing with YACC. It provides code examples for string validation, keyword identification, comment extraction, and arithmetic expression evaluation. Additionally, it covers the integration of Lex and YACC for building a simple calculator and analyzing text files for character, word, and line counts.

Uploaded by

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

200490131008 Compiler Design

Practical: 1
Aim: Implementation of Finite Automata and String Validation.

Code:

#include<stdio.h>
#define max 100
int main()
{
char str[max], f='a';
int i;
printf("Enter a string: ");
scanf("%s",str);
for(i=0; str[i]!='\0'; i++)
{
switch(f)
{
case 'a':
if(str[i]=='0')
{
f='b';
}
else if(str[i]=='1')
{
f='a';
}
break;
case 'b':
if(str[i]=='0')
{
f='b';
}
else if(str[i]=='1')
{
f='c';
}
break;
case 'c':
if(str[i]=='0')
{
f='b';
}
else if(str[i]=='1')
{

f='a';
}
break;
}

SNPITRC/CSE/2025-26/SEM-7/3170710 Page |1
200490131008 Compiler Design

}
if(f=='c')
{
printf("String Accepted..!");
}
else
{
printf("String Not Accepted..!");
}
}

Output:

SNPITRC/CSE/2025-26/SEM-7/3170710 Page |2
200490131008 Compiler Design

Practical: 2
Aim: Introduction to Lex Tool.

Code:

%{
#include <stdio.h>
%}

K if|else|int|char|float
Letter [A-Za-z]
Digit [0-9]
Id ({Letter}|_)+({Letter}|{Digit})*
Op \+|\-|\<|\<=|\>=|\*|\=

%%

{K} {printf("%s is a Keyword\n", yytext); }


{Id} {printf("%s is an identifier\n", yytext); }
{Digit}+ {printf("%s is a number\n", yytext); }
{Op} {printf("%s is an operator\n", yytext); }
[\n\t ]+ {/*Ignore whitespace */}
. {printf("%s is an unrecognized token\n",
yytext);}

%%

int main()
{
printf("Enter the Input: \n");
yylex();
return 0;
}

int yywrap()
{
return 1;
}

SNPITRC/CSE/2025-26/SEM-7/3170710 Page |3
200490131008 Compiler Design

Output:

SNPITRC/CSE/2025-26/SEM-7/3170710 Page |4
200490131008 Compiler Design

Practical 3:
Aim: Implement following Program using Lex
a) Ceasor Cipher

Code:

%{
#include <stdio.h>
#include <ctype.h> // For isalpha, isupper, islower
// Define the shift value
#define SHIFT 3
%}
%%
[a-zA-Z] {
char ch = yytext[0];
if (isupper(ch)) {
putchar('A' + (ch - 'A' + SHIFT) % 26);
} else if (islower(ch)) {
putchar('a' + (ch - 'a' + SHIFT) % 26);
}
}
. {
// Print any other character as is (e.g., spaces,

punctuation, numbers)
putchar(yytext[0]);
}
%%
int main()
{
printf("Enter text to encrypt:\n");
yylex();
return 0;
}
int yywrap()
{
return 1;
}

Output:

SNPITRC/CSE/2025-26/SEM-7/3170710 Page |5
200490131008 Compiler Design

b) Extract single and multiline comments from C program.

Code:
%{
#include <stdio.h>
%}
%%
"/*"([^*]|\*+[^*/])*\*+"/" { printf("\nMulti-line
comment found:\n%s\n", yytext); }

"//".* { printf("\nSingle-
line comment found: \n%s\n", yytext);}
.|\n { }
%%
int main()
{
char fname[100];
printf("Enter the name of the C file: ");
scanf("%s", fname);
yyin = fopen(fname, "r");
if (yyin == NULL)
{
perror("Error opening file");
return 1;
}
printf("\n--- Extracting Comments from '%s'
---\n", fname);
yylex();
fclose(yyin);
printf("--- Comment extraction complete ---
\n");
return 0;
}
int yywrap()
{
return 1;
}

Output:

SNPITRC/CSE/2025-26/SEM-7/3170710 Page |6
200490131008 Compiler Design

Practical: 4
Aim: Implement following Programs Using Lex
a) Convert Roman to Decimal
Code:
%{
#include <stdio.h>
#include <stdlib.h> // For exit()
int total = 0;
%}
%%
"CM" { total += 900; } // 900
"CD" { total += 400; } // 400
"XC" { total += 90; } // 90
"XL" { total += 40; } // 40
"IX" { total += 9; } // 9
"IV" { total += 4; } // 4
"M" { total += 1000; } // 1000
"D" { total += 500; } // 500
"C" { total += 100; } // 100
"L" { total += 50; } // 50
"X" { total += 10; } // 10
"V" { total += 5; } // 5
"I" { total += 1; } // 1
\n { return total; }
. {
fprintf(stderr, "Error: Invalid Roman numeral
symbol'%s'\n", yytext);
exit(1);
}
%%
int main()
{
printf("Enter Roman numeral (use uppercase): ");
yylex();

printf("Decimal equivalent: %d\n", total);


return 0;
}
int yywrap()
{
return 1;
}

SNPITRC/CSE/2025-26/SEM-7/3170710 Page |7
200490131008 Compiler Design

Output:

b) Extract html tags from .html file.

Code:
%{
#include <stdio.h>
%}
%%
\<[^>]*\> { printf("%s\n", yytext); }
.|\n { /* Do nothing - effectively ignores regular
content */ }
%%
int main()
{
char fname[100];
printf("Enter the name of file: ");
scanf("%s",fname);
yyin=fopen(fname,"r");
yylex();
return 0;
}
int yywrap()
{
return 1;
}

SNPITRC/CSE/2025-26/SEM-7/3170710 Page |8
200490131008 Compiler Design

Output:

SNPITRC/CSE/2025-26/SEM-7/3170710 Page |9
200490131008 Compiler Design

Practical: 5
Aim: Write a FLEX program that accepts language of all strings of the form a nbn.

Code:
%{
#include <stdio.h>
int i, ca = 0, cb = 0;
%}
%%
[a]+[b]+ {
for(i=0;i<yyleng;i++)
if(yytext[i]=='a')
ca++;
else if(yytext[i]=='b')
cb++;
if(ca==cb)
printf("String accepted\n");
else
printf("String not accepted\n");
return 0;
}
.+ {
printf("String not accepted\n");
return 0;
}
%%
int main()
{
printf("Enter a string: ");
yylex();
return 0;
}
int yywrap()
{
return 1;
}

Output:

SNPITRC/CSE/2025-26/SEM-7/3170710 P a g e | 10
200490131008 Compiler Design

Practical : 6
Aim: Write a FLEX program to take input from text file and count no of characters,
no. of spaces, no. of lines & no. of words.

Code:
/* FLEX program to read a file and count lines, words,
characters,
and spaces */
%{
#include <stdio.h>
int lines = 0;
int words = 0;
int characters = 0;
int spaces = 0;
int in_word = 0; // Flag to check if inside a word
int last_char = 0; // To detect if last char was newline
%}
%%
\n {
lines++;
characters++;
in_word = 0;
last_char = '\n';

}
[ \t] {
spaces++;
characters++;
in_word = 0;
last_char = yytext[0];

}
[A-Za-z0-9]+ {
characters += yyleng;
if (!in_word)

words++;
in_word = 1;
}
last_char = yytext[yyleng - 1];
}
. {
characters++;
in_word = 0;

last_char = yytext[0];

SNPITRC/CSE/2025-26/SEM-7/3170710 P a g e | 11
200490131008 Compiler Design

%%
int main()
{
char fname[100];
printf("Enter the name of file: ");
scanf("%s", fname);
yyin = fopen(fname, "r");
if (!yyin)
{
printf("Error: Cannot open file %s\n", fname);
return 1;
}
yylex();
//count last line if file doesn’t end with newline
if (characters > 0 && last_char != '\n')
{
lines++;
}
printf("\n--- File Analysis Results ---\n");
printf("Lines : %d\n", lines);
printf("Words : %d\n", words);
printf("Characters : %d\n", characters);
printf("Spaces : %d\n", spaces);
return 0;
}
int yywrap()
{
return 1;
}

Contents of input file ([Link])

Output:

SNPITRC/CSE/2025-26/SEM-7/3170710 P a g e | 12
200490131008 Compiler Design

Practical : 7
AIM: Introduction to YACC and generate calculator program.

What is YACC?
• YACC stands for Yet Another Compiler Compiler, a powerful tool designed to
generate parsers for programming languages and interpreters. It reads a formal
grammar, typically written in Context-Free Grammar (CFG), and produces a C
program that can parse input strings to check whether they followthat grammar.
• In compiler construction, YACC plays the role of the syntax analyzer (or parser). It
takes a stream of tokens — usually generated by a Lexical Analyzer (Lex/Flex) —
and applies grammar rules to analyze their structure.

Lex + YACC Integration Overview:


• The typical process in a compiler front-end involves:
1. Lex (Lexical Analyzer):
o Scans the input text.
o Breaks it into tokens (e.g., numbers, operators, keywords).
o Returns token types to the parser.
2. YACC (Syntax Analyzer):
o Receives tokens from Lex.
o Matches sequences of tokens to grammar rules.
o Executes C code blocks (actions) associated with those rules.

Structure of a YACC Program:


• A YACC file has three main sections:
1. Declarations Section
2. Grammar Rules Section
3. Auxiliary Functions Section
➢ Declarations Section (%{ ... %})
• This is similar to Lex’s declaration section.
• Used for including headers, defining variables, function prototypes, and declaring
tokens and precedence.

• Example:
%{
#include <stdio.h>
#include <stdlib.h>
%}
%token NUM
%left '+' '-'
%left '*' '/'
• %token declares tokens (terminals).
• %left defines associativity and precedence of operators to resolve ambiguity.

SNPITRC/CSE/2025-26/SEM-7/3170710 P a g e | 13
200490131008 Compiler Design

➢ Grammar Rules Section (%% ... %%)


• This section defines how tokens (terminals) and non-terminals are combined.
• Each production rule follows this format:
non_terminal : production_body { action }
• The left-hand side (LHS) is a non-terminal.
• The right-hand side (RHS) can be a mix of terminals and non-terminals.
• The { action } block is C code executed when the rule is matched.
• YACC uses special variables:
o $1, $2, ... to access components of the RHS.
o $$ to represent the value of the LHS.
• Example:
expr : expr '+' expr { $$ = $1 + $3; }
• This rule defines addition of two expressions.
➢ Auxiliary Functions Section
• This section includes:
o main(): the program’s entry point.
o yyparse(): the parser function (automatically generated).
o yyerror(): to handle syntax errors.
• Example:
int main() {
yyparse(); // Starts the parser
return 0;
}
int yyerror(char *s) {
printf("Syntax Error: %s\n", s);
return 0;
}

Compilation and Execution Steps:


Step 1: Save Your Files
• filename.l for Lex code
• filename.y for YACC code
Step 2: Compile Using Terminal
• flex filename.l // generates [Link].c
• bison -d filename.y // generates [Link].c and [Link].h
• gcc [Link].c [Link].c // compile to executable
Step 3: Run the Program
• [Link] // run executable file
Example Program: YACC program for Simple Arithmetic Calculator
/* This example implements a calculator using Lex and
YACC that
can evaluate expressions like:
2 + 3 * 4
(5 - 2) * 6
*/

SNPITRC/CSE/2025-26/SEM-7/3170710 P a g e | 14
200490131008 Compiler Design

Code:
Lex File (prac7.l)

/* Lex file to implement simple arithmetic calculator */


%{
#include "[Link].h"
%}
%%
[0-9]+ { yylval = atoi(yytext); return NUM; }
[ \t] ; // Ignore whitespace
\n return 0; // End on newline
. return yytext[0];
%%
int yywrap()
{
return 1;
}

YACC File (pract7.y)

/* YACC file to implement simple desk calculator */


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

int yylex(void);
int yyerror(char *s);
%}

%token NUM
%left '+' '-'
%left '*' '/'

%%

start: expr { printf("Result: %d\n", $$);


return 0; };
expr : expr '+' expr { $$ = $1 + $3; }
| expr '-' expr { $$ = $1 - $3; }
| expr '*' expr { $$ = $1 * $3; }
| expr '/' expr {
if ($3 == 0) {
printf("Error: Division by zero\n");
$$ = 0;
} else {
$$ = $1 / $3;
}
}
| '('expr')' { $$ = $2; }

SNPITRC/CSE/2025-26/SEM-7/3170710 P a g e | 15
200490131008 Compiler Design

| NUM { $$ = $1; }
;
%%
int main()
{
printf("Enter an arithmetic expression: \n");
yyparse();
}
int yyerror(char *s)
{
fprintf(stderr, "Syntax Error: %s\n", s);
return 0;
}

Output:

SNPITRC/CSE/2025-26/SEM-7/3170710 P a g e | 16
200490131008 Compiler Design

Practical: 8
Aim : Write a YACC program to check syntax of for loop.
Code:
Lex File (pract8.l)

%{
#include "[Link].h"
%}

%%

"for" return FOR;


"(" return OB;
")" return CB;
";" return SEMI;
"=" return EQ;
"++" return INC;
"--" return DEC;
"<=" return LE;
">=" return GE;
"<" return LT;
">" return GT;
"+" return PLUS;
"-" return MINUS;

[0-9]+ return NUM;


[a-zA-Z_][a-zA-Z0-9_]* return ID;

[ \t\r]+ ; // Ignore spaces/tabs


\n return NL;

. return yytext[0];

%%

int yywrap()
{
return 1;
}
YACC File (pract8.y)

%{
#include <stdio.h>
#include <stdlib.h>
%}

%token FOR OB CB SEMI EQ ID NUM LT GT LE GE INC DEC PLUS


MINUS NL

%%

program : stmt NL { printf("Valid 'for' loop syntax.\n");


exit(0); }
;

SNPITRC/CSE/2025-26/SEM-7/3170710 P a g e | 17
200490131008 Compiler Design

stmt : FOR OB init SEMI cond SEMI inc CB


;

init : ID EQ NUM
| /* empty */
;

cond : ID LT NUM
| ID GT NUM
| ID LE NUM
| ID GE NUM
| /* empty */
;

inc : ID INC
| ID DEC
| INC ID
| DEC ID
| /* empty */
;
%%

int main()
{
printf("Enter a 'for' loop header:\n");
yyparse();
return 0;
}

int yyerror(char *s)


{
fprintf(stderr, "Syntax Error: %s\n", s);
return 0;
}

Output:

SNPITRC/CSE/2025-26/SEM-7/3170710 P a g e | 18
200490131008 Compiler Design

Practical: 9
Aim: Write a YACC program to validate syntax of function prototype.

Code:

Lex File (pract9.l)

%{
#include "[Link].h"
%}

%%

"int"|"float"|"double"|"void"|"char" { return BUILTIN; }


[a-zA-Z_][a-zA-Z0-9_]* { return ID; }
"," { return COMMA; }
";" { return SC; }
"(" { return LPAREN; }
")" { return RPAREN; }
[\t \n]+ ; // Ignore whitespace
. { return yytext[0]; }

%%

int yywrap()
{
return 1;
}

YACC File (pract9.y)

%{
#include <stdio.h>
#include <stdlib.h>
%}

%token BUILTIN ID COMMA SC LPAREN RPAREN

%%

S : FUN { printf("Valid function prototype syntax\n");


exit(0); }
;

FUN : BUILTIN ID LPAREN PARAM RPAREN SC


;

PARAM : BUILTIN ID
| PARAM COMMA BUILTIN ID
| /* empty */ // Allows void or empty parameters

SNPITRC/CSE/2025-26/SEM-7/3170710 P a g e | 19
200490131008 Compiler Design

%%

int main()
{
printf("\nEnter function declaration statement:\n");
yyparse();
return 0;
}

int yyerror(char *s)


{
fprintf(stderr, "Syntax Error: %s\n", s);
return 0;
}

Output:

SNPITRC/CSE/2025-26/SEM-7/3170710 P a g e | 20
200490131008 Compiler Design

Practical: 10
Aim: Write a YACC program to validate nested if control statements.

Code:

Lex File (pract10.l)

%{
#include "[Link].h"
%}

%%
"if" return IF;
"(" return LPAREN;
")" return RPAREN;
"{" return LBRACE;
"}" return RBRACE;
"<"|">"|"=="|"<="|">="|"!=" return RELOP;
[0-9]+ return NUMBER;
[a-z][a-zA-Z0-9_]* return ID;
[sS][0-9]* return STMT;
\n return NL;
[ \t]+ ;
. return yytext[0];
%%

int yywrap()
{
return 1;
}

YACC File (pract10.y)

%{
#include <stdio.h>
#include <stdlib.h>
int count = 0;
%}

%token IF RELOP STMT NUMBER ID NL


%token LPAREN RPAREN LBRACE RBRACE

%%

input : stmt NL {
printf("Valid Declaration\nNo. of nested if
statements = %d\n", count);
exit(0);
}
;

SNPITRC/CSE/2025-26/SEM-7/3170710 P a g e | 21
200490131008 Compiler Design

stmt : if_stmt
;

if_stmt : IF LPAREN cond RPAREN LBRACE stmt RBRACE {


count++;
}
| STMT
;

cond : expr RELOP expr ;

expr : ID | NUMBER ;

%%

int main()
{
printf("Enter nested if statement:\n");
yyparse();
return 0;
}

int yyerror(char *s)


{
fprintf(stderr, "Syntax Error: %s\n", s);
return 0;
}
Output:

SNPITRC/CSE/2025-26/SEM-7/3170710 P a g e | 22

You might also like