HUST编译原理实验1

实验一、flex词法分析

具体flex使用方法,可参考编译原理-词法分析实践(flex)

1. %option yylineno

使得yylineno自动更新,返回所在行的行号。

2. 定义段

该段直接拷贝到c代码中运行,定义为flex中的全局变量。

%{
#include "stdio.h"
#include "string.h"
%}


id   [A-Za-z][A-Za-z0-9]*  
intconst    [0-9]+

3. 规则段

%%
[ \r\t\n]       {}

{intconst}      {printf("(51,%s) ",yytext);}

"+"               {printf("(60,-) ");}
"-"               {printf("(61,-) ");}
"*"               {printf("(62,-) ");}
"/"               {printf("(63,-) ");}
"="               {printf("(64,-) ");}
"<"               {printf("(65,-) ");}
">"               {printf("(67,-) ");}
"{"               {printf("(71,-) ");}
"}"               {printf("(72,-) ");}
"("               {printf("(73,-) ");}
")"               {printf("(74,-) ");}
","               {printf("(75,-) ");}
";"               {printf("(76,-) ");}


"int"           {printf("(1,-) ");}
"while"         {printf("(2,-) ");}
"if"            {printf("(3,-) ");}
"else"          {printf("(4,-) ");}
"return"        {printf("(5,-) ");}
{id}            {printf("(50,\"%s\") ",yytext);}
.		        {printf("\n<error character \'%s\' in line %d> ",yytext,yylineno);}

"<="            {printf("(66,-) ");}
">="            {printf("(68,-) ");}
"=="            {printf("(69,-) ");}
"!="            {printf("(70,-) ");}

<<EOF>>             { return 0; }


%%

在规则段中注意,如若有两个同等长度的符号匹配,则优先匹配前方的符号。

例如“+”,“”都可匹配符号“+”,则优先匹配写在前方的符号,因此必须将单符号,单字母,写在之前。同理,必须将关键字写在ID匹配之前。

对于特定字符,使用“”括起来匹配,对于正则表达式,直接使用正则表达式,或用{}括起来正则表达式的标识符,例如{id}使用。

<>表示匹配文件末尾标识符。

yytest为flex自带全局变量,保存当前正在匹配的字符串。

4. 用户子程序段

int main(int argc,char *argv[])
{
    yylineno=1;      //行序号变量,每次遇到\n后会自动加1
    yyin=fopen(argv[1],"r");
    if (!yyin) return 0;
    while (yylex());
    return 0;
}
int yywrap() { return 1;}

初始化yylineno,读入文件,while循环yylex,yylex调用规则段匹配程序。

5.编译运行

环境:将flex.exe所在文件的目录保存在用户系统变量中。
在test.l文件下运行cmd。
输入:flex test.l 编译文件,生成C文件lex.yy.c
输入:gcc lex.yy.c 编译c文件,生成可执行文件a.exe
输入:a.exe <需要编译的文件名称> 得到运行结果

实验二、词法分析(确定有穷自动机)

1. 文件的打开

FILE *fp;
fp=fopen(argv[1],"r");
if (!fp) {printf("Fail Open\n");return 0;}

2. 文件的读入

char c = fgetc(fp);

3. 文件的指针修改

fseek(fp,-1,SEEK_CUR);//从当前指针向后退一个字符。

4. 实现有穷自动机的方法:

  • 1)使用函数分割不同状态
  • 2)使用switch case来分割不同的状态

5. 有穷自动机

  1. 首输入为数字时,转入数字状态。
  2. 当首输入为字母时,转入关键字/ID状态。
  3. 当首输入为特殊符号时,转入相对应的符号状态
  4. 当首输入为回车、空格、制表符,跳过。
  5. 数字状态下,匹配数字,直到遇到非数字字符时,退回输入字符,并返回匹配的数字。
  6. 关键字/ID状态下,匹配字母、数字、下划线。遇到非法字符时,退回输入字符,并首先匹配关键字,如若没有匹配,则匹配ID。
  7. 特殊符号状态下,判断是否有双字符运算符,如若有,尝试匹配第二个字符。

实验总结:

掌握了flex的使用方法,flex词法构造,有穷自动机的构造等。
理解了编译器的词法部分的实现过程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Elsa的迷弟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值