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?

+3


source to share


1 answer


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.

+3


source







All Articles