某人,非说要用linux环境装lex和yacc,让我一度怀疑我的电脑的虚拟机环境可能出现了问题,装不了yacc,后面才发现原来lex和yacc是unix下的词法分析器和语法分析器,而在现在的linux系统中词法分析器和语法分析器早已经发展为了flex和bison,因此这一节我们通过flex和bison来实现一个简单编译器的功能。
一、Linux下环境的搭建
//安装flex和bison软件
yum install flex bison
//查看flex是否安装成功
flex -V
//查看bison是否安装成功
bison -V
二、window10环境的搭建
1.下载flex软件和bison软件,并安装在一个文件夹内
链接:https://pan.baidu.com/s/1670CatKUr03vSnEy5a0x_Q
提取码:ok7m
复制这段内容后打开百度网盘手机App,操作更方便哦
2.将这个文件夹的bin文件目录添加到用户变量的path路径下
我将其添加到了我的系统变量上,事实上用户变量也可以,添加到path路径下就行了。
2.测试是否安装成功?
在cmd下直接测试即可,出现以下情况则说明环境搭建成功。
三、linux下实现一个简单计算器的功能
1.词法分析文件,相当于一个词法分析器。
//calc.l代码
%option noyywrap
%{
/*
* 一个简单计算器的Lex词法文件
*/
void yyerror(char*);
#include "calc.tab.h"
%}
%%
/* a-z为变量 */
[a-z] {
yylval = *yytext - 'a';
return VARIABLE;
}
/* 整数 */
[0-9]+ {
yylval = atoi(yytext);
return INTEGER;
}
/* 运算符 */
[-+()=/*\n] {return *yytext;}
/* 空白被忽略 */
[ \t] ;
/* 其他字符都是非法的 */
. yyerror("invalid input");
%%
2.语法分析文件,相当于一个语法分析器。
//calc.y
%token INTEGER VARIABLE
%left '+' '-'
%left '*' '/'
%{
#include <stdio.h>
void yyerror(char*);
int yylex(void);
int sym[26];
%}
%%
program:
program statement '\n'
|
;
statement:
expr {printf("%d\n", $1);}
|VARIABLE '=' expr {sym[$1] = $3;}
;
expr:
INTEGER
|VARIABLE{$$ = sym[$1];}
|expr '+' expr {$$ = $1 + $3;}
|expr '-' expr {$$ = $1 - $3;}
|expr '*' expr {$$ = $1 * $3;}
|expr '/' expr {$$ = $1 / $3;}
|'('expr')' {$$ = $2;}
;
%%
void yyerror(char* s)
{
fprintf(stderr, "%s\n", s);
}
int main(void)
{
printf("A simple calculator.\n");
yyparse();
return 0;
}
3.Makefile文件,用来编译、链接、运行程序
makefile是用来“自动化编译”的,写好了之后,只需要一个make命令,整个工程完全自动编译,能够极大提高软件开发的效率,make是一个命令工具,用来解释makefile当中的指令。
//Makefile
all: clean calc
calc: calc.l calc.y
bison -d calc.y
flex calc.l
cc -o $@ calc.tab.c lex.yy.c -lm
clean:
rm -f calc \
lex.yy.c calc.tab.c calc.tab.h
4.linux下执行过程
四、Windows下实现一个统计输入字符串A-Z和a-z的字符个数
1.文件的创建准备工作
2.打开lex.l, 将以下代码复制到lex.l中去.
/*** Definition Section has one variable
which can be accessed inside yylex()
and main() ***/
%{
int count = 0;
%}
/*** Rule Section has three rules, first rule
matches with capital letters, second rule
matches with any character except newline and
third rule does not take input after the enter ***/
%%
[A-Za-z] {printf("%s capital letter\n", yytext);
count++;}
. {printf("%s not a capital letter\n", yytext);}
\n {return 0;}
%%
/*** Code Section prints the number of
capital letter present in the given input ***/
int yywrap(){}
int main(){
// Explanation:
// yywrap() - wraps the above rule section
/* yyin - takes the file pointer which contains the input */
/* yylex() - this is the main flex function which runs the Rule Section */
// yytext is the text in the buffer
// Uncomment the lines below
// to take input from file
// FILE *fp;
// char filename[50];
// printf("Enter the filename: \n");
// scanf("%s",filename);
// fp = fopen(filename,"r");
// yyin = fp;
yylex();
printf("\nNumber of Captial letters "
"in the given input - %d\n", count);
return 0;
}
3.运行词法分析代码,生成c语言代码
这里没有使用语法分析器,使用的是devc++来运行生成的.c文件,当然也可以自己下载gcc,在命令行窗口下执行.c文件,然后得到结果;但是那样显然就复杂了,反正devc++里也内置有语法分析器。
结束语:时间过得好快呀!