问题
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.
回答1:
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.
来源:https://stackoverflow.com/questions/33023442/character-position-from-starting-of-a-line