%s 是inclusive 包含非独占,没有Start Condition前缀的也会被激活.
%x 是exclusive 独占的,只有带Start Condition前缀的才会被激活.
Start conditions are declared in the defnitions (frst) section of the input using unindented lines beginning with either ‘%s’ or ‘%x’ followed by a list of names. The former declares inclusive start conditions, the latter exclusive start conditions. A start condition is activated using the BEGIN action. Until the next BEGIN action is executed, rules with the given start condition will be active and rules with other start conditions will be inactive.
If the start condition is inclusive, then rules with no start conditions at all will also be active.
If it is exclusive, then only rules qualifed with the start condition will be active.
A set of rules contingent on the same exclusive start condition describe a scanner which is
independent of any of the other rules in the flex input. Because of this, exclusive start
conditions make it easy to specify “mini-scanners” which scan portions of the input that
are syntactically different from the rest (e.g., comments).
If the distinction between inclusive and exclusive start conditions is still a little vague,
here’s a simple example illustrating the connection between the two. The set of rules:
它们两个的区别仍然不是很清楚,但可以用例子来阐述下.
2.1 %s ,Sample fo inclusive,非独占的模式
/*Sample for inclusive, %s*/
%{
%}
/* %s 声明的是一系列非独占开始条件 */
%s example
%%
START BEGIN(example);
<example>foo printf("example foo!!!");
bar printf("example else!!!");
. {} /*其他字符忽略*/
%%
int main(int argc,char **argv){
printf("PARSER START!!!\n");
yylex();
printf("PARSER END!!!\n");
}
> 输出:
* START //输入START开始 example这个条件被激活
* foo //输入 foo
* example foo!!! //<example>foo激活,输出example foo!!!
* bar //输入bar
* example else!!!//虽然现在处于example状态,但是并非独占,其他规则也会生效,输出example else!!!
* example foo// 处于example条件,输入匹配语句
* example foo!!!///同输入foo
* examplebar //同输入bar
* example else!!!
2.2 %x独占的例子
/*Sample for exclusive, %s*/
%{
%}
/* %s 声明的是一系列非独占开始条件 */
%x example
%%
START BEGIN(example);
<example>foo printf("example foo!!!");
bar printf("example else!!!");
. {}
%%
int main(int argc,char **argv){
printf("PARSER START!!!\n");
yylex();
printf("PARSER END!!!\n");
}
编译执行,观察输入输出
START //输入START开始激活example条件
examplefoo //输入examplefoo
exampleexample foo!!! //输出example foo!!!
foo //输入foo
example foo!!! //输出example foo!!!
bar //输入bar
bar //没有输出example else,原样echo输出
exampleboo //同bar
exampleboo
example bar //同bar
example bar
现在有一个问题,为什么inclusive和exclusive同样输入examplefoo的输出不一样.
inclusive:输入examplefoo输出foo输出example foo!!!,而exlusive 输入examplefoo输出exampleexample foo,原因在于inclusive是非独占的,最后一个规则.依然处于激活状态,输出为空,当前处于example状态,examplefoo的example被吞掉后,<example>foo被激活,输出example foo!!!,而%x独占模式时,规则bar和 .无法被激活,也就是无法使用,只有带<example>前缀的规则会被激活,但是这些规则没有<example>example规则,所以echo原样输出example,同时foo又匹配到<example>foo也就能输出example foo!!!.所以两者的不同就在于:
%s 如果当前condition是处于<sc>的,其他规则也能激活
%x 如果当前condition是处于<sc>的,其他规则不能被激活
要想使得独占模式能够和非独占一样,后两条规则可以如下写
/*Sample for exclusive, %s*/
%{
%}
/* %s 声明的是一系列非独占开始条件 */
%x example
%%
START BEGIN(example);
<example>foo printf("example foo!!!");
<INITIAL,example>bar printf("example else!!!");
<INITIAL,example>. {}
%%
int main(int argc,char **argv){
printf("PARSER START!!!\n");
yylex();
printf("PARSER END!!!\n");
}
再次看下输出
START
foo
example foo!!!
example foo
example foo!!!
examplefoo
example foo!!!
bar
example else!!!
examplebar
example else!!!
可以看到和非独占模式inclusive.l的输出一致
网友评论