Showing posts with label LEX Programs. Show all posts
Showing posts with label LEX Programs. Show all posts

Monday, November 21

Lex program ~ Read and copy file content


This lex program will read an input file and copy the content with line number to another file.






%{
#include<stdio.h>
#include<string.h>
char line[20];
int count=0,i=0;
FILE *out;
%}
%%
['\n'] { fprintf(out,"%d %s\n",++count,line);}
(.*) {
strcpy(line,yytext);
}
%%
main()
{
yyin=fopen("in.c","r");
out=fopen("out.c","w");
yylex();
getch();
}

int yywrap()
{
return 1;
}








input
main()
{
int i=9, j=900,k=115;
printf("%d,i+j+k);
}


output file


1 main()
2 {
3 int i=9, j=900,k=115;
4 printf("%d,i+j+k);
5 }
6 }

Lex- Collect Tokens and sort

Hello friend,
  Here I am with an interesting Lex program which sorts all the nubers from input file and sort them. If you are well-familiarised with lex paradigm, it is very easy task.

Things to remember:
  • The definition [0-9]+ can detect all the numbers from input
  • The number detected at present will be pointed by yytext and have length yyleng
  • Whenever a new token (here a number) is detected, yytext will be replaced with new value. 
Logic
  1. Read the input
  2. If a number is detected, store it in an array (we can use yytext and yyleng for this). Read each digit --> multiply with 10 --> add next digit -->continue upto last digit.
  for eg, to read 123
initialise num=0;
  • read 1--> num=num*10+1-->num=0+1-->num=1
  • read 2--> num=num*10+2-->num=10+2-->num=12
  • read 3--> num=num*10+3-->num=120+3-->num=123
store num in an array.
3. After reading all the numbers, sort the number within the array




%{
#include<stdio.h>
int t, a[20],i,j,n,num;
%}
%%
[0-9]+ {num=0;
 for(i=0;i<yyleng;i++)
num=num*10+(yytext[i]-'0');

a[n++]=num;
}
. ;
%%
main()
{
yyin=fopen("file.c","r");
yylex();
for(i=0;i<n;i++)
for(j=0;j<n-i-1;j++)
if(a[j]>a[j+1])
{
t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
for(i=0;i<n;i++)
printf("%d\n",a[i]);

}

int yywrap()
{
return 1;
}





sample input (in file.c)
main()
{
int i=9, j=900,k=115;
printf("%d,i+j+k);
}




output
9
115
900

Friday, November 18

Lex and Yacc in Windows 7 - Compile and Run


Hi Friend,
I was in search for a long time to get a platform in windows-7 to run lex and Yacc ,for academic purposes. Many of my friends also had the same problem and often forced to choose Linux only for merely executing Lex & Yacc programs..!!!

At last, I found one solution and its my pleasure to share it with all of you.!!  :)

Its very simple.You need to download two very small files.
You have to download two executable( i.e.,   .exe files). In total,its size may have about 370KB.

To download them click the links below.

Link 1:   Flex

Link 2:  Bison

Save both files in same place. ( I did in D: --> Flex)
Keep the lex program to be compiled also in same place.


Now open command prompt--> reach your directory through command prompt.

To compile, type command 
                flex <filename> (eg:- flex myflex.l)

If your program is error-free, lex.yy.c will be generated.


We can compile this C file with any C compiler available (eg: Turbo C)

and generate yy.lex.exe

Now just run yy.lex.exe. Its your lexical analyser..!!!




I hope this post was useful for you.!!
Please comment your feedback here.!!
Thank You.!!  :)








Tuesday, November 15

LEX program to check a Date (dd/mm/yyyy)


Hello dude..   

            I would like to discuss a problem asked by my teacher in our internal lab exam- LEX program to check the validity of a Date. Ahem..In normal programming (i.e, that with C or Java) this is not a big deal!! But in Lex paradigm,it require some more effort..!!

                                                
                                                   

*Check the syntax of Date::


* If we have to check the syntax only ,i.e., dd/mm/yyyy apply the simple logic

[0-9][0-9] \ / [0-9][0-9] \ / [0-9] [0-9] [0-9] [0-9]


* But date should be within range [01-31] ,month be within [01-12] and assume year be within the range [1000-2999]. To apply these constraints, we redefine rules as:

"01-31"----> ([0-2][0-9] | 3 [0-1])
"01-12"----> (0[1-9] | 1[0-2])
"1000-2999"---->  ([1-2][0-9][0-9][0-9])


* Thus we can simply check the syntax of given Date as:

([0-2][0-9] | 3 [0-1])  \ /  (0[1-9] | 1[0-2]) \ / ([1-2][0-9][0-9][0-9])






*To Check the validity of date::

-->  In months 01,03,05,07,08,10 &12 , there will be at most 31 days.
([0-2][0-9]|[3][0-1])\/((0(1|3|5|7|8))|(10|12))\/([1-2][0-9][0-9][-0-9]) 

--> In months 04,06,09 & 11 may have at most 30 days
([0-2][0-9]|30)\/((0(4|6|9))|11)\/([1-2][0-9][0-9][0-9])

-->February has 28 days (in linear and non-linear years)
([0-1][0-9]|2[0-8])\/02\/([1-2][0-9][0-9][0-9])

-->If February has a day 29, check whether it is leap year or not..!!
29\/02\/([1-2][0-9][0-9][0-9])
 {
extract year value;
check whether it is a leap year;
}

-->Extract year value

   1.Iterate upto two "/" in date are over.(i.e.,in dd/mm/yyyy pass over two "/"s to reach at year value.
   2.read all susequent characters (they all are part of year value - yyyy)

while(yytext[i]!='/')i++;   //reach at first "/"
i++;                        // increment pointer
while(yytext[i]!='/')i++;   //reach at next "/"
i++;                        // increment pointer
while(i<yyleng)             // read all characters upto end of the string
yr=(10*yr)+(yytext[i++]-'0');// extract integer value of year

--> Check whether it is Leap year or not:

if(yr%4==0||(yr%100==0&&yr%400!=0))

Well... the complete lex program is as follows..!!



Date.l

%{
#include<stdio.h>
int i=0,yr=0,valid=0;
%}
%%

([0-2][0-9]|[3][0-1])\/((0(1|3|5|7|8))|(10|12))\/([1-2][0-9][0-9][-0-9]) {valid=1;}

([0-2][0-9]|30)\/((0(4|6|9))|11)\/([1-2][0-9][0-9][0-9]) {valid=1;}

([0-1][0-9]|2[0-8])\/02\/([1-2][0-9][0-9][0-9]) {valid=1;}

29\/02\/([1-2][0-9][0-9][0-9]) { while(yytext[i]!='/')i++; i++;while(yytext[i]!='/')i++;i++;while(i<yyleng)yr=(10*yr)+(yytext[i++]-'0'); if(yr%4==0||(yr%100==0&&yr%400!=0))valid=1;}

%%
main()
{
yyin=fopen("vpn.txt","r");
yylex();
if(valid==1) printf("It is a valid date\n");
else printf("It is not a valid date\n");
}

int yywrap()
{
return 1;
}




OUTPUT
Content in input file
(here, vpn.txt)
 Output
12/12/2011It is a valid date
32/10/2009It is not a valid date
29/02/2008It is a valid date
31/04/1990It is not a valid date
29/02/2007It is not a valid date



Hope this post was useful for you. If you have any suggestions or doubts,please do comment here...!!
Thank you




Saturday, October 8

C Program to generate Intermediate code



#include<stdio.h>
#include<ctype.h>
#include<string.h>

main()
{
char a[20];
int i=2,n;
printf("Exp  :");
scanf("%s", a);
if(isdigit(a[0]))
printf("MVI A,%c\n",a[0]);
else printf("MOV A,%c\n",a[0]);
n=strlen(a);
while(i<n)
{
switch(a[i])
{
case '+':printf("ADD B\n");i+=3;break;
case '-':printf("SUB B\n");i+=3;break;



default:if(isdigit(a[i]))
printf("MVI B,%c\n",a[i]);
else
printf("MOV B,%c\n",a[i]);
i--;
}
}
}

LEX program to check the syntax of SCANF statement

%{
#include<stdio.h>
#include<ctype.h>
int i=0,j=0;
%}
a "%d"|"%f"|"%c"|"%s"
id [a-zA-Z][a-zA-Z0-9]*
%%
scanf\((\"({a}*|.*)*\"(,\&{id})*\))\;

{for(i=0;i<yyleng;i++)
{if(yytext[i]=='%')
j++;
if(yytext[i]==',')
j--;
}

if(j==0)
printf("Correct");
else
printf("Incorrect");
}
%%
main()
{ yyin=fopen("sample.c","r");
yylex();
}
int yywrap()
{

return 1;
}        

LEX program to check the syntax of PRINTF statement



%{
#include<stdio.h>
#include<ctype.h>
int i=0,j=0;
%}
a "%d"|"%f"|"%c"|"%s"
id [a-zA-Z][a-zA-Z0-9]*
%%

printf\((\"({a}*|.*)*\"(,{id})*\))\; {for(i=0;i<yyleng;i++) {
if(yytext[i]=='%')
j++;
if(yytext[i]==',')
j--;
}

if(j==0)
printf("Correct..!!");
else
printf("Incorrect..!!");
}
%%

main()
{

yyin=fopen("sample.c","r");
yylex();
}


int yywrap()
{

return 1;
}      




Explanation:

Well, checking syntax of printf statement is very easy.
The syntax should be "printf" followed by "(" and  . It can include a usual string or %d,%f type expression delimited by another ".

The entities specified by %f typed expression should be specified before ")" separated by commas.

The number of arguments is then checked within rule part ( i.e, no. of % is equal to no. of commas).


For more interesting LEX programs , click here...!!


                            

Lex program to check the syntax of FOR loop



%{
#include<stdio.h>
#include<ctype.h>
int c=1;
%}
op "++"|"--"
rop "<"|">"|"<="|">="|"=="|"!="
id [a-zA-Z][a-zA-Z0-9]*
no [0-9]*
pp [\n]
%%
for\(({id}=({no}|{id}))?\;{id}{rop}({id}|{no})\;{id}{op}\){pp}+\{(.*\n)*.*\} {printf("correct");c=0;}
%%
main()
{ yyin=fopen("file11.c","r");
yylex();
if(c==1)
printf("incorrect");
}
int yywrap()
{
return 1;
}

Friday, September 9

LEX Program to identify Keywords and convert it into uppercase


Guys, apply simple logic. Detect all keywords( This program deal with a small number of keywods for sake of simplicity).
On detecting any keyword in C, convert it into uppercasr letter using the funtion 'toupper' . Game over!!




%{#include<stdio.h>
int i;

%}keyword main|int|scanf|printf|if|else
%%

{keyword} {
 for(i=0;i<yyleng;i++)
 printf("%c",toupper(yytext[i]));
   }

%%

main()
{
yyin=fopen("num.c","r");
yylex();
}


int yywrap()
{
return 1;
}

OutputLet num.c contains following program fragment.

main()
{
int num;
scanf("%d",&num);
if(num%2)printf("Odd");
else printf("Even")
}


The output will be,

MAIN()
{
INT num;
SCANF("%d",&num);
IF(num%2)PRINTF("Odd");
ELSE PRINTF("Even")
}





LEX Program to eliminate all whitespaces

Hi Guys,
This lex program is aimed to eliminate all whitespaces from an input file. As u think, this is not at all a difficult job. We have to simply detect single blank ' ' or tab '\t' or a newline '\n' and delete them in output. That's all..!!!!



%{
#include<stdio.h>
%}

%%
[\n\t ' '] {};
%%
main()
{
yyin=fopen("myfile.txt","r");
yylex();

}
int yywrap()
{
return 1;
}

____________________________________________________________________
Look @ the example:

Basic datatypes in C are:
int   char  float   double

output will be

BasicdatatypesinCare:intcharfloatdouble




.

LEX Program to delete all comments


No Comments  :)


This lex program is intended to eliminate comments from a C program. This task is simple since in a C program, comments will be associated only with '//' or '/*...*/ only. So our aim is to detect the occurence of these characters and ignore subsequent comments.



%{
#include<stdio.h>
%}


%%

\/\/.* ;
\/\*(.*\n)*.*\*\/ ;

%%

main()
{
yyin=fopen("mypgm.c","r");
yylex();
}


int yywrap()
{
return 1;
}





\/\/.* ; eliminates single line coments. i.e., comments of the form ' //comment.. .. .. ;'
It simply look on '/'immediately followed by another '/' and ignore that line.

\/\*(.*\n)*.*\*\/ ; eliminates multiple comments. i.e, code fragment lies within /*...*/


Have  a look on this Example:

Consider mypgm.c

//This is a single comment;
This is not a comment;
/*But..
These are mulptiple comments
*/
Again, It is not a comment


The output will be,

This is not a comment;
Again, It is not a comment

LEX Program to count the number of lines, words and letters


Howdy guys,

Lets have a look on how a Lex programs works using a simple example.

This sample programs counts the number of lines, words and characters in a text file.


 
Lex programming is not rocket science. You have to just apply an eight year old kid's logic. Yes, you read right. Only a school kid's logic.

LOGIC

Read each character from the text file :

  • Is it a capital letter in English? [A-Z] : increment capital letter count by 1.
  • Is it a small letter in English? [a-z] : increment small letter count by 1
  • Is it [0-9]? increment digit count by 1.
  • All other characters (like '!', '@','&') are counted as special characters
  • How to count the number of lines? we simply count the encounters of '\n' <newline> character.that's all!! 
  • To count the number of words we count white spaces and tab character(of course, newline characters too..)

 Alignment of a Lex program is very simple and it makes the logic more vivid.



counter.l
%{
#include<stdio.h>
int lines=0, words=0,s_letters=0,c_letters=0, num=0, spl_char=0,total=0;
%}
%%


 
\n { lines++; words++;}
[\t ' '] words++;
[A-Z] c_letters++;
[a-z] s_letters++;
[0-9] num++;
. spl_char++;
%%





main(void)
{
yyin= fopen("myfile.txt","r");
yylex();
total=s_letters+c_letters+num+spl_char;
printf(" This File contains ...");
printf("\n\t%d lines", lines);
printf("\n\t%d words",words);
printf("\n\t%d small letters", s_letters);
printf("\n\t%d capital letters",c_letters);
printf("\n\t%d digits", num);
printf("\n\t%d special characters",spl_char);
printf("\n\tIn total %d characters.\n",total);
}
 
int yywrap()
{
return(1);
}


Sample output



 Let the 'myfile.txt' contains this.

                         This is my 1st lex program!!!
                         Cheers!! It works!!:)

The output will be


This file contains..
2 lines
9 words
30 small letters
3 capital letters
1 digits
9 special characters
In total 43 characters.