获取输入字符串中的当前索引(flex 词法分析器)

Getting the current index in the input string (flex lexer)

我正在使用 flex 词法分析器。有没有办法(1)获取输入字符串中的当前索引(2)在未来的时间点跳回到该索引?

谢谢。

保持当前输入位置相当容易。匹配任何一条规则时,yyleng包含匹配的长度,所以处理的累计长度加上yyleng就可以了。假设您使用的是 flex,则不必将代码直接插入到每个规则操作中,那样会很乏味。相反,您可以使用 YY_USER_ACTION 宏:

#define YY_USER_ACTION input_pos += yyleng;

(假设你已经在某处定义了 input_pos,并安排在词法扫描开始时将其初始化为 0。)

如果您使用 REJECTyymore()yyless()input(),这将导致不正确的结果;在所有这些情况下,您都必须调整 input_pos 的值。对于 yymore() 的每次调用,您需要从 input_pos 中减去 yyleng;这也适用于 REJECT。对于 yyless() 的调用,您可以在调用前减去 yyleng 并在调用后将其加回去。对于 input() 的每个调用,您需要将一个添加到 input_pos.

在规则中,您可以使用 input_pos 作为匹配 结束 的位置,或 input_pos - yyleng 作为开始的位置比赛的。

返回到保存的位置比较棘手。

(F)lex 不会将整个输入保存在内存中,因此原则上您需要使用 fseek()yyin 倒回到正确的位置。但是,在未以二进制模式打开 yyin 的常见情况下,您不能可靠地使用 fseek() 到 return 计算输入偏移量。因此,至少,您必须确保 yyin 以二进制模式打开(或重新打开)。

此外,通常不可能保证 yyin 所附加的任何流都可以完全倒回(它可能是控制台输入、管道或其他一些不可搜索的设备)。因此,要完全通用,您可能必须使用临时文件来存储从流中读取的数据。当您尝试重新读取以前的输入时,这会产生额外的复杂性,因为您必须切换到临时文件进行读取,直到它完成,此时您将不得不 return 到主文件。创造性地使用 yywrap 将简化此过程。

请注意,在倒回输入流之后——无论是否切换到从临时文件读取——您都必须调用 yyrestart() 来重置扫描仪的输入缓冲区。 (这也是 flex 独有的功能;Posix lex 没有指定通知扫描器其缓冲区需要重置的机制,因此如果您不使用 flex,则必须查阅相关文档用于您的扫描仪生成器。)