语法分析 Flex + Yacc (BISON) + 词法分析

语法分析 Flex + Yacc (BISON)

Difference

flex 文件中第一部分,加上 #include “y.tab.c”
y.tab.h是bison在翻译代码时自动生成的头文件(这也是为什么我们先翻译.y文件),如果不加上这个头文件,则编译会出错。

第二部分的 action, 会变成 return

事实上,这些符号的定义就在t.tab.h头文件中,它们都是一些互不相同的常量,这也是为什么不使用该头文件就会报错。那么这些符号是bison自动定义的吗?其实不是,我们会在编写bison代码时手动定义这些符号。

第三部分直接略掉,搬到了yacc文件中

makefile 中指令也发生变化

eg: test.l, test.y

bison --yacc -dv test.y
flex -o test.yy.c test.l
gcc -o test.out y.tab.c test.yy.c

文件架构

与flex 文件相同,但是具体语法有所差距

语法

%{ %} 中,需要定义 int yylex(void); void yyerror(char* ); 函数 (flex中有的函数)

%token NUM ADD SUB MUL DIV VAR CR 

在%token后面,跟着一些字符串,我们就是在这里定义了这些符号,它们会被翻译成C头文件 #define NUM 123 // 不关心数值,数值没用
被flex引用,然后又通过yylex()函数return回来。
称为标记

第二部分语法规则 (关键)
需要懂得BNF(巴克斯范式), 明白什么是移进和归约 rule-> BNF action—

expression: expression '+' expression
		  | expression '-' expression
		  | NUM
		  ;

**【注意】:最后需要;结尾

第三部分代码

void yyerror(char *str){
    fprintf(stderr,"error:%s\n",str);
}

int yywrap(){
    return 1;
}
int main()
{
    yyparse();
}

这里给出了yyerror具体的报错操作;
yywrap函数同之前在flex的讲述;
yyparse函数就是bison的语法分析函数。

最后就是yywarp函数,这是一个约束函数,当它返回1时,代表扫描结束,此时结束程序。这个函数在读取多个文件时很有用处,关于它的进阶运用也会在未来而不是现在展开

运行

会自动生成.output文件(好像),里面是语法分析器的具体实现(语法分析表以及语法规则)

保留值

%union{
	int i;
	double d;
}

首先,我们用%unionyylval变成了一个联合体,类似于全局变量,方便后续使用
此后,我们发现了%token的另一种用法:将联合体的一个变量名用尖括号括起,后跟终结符(可以为多个),就能表示它们的值使用的是这个变量。
接着,是从未见过的%type,其实这与上面%token的用法一样,也是指示类型,但这次指示的是非终结符。

expression: expression SUB term   {$$=$1-$3;}

$1表示的是expression的值, 3 表示的是 t e r m 的值; ( ∗ ∗ 产生式的右部 ∗ ∗ ) 而两者相减后将值传给 3表示的是term的值;(**产生式的右部**) 而两者相减后将值传给 3表示的是term的值;(产生式的右部)而两者相减后将值传给$,这就是归约后的符号的值(产生式的左部)

yytext

yytext是lex内部已经定义好的指针变量
lex分析过程是将输入字符串按程序员预先设计好的正则表达式进行匹配
yytext总是指向当前获得匹配的字符串

{NUM} sscanf(yytext,"%d",&yylval.asd); return NUM;

表示,当读到NUM时,将NUM的以值的形式传给yylval.asd,方便后续使用,(可以进行运算并输出结果的原因)

词法分析 Flex

Flex 简介
Flex + Yacc 逐步解析

将词法分析程序 生成可执行文件

write a txtfile named ?.l
run the code in cmd

        flex ?.l
        flex -o asd.yy.c asd.l
        gcc lex.yy.c
        gcc -o asd asd.yy.c
        

then you ll get an excutable file named ?.out
运行 cmd :./?.out over

Flex

make a lexical analyzer into a “.c” file

内置函数

函数名定义
yyinFILE*类型,指向LEX输入文件,缺省情况下指向标准输入
yyoutFILE*类型,指向LEX输出文件,缺省情况下指向标准输出
yytextchar*类型,指向识别规则中的一个正规式匹配的单词的首字符
yylengint类型,记录与识别规则中正规式匹配的单词的长度
yylex()从该函数开始分析,可由lex自动生成
yywrap()文件结束处理函数,如果返回值为1就停止解析。可以用来解析多个文件。
echo将yytext打印到yyout

分析文件

yyin=fopen(“testin.c”,“r”);
yyout=fopen(“testout.txt”,“w”);

【注意】:分析是从yylex开始
【注意】:fopen中的引号是双引号,否则编译能过,但是运行会出错

操作 // 第二部分

第二部分用于定义语法规则
一行表示一种匹配,最后附加的语句表示匹配到之后的动作(多条语句用花括号)

宏定义

ALPHA [a-zA-Z]
VAR   {ALPHA}+[a-zA-Z0-9_]*
KEY   int|double
DIGIT [0-9]
VALUE [1-9]+{DIGIT}*|{DIGIT}+\.{DIGIT}+

匹配时,{KEY}

写程序时候别忘了分区域 %%,否则无法编译

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值