0

In flex, what's the way to get character position from the starting of a line? I've got a post regarding position from start of a file but i want it from the start of a line.

Also it should handle case like this:

/** this is 
a comment
*/int x,y;

output:

Here position of "int"=3

Please give me some hints to implement this.

Paul Roub
  • 36,322
  • 27
  • 84
  • 93

1 Answers1

0

I presume that the "post regarding position from start of a file" is this one, or something similar. The following is based on that answer.

To track the current column offset, you only need to add the code to reset the offset value when you hit a newline character. If you follow the model presented in the linked answer, you can use a YY_USER_ACTION macro like this to do the adjustment:

#define YY_USER_ACTION                                       \
  yylloc.first_line = yylloc.last_line;                      \
  yylloc.first_column = yylloc.last_column;                  \
  if (yylloc.first_line == yylineno)                         \
     yylloc.last_column += yyleng;                           \
  else {                                                     \
     int col;                                                \
     for (col = 1; yytext[yyleng - col] != '\n'; ++col) {}   \
     yylloc.last_column = col;                               \
     yylloc.last_line = yylineno;                            \
  }

The above code assumes that the starting line/column of the current token is the end line/column of the previous token, which means that yylloc needs to be correctly initialized. Normally you don't need to worry about this, because bison will automatically declare and initialize yylloc (to {1,1,1,1}), as long as it knows that you are using location information.

The test in the third line of the macro optimizes the common case where there was no newline in the token, in which case yylineno will not have changed since the beginning of the token. In the else clause, we know that a newline will be found in the token, which means we don't have to check for buffer underflow. (If you call input() or otherwise manipulate yylineno yourself, then you'll need to fix the for loop.)


Note that the code will not work properly if you use yyless or yymore, or if you call input.

With yymore, yylloc will report the range of the last token segment, rather than the entire token; to fix that, you'll need to save the real token beginning.

To correctly track the token range with yyless, you'll probably need to rescan the token after the call to yyless (although the rescan can be avoided if there is no newline in the token).

And after calling input, you'll need to manually update yylloc.last_column for each character read. Don't adjust yylineno; flex will deal with that correctly. But you do need to update yylloc.last_line if yylineno has changed.

Community
  • 1
  • 1
rici
  • 234,347
  • 28
  • 237
  • 341