20DCS020 DLP
20DCS020 DLP
PRACTICAL 1
AIM:
Write a Lex program to count the number of characters, words and lines in the given input.
Supplementary Experiment:
1. Implement a lexical analyzer for a subset of Java using LEX. Implementation should
support Error handling. [L: M]
IMPLEMENTATION:
lex <filename with .l extension>
In this case, create an extra text file named input.txt which will contain some sample text to work
as input for lexical analysis.
CODE:
%{
int charCount = 0;
int wordCount = 0;
int lineCount = 0;
int inWord = 0;
int inSingleLineComment = 0;
int inMultiLineComment = 0;
%}
%x COMMENT
%%
"//" { inSingleLineComment = 1; BEGIN(COMMENT); }
"/*" { inMultiLineComment = 1; BEGIN(COMMENT); }
<COMMENT>"*/" { inMultiLineComment = 0; BEGIN(INITIAL); }
<COMMENT>. { /* Inside a multi-line comment, ignore */ }
%%
Input.txt
This is a sample text.
It has multiple lines.
// This is a single-line comment.
/* This is
a multi-line
comment. */
Counting words and characters.
OUTPUT:
CONCLUSION:
In conclusion, the provided Lex program effectively counts the number of characters, words, and
lines in a given input text, while also handling single-line and multi-line comments gracefully. It
demonstrates the use of Lex states to transition between regular parsing and comment handling
states, ensuring that comments do not interfere with the counting process.
AIM:
Implement a lexical analyzer for identification of numbers.
IMPLEMENTATION:
lex <filename with .l extension>
gcc <newly created .c file> -o <file name for exe file>
<filename of exe file>
CODE:
bin (0|1)+
char [A-Za-z]+
digit [0-9]
oct [0-7]
dec [0-9]*
float {digit}+("."{digit}+)
exp {digit}+("."{digit}+)?("E"("+"|"-")?{digit}+)?
hex [0-9a-fA-F]+
%%
{bin} {printf("\n %s= it is a binary number",yytext);}
{char} {printf("\n %s=it is a char",yytext);}
{oct} {printf("\n %s=it is a octal number",yytext);}
{digit} {printf("\n %s=it is a digit",yytext);}
{dec} {printf("\n %s=it is a decimal",yytext);}
{float} {printf("\n %s=it is a float",yytext);}
{exp} {printf("\n %s=it is a exp",yytext);}
{hex} {printf("\n %s=it is a hex",yytext);}
%%
int yywrap()
{
return 1;
}
int main()
{
printf("Enter the number=");
yylex();
return 0;
}
OUTPUT:
CONCLUSION:
In this practical, we learnt about lexical analysis for numbers and characters.
IMPLEMENTATION:
lex <filename with .l extension>
yacc <filename with .y extension>
gcc <newly created .c file from yacc> -o <file name for exe file>
<filename of exe file>
CODE:
Lex File:
DIGIT [0-9]
%option noyywrap
%%
{DIGIT} { yylval=atof(yytext); return NUM;}
\n|. {return yytext[0];}
Yacc File:
%{
#include<ctype.h>
#include<stdio.h>
#define YYSTYPE double
%}
%token NUM
%left '+' '-'
%left '*' '/'
%%
S : S E '\n' { printf("Answer: %g \nEnter:\n", $2); }
| S '\n'
|
| error '\n' { yyerror("Error: Enter once more�\n" );yyerrok; }
;
E : E '+' E { $$ = $1 + $3; }
| E'-'E { $$=$1-$3;}
| E'*'E {$$=$1*$3;}
| E'/'E {$$=$1/$3;}
| NUM
;
%%
#include "lex.yy.c"
int main()
{
printf("Enter the expression: ");
yyparse();
}
yyerror (char * s)
{
printf ("% s \n", s);
exit (1);
}
OUTPUT:
CONCLUSION:
In this practical, we learnt implemented a calculator using lex and yacc which takes expression as
input and perform basic arithmetic operations.
IMPLEMENTATION:
· python <filename with .py extension>
CODE:
import re
return tokens
OUTPUT:
CONCLUSION:
This practical experiment demonstrates the versatility of finite automata in language tokenization
and highlights the importance of adapting the automaton's rules and keywords to specific
programming languages for accurate recognition.
IMPLEMENTATION:
yacc <filename with .y extension>
gcc <newly created .c file> -o <file name for exe file>
<filename of exe file>
CODE:
%{
/*** Auxiliary declarations section ***/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
%%
yylex(){
char c;
c = getchar();
p=c;
if(isdigit(c)){
pos++;
return NUM;
}
else if(c == ' '){
yylex(); /*This is to ignore whitespaces in the input*/
}
else {
return c;
}
}
main()
{
yyparse();
return 1;
}
OUTPUT:
DEPSTAR-CSE Page No. 10
CS450-Design of Language Processor 20DCS109
CONCLUSION:
In this practical, we learnt about yacc and performed infix to postfix conversion.
IMPLEMENTATION:
· gcc <newly created .c file> -o <file name for exe file>
· <filename of exe file>
CODE:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_PROD 10
#define MAX_LENGTH 10
struct Production {
char nonTerminal;
char body[MAX_LENGTH];
};
struct Set {
char values[MAX_LENGTH];
};
void calculateFollow(struct Production productions[], int n, struct Set firstSets[], struct Set
followSets[]) {
addToSet(&followSets[0], '$'); // Start symbol
int changed = 1;
while (changed) {
changed = 0;
for (int i = 0; i < n; i++) {
struct Production production = productions[i];
char nonTerminal = production.nonTerminal;
int main() {
struct Production productions[MAX_PROD];
int n;
// Example grammar
n = 3;
productions[0].nonTerminal = 'S';
strcpy(productions[0].body, "AB");
productions[1].nonTerminal = 'A';
strcpy(productions[1].body, "aA|e");
productions[2].nonTerminal = 'B';
strcpy(productions[2].body, "bB|e");
calculateFirst(productions, n, firstSets);
calculateFollow(productions, n, firstSets, followSets);
printf("FIRST Sets:\n");
for (int i = 0; i < n; i++) {
printf("FIRST(%c): %s\n", productions[i].nonTerminal, firstSets[i].values);
}
printf("\nFOLLOW Sets:\n");
for (int i = 0; i < n; i++) {
printf("FOLLOW(%c): %s\n", productions[i].nonTerminal, followSets[i].values);
}
return 0;
}
CONCLUSION:
In conclusion, the provided C program successfully calculates the FIRST and FOLLOW sets for
a given context-free grammar. It demonstrates the core concepts of parsing and analyzing
grammars using these sets to determine the possible first symbols and the symbols that can
follow non-terminals.
IMPLEMENTATION:
· gcc <newly created .c file> -o <file name for exe file>
· <filename of exe file>
CODE:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_PROD 10
#define MAX_LENGTH 10
struct Production {
char nonTerminal;
char body[MAX_LENGTH];
};
if (production.nonTerminal == nonTerminal) {
// Create productions without left recursion
char temp[MAX_LENGTH];
strcpy(temp, production.body);
char* token = strtok(temp, "|");
while (token != NULL) {
struct Production newProduction;
newProduction.nonTerminal = newNonTerminal;
strcpy(newProduction.body, token);
productions[count++] = newProduction;
token = strtok(NULL, "|");
}
} else {
// Append newNonTerminal to productions
strcat(production.body, newNonTerminal);
productions[i] = production;
}
}
int main() {
struct Production productions[MAX_PROD];
int n;
printf("Original Grammar:\n");
for (int i = 0; i < n; i++) {
printf("%c -> %s\n", productions[i].nonTerminal, productions[i].body);
}
return 0;
}
CONCLUSION:
The program successfully removes left recursion from the given grammar and produces the
modified grammar as output. Left recursion removal is a crucial step in grammar transformation
for various parsing algorithms. This example demonstrates a simple approach to address left
recursion in a context-free grammar.
IMPLEMENTATION:
gcc <our .c file> -o <file name for exe file>
<filename of exe file>
In this case, create a syntax.txt file as input for the executable which will contain following
statements.
S aBaA
S AB
A Bc
Bc
CODE:
//CFG
#include<stdio.h>
#include<string.h>
#include<conio.h>
int i,j,k,l,m,n=0,o,p,nv,z=0,t,x=0;
char str[10],temp[20],temp2[20],temp3[20];
struct prod
{
char lhs[10],rhs[10][10];
int n;
}pro[10];
void findter()
{
for(k=0;k<n;k++)
{
if(temp[i]==pro[k].lhs[0])
{
for(t=0;t<pro[k].n;t++)
{
for(l=0;l<20;l++)
temp2[l]='\0';
for(l=i+1;l<strlen(temp);l++)
temp2[l-i-1]=temp[l];
for(l=i;l<20;l++)
temp[l]='\0';
for(l=0;l<strlen(pro[k].rhs[t]);l++)
temp[i+l]=pro[k].rhs[t][l];
strcat(temp,temp2);
if(str[i]==temp[i])
DEPSTAR-CSE Page No. 19
CS450-Design of Language Processor 20DCS109
return;
else if(str[i]!=temp[i] && temp[i]>=65 && temp[i]<=90)
break;
}
break;
}
}
if(temp[i]>=65 && temp[i]<=90)
findter();
}
int main()
{
FILE *f;
// clrscr();
for(i=0;i<10;i++)
pro[i].n=0;
f=fopen("input.txt","r");
while(!feof(f))
{
fscanf(f,"%s",pro[n].lhs);
if(n>0)
{
if( strcmp(pro[n].lhs,pro[n-1].lhs) == 0 )
{
pro[n].lhs[0]='\0';
fscanf(f,"%s",pro[n-1].rhs[pro[n-1].n]);
pro[n-1].n++;
continue;
}
}
fscanf(f,"%s",pro[n].rhs[pro[n].n]);
pro[n].n++;
n++;
}
n--;
while(1)
{
for(l=0;l<10;l++)
str[0]=NULL;
OUTPUT:
DEPSTAR-CSE Page No. 21
CS450-Design of Language Processor 20DCS109
CONCLUSION:
In this practical, we learnt about Context Free Grammar and implemented the concept using C.
IMPLEMENTATION:
gcc <our .c file> -o <file name for exe file>
<filename of exe file>
Content of Input1.txt:
a=b+c;
d=n+s;
p=q;
CODE:
// Pgm for Code generation by using simple code generation algorithm
#include<stdio.h>
#include<string.h>
struct table{
char op1[2];
char op2[2];
char opr[2];
char res[2];
}tbl[100];
OUTPUT:
DEPSTAR-CSE Page No. 25
CS450-Design of Language Processor 20DCS109
CONCLUSION:
In this practical, we learnt about code generation and implemented the same using C.
IMPLEMENTATION:
gcc <our .c file> -o <file name for exe file>
<filename of exe file>
CODE:
#include <stdio.h>
#include <conio.h>
#include <string.h>
struct op
{
char l;
char r[20];
}op[10], pr[10];
void main()
{
int a, i, k, j, n, z = 0, m, q;
char *p, *l;
char temp, t;
char *tem;
//clrscr();
printf("enter no of values=");
scanf("%d", &n);
//n=5;
for (i = 0; i < n; i++)
{
printf("\t left: \t");
OUTPUT:
CONCLUSION:
In this practical, we learnt about code optimization and implemented the same using C.