从行

时间:2015-10-08 18:34:14

标签: flex-lexer lex

在flex中,从一行开始获取角色位置的方法是什么? 我从一个文件的开头有一个关于位置的帖子,但我想从一行开始。

它也应该处理这样的情况:

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

输出:

  

这里“int”的位置= 3

请给我一些提示来实现这一点。

1 个答案:

答案 0 :(得分:0)

我认为“关于文件开头的位置的帖子”是this one,或类似的东西。以下是基于该答案。

要跟踪当前列偏移量,只需添加代码即可在遇到换行符时重置offset值。如果您按照链接答案中显示的模型进行操作,则可以使用此类YY_USER_ACTION宏进行调整:

#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;                            \
  }

上面的代码假定当前令牌的起始行/列是前一个令牌的结束行/列,这意味着需要正确初始化yylloc。通常您不必担心这一点,因为只要知道您正在使用位置信息,Bison就会自动声明并初始化yylloc{1,1,1,1})。

宏的第三行中的测试优化了令牌中没有换行符的常见情况,在这种情况下,yylineno自令牌开始以来不会发生变化。在else子句中,我们知道在令牌中会找到换行符,这意味着我们不必检查缓冲区下溢。 (如果您致电input()或以其他方式操纵yylineno,那么您需要修复for循环。)

请注意,如果您使用yylessyymore,或者致电input,则代码将无法正常运作。

使用yymoreyylloc将报告最后一个令牌段的范围,而不是整个令牌;为了解决这个问题,你需要保存真正的令牌开始。

要使用yyless正确跟踪令牌范围,您可能需要在调用yyless后重新扫描令牌(尽管如果令牌中没有换行符可以避免重新扫描)

调用input后,您需要为每个字符读取手动更新yylloc.last_column。不要调整yylineno; flex将正确处理。但如果yylloc.last_line已更改,则需要更新yylineno