编译原理lab4
1 考虑如下FLEX描述文件的识别规则部分,下面输入串对应的输出是什么?请分析原因并附上执行输出截图。 AAAAAAA
%%
A {printf("ONE\n");};
AA {printf("TWO\n");};
AAAA {printf("THREE\n");};
%%
输出为:
THREE
TWO
ONE
输出截图如下:

原因为词法分析器匹配输入时匹配尽可能多的字符串,
本题规则如下:
| 序号 | 规则 | 执行动作 |
|---|---|---|
| 1 | A | printf("ONE\n") |
| 2 | AA | printf("TWO\n") |
| 3 | AAAA | printf("THREE\n") |
而输入为: AAAAAAA(共7个A),
识别规则均与A相关,则词法分析器将首先匹配最长的规则3,因为规则3匹配4个A,并输出THREE和换行;
然后剩余字符串为AAA(共3个A),已不满足规则3的4个A,但满足了规则2的2个A且也满足尽可能多的匹配原则,因此输出TWO并换行;
最终只剩余A,只能匹配规则1,输出了ONE和换行。
最终得到了上述输出。
2 对如下FLEX描述文件的识别规则部分,下面输入串对应的输出是什么?请分析原因并附上执行输出截图。abbacbababcab
%%
ab printf("1 %s\n", yytext);
b*a*c? printf("2 %s\n", yytext);
ba.a* printf("3 %s\n", yytext);
aa*c printf("4 %s\n", yytext);
ab*c? printf("5 %s\n", yytext);
%%
输出为:
5 abb
2 ac
3 baba
2 bc
1 ab
输出截图如下:

原因综合了以下两条规则:
1.词法分析器匹配输入时匹配尽可能多的字符串。
2.如果两个模式都可以匹配的话,匹配在程序中更早出现的模式
本题规则如下:
| 序号 | 规则 | 执行动作 |
|---|---|---|
| 1 | ab | printf("1 %s\n", yytext) |
| 2 | bac? | printf("2 %s\n", yytext) |
| 3 | ba.a* | printf("3 %s\n", yytext) |
| 4 | aa*c | printf("4 %s\n", yytext) |
| 5 | ab*c? | printf("5 %s\n", yytext) |
而输入为:abbacbababcab,
首先匹配以a开头的规则,可能有规则1、4、5,继续匹配b则有规则1、5,匹配时匹配尽可能多的字符串,则规则5能够匹配更多字符串abb,于是输出5和abb;
然后剩余字符串为acbababcab,匹配a,可能有规则1、2、4、5,继续匹配c则有规则2、4、5,而后的b都不满足无法继续匹配,则规则2、4、5都匹配ac时,选取出现最早的模式即规则2,于是输出2和ac;
随后剩余字符串为bababcab,匹配b,可能有规则2、3,继续匹配b,仍符合规则2、3,但规则3可以继续匹配而规则2不在能够继续匹配,于是遵循匹配尽可能多的字符串的原则,匹配规则3,能够匹配字符串baba,于是输出3和baba;
再然后剩余字符串为bcab,匹配b,可能有规则2、3,继续匹配c则仅有规则2能匹配上,于是输出2和bc;
最后剩余字符串为ab,匹配a,可能有规则1、4、5,继续匹配b可能有规则1、5,此时结束,对于相同长度则先选取最先出现规则即规则1,于是输出1和ab。
最终输出如上所述。
3 请用FLEX写一个规则处理文件,将输入文件中的多个空格、制表符、回车、换行均改为单个空格,其余字符保持不变。请给出完整的.l文件,并附上输入文件和执行输出截图。
提示:可以将 yyin 赋值为文件指针,例如 yyin = fopen("file.txt", "r"),这将使 Flex 从 file.txt 文件中读取数据进行分析。
flex规则处理文件如下:
%%
[ \t\r\n]+ {printf(" ");}
. {printf("%s",yytext);}
%%
int main(){
yyin = fopen("file.txt","r");
yylex();
fclose(yyin);
}
int yywrap(){
return 1;
}
输入文件如下:
a b c
d
e
f
g
hijklmn op q rs t u v w
xy
z
输出截图如下:

- 需注意文件路径,确认是否能够读到输入文件
4 自行用FLEX编写一个规则处理文件,定义至少三条词法识别(及相应处理)的规则,完成一个有实际意义的任务。请给出你的任务说明、完整的.l文件、执行输入输出截图。
注:规则不能全部和本课程已有的上机题一样。
任务说明如下:
在给定的输入后,确定其是否是下列信息,并输出判断
1、身份证号码
2、电子邮件地址
3、符合给定规则的手机号(如以13,18开头等)
flex规则处理文件如下:
%%
^[0-9]{18}$ {printf("id#");}
^[0-9]{17}([0-9]|X|x)$ {printf("id#");}
^[A-Za-z0-9]+@[a-zA-Z0-9_-]+(.[a-zA-Z0-9_-]+)+$ {printf("EMAIL_ADDRESS");}
^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])[0-9]{8}$ {printf("phone#");}
%%
int main(){
yylex();
}
int yywrap(){
return 1;
}
输入和输出截图如下:

代码链接
https://gitee.com/WilliamSamShen/complier-concepts/tree/master/Lab/lab4