获取输入字符串中的当前索引(flex lexer)

时间:2017-11-03 11:26:30

标签: flex-lexer lex

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

感谢。

1 个答案:

答案 0 :(得分:2)

维持当前输入位置相当容易。匹配任何规则时,yyleng包含匹配的长度,因此将yyleng添加到已处理的累积长度就足够了。假设您正在使用flex,则不必将代码直接插入到每个规则操作中,这将是乏味的。相反,您可以使用YY_USER_ACTION宏:

#define YY_USER_ACTION input_pos += yyleng;

(这假设您已在某处定义了input_pos,并安排在词汇扫描开始时将其初始化为0.)

如果您使用REJECTyymore()yyless()input(),这将导致错误的结果;在所有这些情况下,您必须调整input_pos的值。对于yymore()的每次通话,您需要从yyleng中减去input_pos;这也适用于REJECT。对于yyless()的来电,您可以在通话前减去yyleng,并在通话后将其重新添加。对于input()的每次通话,您需要向input_pos添加一个。

在规则中,您可以使用input_pos作为匹配 end 的位置,或input_pos - yyleng作为匹配开头的位置。< / p>

返回保存位置比较棘手。

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

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

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