【问题标题】:Character Position from starting of a line从行首开始的字符位置
【发布时间】:2015-10-08 18:34:13
【问题描述】:

在flex中,从行首获取字符位置的方法是什么? 我有一篇关于文件开头位置的帖子,但我希望它从行首开始。

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

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

输出:

“int”的位置=3

请给我一些提示来实现它。

【问题讨论】:

    标签: flex-lexer lex


    【解决方案1】:

    我认为“关于文件开头位置的帖子”是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;                            \
      }
    

    上面的代码假设当前token的起始行/列是前一个token的结束行/列,这意味着yylloc需要正确初始化。通常你不需要担心这个,因为bison会自动声明和初始化yylloc(到{1,1,1,1}),只要它知道你在使用位置信息。

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


    请注意,如果您使用yylessyymore,或者如果您调用input,代码将无法正常工作。

    使用yymoreyylloc会报告最后一个token段的范围,而不是整个token;要解决这个问题,您需要保存真正的令牌开头。

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

    在调用input 后,您需要为读取的每个字符手动更新yylloc.last_column。不要调整yylineno; flex 将正确处理。但如果 yylineno 发生变化,您确实需要更新 yylloc.last_line

    【讨论】:

      猜你喜欢
      • 2020-11-10
      • 2011-10-19
      • 2013-07-15
      • 1970-01-01
      • 2011-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-07
      相关资源
      最近更新 更多