9

I'm writing a simple parser for tcpdump logs, could you please tell me why I can't get proper line number?

%{
char str[80];
%}
%option yylineno

...
%%

^{HOURS}:{MINUTES}:{MINUTES} if(input()=='.') { strcpy(str, yytext);  BEGIN(A); } else {printf("Wrong hour %d", yylineno); }
<A>({NDPS}|{DPS})\.({NDPS}|{DPS})\.({NDPS}|{DPS})|\.{NDPS} printf("Wrong IP!, %d", yylineno);
<A>[ ]{DPS}\.{DPS}\.{DPS}\.{DPS} strcat(str, " from "); strcat(str, yytext+1); BEGIN(B);
...
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Wojciech Reszelewski
  • 2,656
  • 2
  • 18
  • 27

1 Answers1

19

When I tried this, it turned out that I had to have a rule that actually matches newline for yylineno to be updated. With the following rule it worked, and without it yylineno never changed:

\n { }
Thomas Padron-McCarthy
  • 27,232
  • 8
  • 51
  • 75
  • 2
    Thanks for saving a lot of time. It's very hard to find useful tips for the usage of flex. – Quxflux Apr 21 '13 at 16:24
  • 3
    Note that if you are not using `flex` (but are using `lex` or some other variant of it), this may not be sufficient. See [Lex: `yylineno` returning 1](http://stackoverflow.com/questions/31524630/lex-yylineno-returning-1) for some information (or, short form, replace `\n { }` with `\n { yylineno++; }`). If you are using `flex`, this is probably not a good idea — it probably double-increments the line number, which is probably counter-productive. – Jonathan Leffler Jul 20 '15 at 20:11
  • If we're anyway adding the rule to increment line number, why not create our own lineno variable independent of flex's internals? put `int my_yylineno=1` in declaration region, and `\n {my_yylineno++;}` in rules – Udayraj Deshmukh Feb 26 '18 at 19:35
  • EXCELLENT! IT WORKS – Sumukha Pk Jan 14 '19 at 13:21