Pages

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




8 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. @smart vishnu sris it? What was your input and how did the program respond? Please do specify..!!!
    (note: sample input given by me and their respective outputs are tabulated @ the end of post)

    ReplyDelete
  3. @smart vishnu srbuddy.. Note one more thing. The name of input file is 'vpn.txt' here. Dont forget to edit th program with name of your own file.

    ReplyDelete
  4. your regular expression accepts a date of 0/03/1999 also .... whereas 0 is not a valid date

    ReplyDelete
  5. what was the source code to convert long date in to short date

    ReplyDelete
  6. This comment has been removed by the author.

    ReplyDelete
  7. how to align the inputs in the input text file?

    ReplyDelete