注:
课程:《编译技术》上机
实验一:词法语法分析器的设计与实现,生成抽象语法树。
建议使用词法语法分析程序生成工具如:LEX/FLEX , YACC/BISON等专业工具完成。

此处完成补充 二元式展示+添加程序根 的操作
前期准备
  1. 已经将整个文件夹都备好份,以供魔改后的回溯
    在这里插入图片描述
开始实验
第一步

修改lex.l文件(lex描述文件给出了每一类词法单元的规则)
 大改!!!每个匹配后的执行语句都加上printf
在这里插入图片描述

%{
#include "parser.tab.h"
#include "string.h"
#include "def.h"
int yycolumn=1;
#define YY_USER_ACTION      yylloc.first_line=yylloc.last_line=yylineno; \
    yylloc.first_column=yycolumn;   yylloc.last_column=yycolumn+yyleng-1; yycolumn+=yyleng;
typedef union {
    int type_int;
    int type_float;
    char type_char;
    char type_id[32];
    struct node *ptr;
} YYLVAL;
#define YYSTYPE YYLVAL

%}
%option yylineno

id   [A-Za-z][A-Za-z0-9]*  
int    [0-9]+
float  ([0-9]*\.[0-9]+)|([0-9]+\.)
char    (\'[^\n]\')|(\"[^\n]\")

%%
{int}        {printf("%d [INT,%s]\n",yylineno,yytext); yylval.type_int=atoi(yytext); return INT;}
{float}      {printf("%d [FLOAT,%s]\n",yylineno,yytext);yylval.type_float=atof(yytext); return FLOAT;}
{char}      {printf("%d [CHAR,%s]\n",yylineno,yytext);yylval.type_char=*(yytext+1); return CHAR;}

"int"        {printf("%d [TYPE,%s]\n",yylineno,yytext);strcpy(yylval.type_id,  yytext);return TYPE;}
"float"      {printf("%d [TYPE,%s]\n",yylineno,yytext);strcpy(yylval.type_id,  yytext);return TYPE;}
"char"      {printf("%d [TYPE,%s]\n",yylineno,yytext);strcpy(yylval.type_id,  yytext);return TYPE;}
"return"     {printf("%d [RETURN,%s]\n",yylineno,yytext);return RETURN;}
"if"         {printf("%d [IF,%s]\n",yylineno,yytext);return IF;}
"else"       {printf("%d [ELSE,%s]\n",yylineno,yytext);return ELSE;}
"while"      {printf("%d [WHILE,%s]\n",yylineno,yytext);return WHILE;}
"for"      {printf("%d [FOR,%s]\n",yylineno,yytext);return FOR;}
"break"      {printf("%d [BREAK,%s]\n",yylineno,yytext);return BREAK;}
"continue"      {printf("%d [CONTINUE,%s]\n",yylineno,yytext);return CONTINUE;}
{id}       {printf("%d [ID,%s]\n",yylineno,yytext);strcpy(yylval.type_id,  yytext); return ID;}
";"           {printf("%d [SEMI,%s]\n",yylineno,yytext);return SEMI;}
","           {printf("%d [COMMA,%s]\n",yylineno,yytext);return COMMA;}
">"|"<"|">="|"<="|"=="|"!=" {printf("%d [RELOP,%s]\n",yylineno,yytext);strcpy(yylval.type_id, yytext);return RELOP;}
"="           {printf("%d [ASSIGNOP,%s]\n",yylineno,yytext);return ASSIGNOP;}
"+"           {printf("%d [PLUS,%s]\n",yylineno,yytext);return PLUS;}       
"-"           {printf("%d [MINUS,%s]\n",yylineno,yytext);return MINUS;}
"++"      {printf("%d [DPLUS,%s]\n",yylineno,yytext);return DPLUS;}
"--"      {printf("%d [DMINUS,%s]\n",yylineno,yytext);return DMINUS;}
"*"           {printf("%d [STAR,%s]\n",yylineno,yytext);return STAR;}
"/"           {printf("%d [DIV,%s]\n",yylineno,yytext);return DIV;}
"&&"         {printf("%d [AND,%s]\n",yylineno,yytext);return AND;}
"||"          {printf("%d [OR,%s]\n",yylineno,yytext);return OR;}
"!"           {printf("%d [NOT,%s]\n",yylineno,yytext);return NOT;}
"("           {printf("%d [LP,%s]\n",yylineno,yytext);return LP;}
")"           {printf("%d [RP,%s]\n",yylineno,yytext);return RP;}
"{"           {printf("%d [LC,%s]\n",yylineno,yytext);return LC;}
"}"           {printf("%d [RC,%s]\n",yylineno,yytext);return RC;}
"["           {printf("%d [LB,%s]\n",yylineno,yytext);return LB;}
"]"           {printf("%d [RB,%s]\n",yylineno,yytext);return RB;}
[\n]           {yycolumn=1;}   
[ \r\t]          {}   
.           {printf("Error type A :Mysterious character \"%s\"\n\t at Line %d\n",yytext,yylineno);}

%%

int yywrap()
{
return 1;
}
第二步

修改parser.y文件(parser.y是C语言文法)

  1. 第60行修改Exp语法
     老师想要程序有根,那么根从哪里来,就在这里添加语句
     其实一开始我是想要搞一个将源代码的文件名输出出来的操作得(test.c程序体:),但是参数是从main(int argc, char * argv[])的argv[1]获取的,但是很遗憾咱们的输出语句是在main运行前完成的,不能够获取到那个参数,so…木得了
    在这里插入图片描述
第三步

修改ast.c文件(ast.c定义了树的生成与输出)

  1. 第26行修改EXT_DEF_LIST的输出,indent+3
     为的是所有的代码输出都后移3个单位,从而体现出“程序体”文字的统领全篇
    在这里插入图片描述

补:解释一下 printf("% * cCHAR:%c\n",indent,’ ‘,T->type_char);的含义:先打印indent个空格,再打印CHAR:%c
默认低一级的话,往后移3个空格

结果检验

 依次运行

flex lex.l
bison -d parser.y
gcc -o parser lex.yy.c parser.tab.c ast.c
parser test.c

在这里插入图片描述
 发现有乱码,使用chcp 65001切换到UTF-8编码界面
在这里插入图片描述

 二元式输出完成!
在这里插入图片描述

 程序有根了hhhh!

 实验一暂时就搞到这里吧,还有很多功能没有添加上,也还有很多bug其实我知道在哪里,但是并没有精力去一个个改好了,虽有一点点缺憾,但我已经足够满意了。加油呀,打工人!

写在结尾

希望以上可以帮到你!
如有错误,或不同想法,欢迎指出,互相学习共同进步!

另:

 别催更了别催更了…..,弟弟哭liao~

在这里插入图片描述
 实验二还没有怎么搞,之后如果感觉搞得还行的话肯定是会发的,emmmm如果自己弄的乱七八糟也肯定不会发的,哥哥姐姐们先自己加油好呱!
在这里插入图片描述