内容目录
编译原理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
执行输出截图如下:

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
执行输出截图如下:

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
执行输出截图如下:

同样输入串得到不同识别结果的原因是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变量置为空