第十章文件结束规则
特殊规则<
1、给yyin赋值新的输入文件(在以前版本的flex中,在完成赋值后,必须调用特殊操作YY_NEW_FILE。这已经没有必要了。)
2、执行一个return语句
3、执行一个特殊的yyterminate()动作
4、或者,使用yy_switch_to_buffer()切换到新的缓冲区,如上面示例一样
<
这些规则对于捕获未关闭注释之类的东西很有用。例如:
%x quote
%%
...other rules for dealing with quotes...<quote><<EOF>> {error( "unterminated quote" );yyterminate();}
<
if ( *++filelist )
yyin = fopen( *filelist, "r" );
else
yyterminate();
}
第十一章其它的宏
可以定义宏YY_USER_ACTION来提供一个总是在匹配规则的操作之前执行的操作。例如,可以使用#define来调用一个程序将yytext转换为小写。当调用YY_USER_ACTION时,变量yy_act给出匹配规则的编号(规则从1开始编号)。假设您想要分析每条规则匹配的频率。下面的方法可以达到这个效果:
#define YY_USER_ACTION ++ctr[yy_act]
这里的ctr是一个持有不同规则数量计数的数组。请注意,宏YY_NUM_RULES给出了规则的总数(包括默认规则),即使你使用’-s’,所以正确的ctr的声明是:
int ctr[YY_NUM_RULES];
可以定义宏YY_USER_INIT来提供一个操作,该操纵总是在第一次扫描之前执行(并且在扫描器的内部初始化完成之前)。例如,它可以用来调用一个程序来读取数据表或打开日志文件。
宏yy_set_interactive(is_interactive)可以被用来控制当前缓冲区是否被考虑为interactive。交互式缓冲区的处理速度较慢,但是当扫描器的输入源由于等待填充缓冲区必须是交互式以避免问题时这个必须被使用(查看在扫描器选项章节中对于’-I’标志的讨论)。宏调用参数的非零值将缓冲区标记为交互式,零值表示非交互式。请注意,使用此宏将覆盖%option always-interactive或%option never-interactive(查看扫描器选项章节)。在开始扫描被认为是(或不是)交互式的缓冲区前,必须调用yy_set_interactive()。
宏yy_set_bol(at_bol)可以被用于控制当前缓冲区的下一个标记匹配的扫描上下文是否像在一行的开头一样完成。非0的宏参数使用’’锚定的规则处于活动状态,而0参数使’’规则处于非活动状态。
如果从当前缓冲器扫描的下一个标记有’^’规则激活则宏YY_AT_BOL()返回真,其它的返回假。
在生成的扫描器中,所有动作都聚集在一个大的switch语句中,并使用YY_BREAK分割,这个YY_BREAK是可以重新定义的。默认情况下,它只是一个break,为了将每个规则的操作与下一个规则的操作分开。允许重定义YY_BREAK,例如,C++用户 #define YY_BREAK什么也不做(同时要非常小心,每个规则都可以以break或return结束)避免出现不可达语句告警,因为规则的动作以return结束,所以YY_BREAK不可达。