跳至正文

编译原理lab3

内容目录

编译原理lab3

1 有如下FLEX描述文件,当输入14时,对应的输出是什么?请附上执行输出截图。

%{
   #include <stdio.h>
   int k;
%}
%%
[0-9]+ { k = atoi(yytext);
    if (k%7 == 0) printf("%d", k+3);
    else  printf("%d",k);
}
%%

输出为:

17

执行输出截图如下:

img

2 对如下FLEX描述文件的识别规则部分,下面输入串对应的输出是什么?LET Something01 = DeadBeefH + Compiler 请附上执行输出截图。

%%

"LET" {printf("Keyword ");}

[0-9A-Fa-f]+H {printf("Number ");}

[A-Za-z][A-Za-z0-9]* {printf("Identifier ");}

"=" {printf("Operator ");}

. {}

%%

输出为:

Keyword Identifier Operator Number Identifier

执行输出截图如下:

img

3 对如下FLEX描述文件的识别规则部分,下面输入串对应的输出是什么?LET Something01 = DeadBeefH + Compiler 请附上执行输出截图。和上一题相比,为什么同样的输入串会得到不同的识别结果?

%%

[0-9A-Fa-f]+H  {printf("Number ");}

[A-Za-z][A-Za-z0-9]*  {printf("Identifier ");}

"LET"  {printf("Keyword ");}

"="  {printf("Operator ");}

. {}

%%

输出为:

Identifier Identifier Operator Number Identifier

执行输出截图如下:

img

同样输入串得到不同识别结果的原因是flex程序大多具有二义性,flex采取以下规则来处理这类情况,于是有了不同识别结果:

1.词法分析器匹配输入时匹配尽可能多的字符串。

2.如果两个模式都可以匹配的话,匹配在程序中更早出现的模式

上一题与本题识别规则比较如下:

序号 上一题识别规则 本题识别规则
1 "LET" {printf("Keyword ");} [0-9A-Fa-f]+H {printf("Number ");}
2 [0-9A-Fa-f]+H {printf("Number ");} [A-Za-z][A-Za-z0-9]* {printf("Identifier ");}
3 [A-Za-z][A-Za-z0-9]* {printf("Identifier ");} "LET" {printf("Keyword ");}
4 "=" {printf("Operator ");} "=" {printf("Operator ");}
5 . {} . {}

在识别时,程序将依次从1-5进行匹配,因此对于同样的输入串LET Something01 = DeadBeefH + Compiler

在上题中, LET 首先从序号1规则匹配并成功,因此输出Keyword;Something01依次匹配了1和2未能匹配上但在3规则下匹配输出了Identifier;后续同理。

但在本题中,LET 依旧从序号1规则开始匹配,此时序号1识别规则为 [0-9A-Fa-f]+H,匹配不成功,继续匹配规则2:[A-Za-z][A-Za-z0-9]*匹配成功并输出Identifier,也不再进行后续其他规则匹配;后续同理。

因此在本题中,上一题最先的规则"LET"被后移,而规则[A-Za-z][A-Za-z0-9]*被提前先于"LET",恰此规则也能够匹配 LET,于是出现了不同的识别结果。

实验代码链接

https://gitee.com/WilliamSamShen/complier-concepts/tree/master/Lab/lab3

  • 注意Windows下,提前配置好FLEX_BISON,默认大概率是win_flex,如果更名为flex,请将Makefile中对应win下的FLEXPREFIX变量置为空