Reputation: 4197
I am trying to write a program in ml-lex which will detect integers and reals. My program is something like this:
datatype lexresult = INTEGER of string | REAL of string | EOF
val linenum = ref 1;
val error = fn x => output(stdOut,x^"\n");
val eof = fn () => EOF;
fun inc(j) = j := !(j) + 1;
%%
%structure Something
num=[1-9];
zero=[0];
%%
\n => (inc linenum; lex());
^({num}+)({num}* | {zero}*)* => (INTEGER yytext);
^({num}+)({num}* | {zero}*)*(".")({zero} | ({zero}* | {num}+)) => (REAL yytext);
. => (error ("ignoring bad character "^yytext); lex());
But the problem is that it detects only integers and reals starting in new line. I tried to give (^ | " "+)
in start in place of ^
but then ml-lex gives error ml-lex: syntax error, line 15:
unhandled exception: Error
. What changes can I make to detect integers and reals in between the sentence like "I have 5 books." and the program should ignore all characters and should detect integer 5 only.
I also have one more problem. I think I have defined regular expression for real number something like that it should say that some thing is real only if number has only one zero after .
(dot) or some sequence of number from 0-9 but doesn't end in zero. But my program also detecting 5.00 and 5.600 as real number.
Upvotes: 1
Views: 674
Reputation: 18667
I don't know mllex, but I've played a little with GNU Flex and ocamllex. What I would do is add a rule like this:
" " => (lex());
That way, whitespace is silently skipped. If you want to skip all letters, you can remove the call to error
in your rule for .
.
I see no problem with your program detecting 5.600 as a real number as it has a decimal component. To force 5.000 to be lexed as an integer, you can do additional tests in the RHS of your rule that currently returns REAL
.
Upvotes: 2