Strange flexible behavior
I have a bone note scanner with the following scanner
%option debug
%option noyywrap
%option yylineno
%{
#include <limits.h>
#include "parser.h"
%}
%%
[0-9]+ {
errno = 0;
#ifdef DEBUG
printf("Scanner: NUMBER %s (%i)\n", yytext, yyleng);
#endif
long number = strtol( yytext, NULL, 10);
if ( errno != 0 && errno != ERANGE && number == 0 ) {
printf("Error: incorrect number %s\n", yytext);
exit(EXIT_FAILURE);
}
// we only accept integers
if ( number > INT_MAX ) {
printf("Error: %s is too large\n", yytext );
exit(EXIT_FAILURE);
}
yylval.int_type = (int)number;
return NUMBER;
}
\+ { return PLUS; }
\- { return MINUS; }
["*"x] { return TIMES; }
\/ { return DIV; }
d|D {
#ifdef DEBUG
printf("Scanner: DICE\n");
#endif
return DICE;
}
f|F { return FUDGE; }
h|H { return HIGH; }
l|L { return LOW; }
"(" { return LPAREN; }
")" { return RPAREN; }
"{" {
#ifdef DEBUG
printf("Scanner: LCURLY\n");
#endif
return LCURLY;
}
"}" {
#ifdef DEBUG
printf("Scanner: RCURLY\n");
#endif
return RCURLY;
}
">" { return GT; }
">=" { return GE; }
"<" { return LT; }
"<=" { return LE; }
"!=" { return NE; }
"<>" { return NE; }
"%" { return PERCENT; }
, {
#ifdef DEBUG
printf("Scanner: COMMA\n");
#endif
return COMMA;
}
[[:blank:]] {
/* ignore spaces */
#ifdef DEBUG
printf("Scanner: BLANK\n");
#endif
}
. { printf("Error: unknown symbol '%s'\n", yytext); exit(EXIT_FAILURE); }
%%
When I parse something like 4{3d6, 1d5}
everything works fine. But when the 4{3d6,1d5}
scanner has strange behavior and misses the first curly brace.
Debug output
--accepting rule at line 20 ("43")
Scanner: NUMBER 43 (2)
--accepting rule at line 47 ("d")
Scanner: DICE
--accepting rule at line 20 ("641")
Scanner: NUMBER 641 (3)
--accepting rule at line 47 ("d")
Scanner: DICE
The scanner matches 4{3
as 43
although {
not included in the [0-9]+
.
Since the other behavior is triggered empty much later in the expression, I suspect I missed something in handling the space, but I don't understand why it should mess up the integer match at the beginning of the expression.
Any hints?
source to share
If the Unix shell accesses your login, it 4{3d6,1d5}
will be expanded to 43d6 41d5
. Your lexer ignores whitespace entirely, so then it becomes 43d641d5
, which (modulo some truncation on your part?) Is what you are communicating.
I have duplicated your code and when I run something like:
echo 4{3d6,1d5} | ./lex
I am getting your problem. If I run:
echo '4{3d6,1d5}' | ./lex
then it's all right. It's also fine if I type 4{3d6,1d5}
in a file and then run lexer on the file.
source to share