从lex&yacc说到编译器(2.flex的使用)

lex&yacc说到编译器(2.flex的使用)

作者:tangl_99

QQ:8664220

msn:tangl_99@hotmail.com

email:tangl_99@sohu.com

 

看了第一篇的关于正则表达式的说明后,下面我们就来通过它,使用flex这个词法分析工具来构造我们的编译器的词法分析器.

关于lex的教程应该是很多,这里我就简单地介绍一下,然后着重后面的lex和yacc的配合使用以及其技巧.所以,如果你不看了后还是不太明白lex或者yacc的使用,请你自己上网去查查,这方面的教程是很多的.我知道的一篇常见的就是

Yacc 与 Lex 快速入门
Lex 与 Yacc 介绍

它的作者就是Ashish Bansal.

 

Flex就是fast lex的意思.而lex就是Lexical Analyzar的意思.flex可以在cygwin或者gnupro中找到.它是unix的一个工具,属于GNU组织产品.网上也可以找到单独可以在windows下用的版本.

我们一般把我们的词法扫描程序要扫描的一些单词(token)用正则表达式写好,然后作为lex的输入文件,输入命令flex xxx.l(xxx.l就是输入文件),lex经过处理后,就能得到一个名字叫lex.yy.c的C源代码.这个C源代码文件,就是我们的词法扫描程序.通常lex为我们生成的词法分析器的C源代码都是十分复杂而且庞大的,我们一般根本不会去查看里面的代码(放心好了,flex这个东西不会出错的)

 

下面让我们看看几个我已经使用过的几个lex输入文件.

这是一个前段时间我为GBA上的一个RPG游戏写的脚本引擎所使用的lex输入文件(部分)

2.1

 

%{

/* need this for the call to atof() below */

#include <stdio.h>

#include <stdlib.h>

#include <math.h>

#include "globals.h"

 

%}

digit        [0-9]

number       ("-"|"+")?{digit}+

hexnumber    "0x"({digit}|[a-fA-F])+

letter       [a-zA-Z]

identifier   ({letter}|_)({number}|{letter}|_)*

newline      [/n]

whitespace   [ /t]+

string       /"[^"]*/"

comment      "#"[^#]*"#"

%%

 

{string}     { return VM_STRING;        }

"Logo"       { return VMIN_LOGO; }

"FaceIn"     { return VMIN_FACEIN; }

"FaceOut"    { return VMIN_FACEOUT; }

"LoadTile"   { return VMIN_LOAD_TILE;   }

"CreateRole" { return VMIN_CREATE_ROLE; }

"ReleaseRole" { return VMIN_RELEASE_ROLE;}

"CreateMap"  { return VMIN_CREATE_MAP;  }

阅读终点,创作起航,您可以撰写心得或摘录文章要点写篇博文。去创作
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Lex和Yacc是Unix系统中的常见工具,它们可以用于生成编译器的词法分析器和语法分析器。我们可以使用这两个工具来实现一个简单的C编译器。 下面是一个实现C编译器的基本步骤: 1. 设计语法规则:首先需要确定C语言的语法规则。可以参考C语言标准来确定语法规则,并将其表示为BNF范式。 2. 编写Lex文件:根据语法规则,编写Lex文件。Lex文件包含正则表达式和对应的动作,用于生成词法分析器。词法分析器会根据输入的源代码逐个读取字符并生成词法单元。 3. 编写Yacc文件:根据语法规则,编写Yacc文件。Yacc文件包含语法规则和对应的动作,用于生成语法分析器。语法分析器会根据词法分析器生成的词法单元,逐步构建语法树,并执行对应的动作。 4. 编写代码生成器:根据语法树,生成对应的目标代码。 下面是一个简单的例子,用于演示如何使用Lex和Yacc生成C编译器: 首先,我们需要定义C语言的语法规则。例如,我们可以定义一个简单的语法规则,用于表示一个整数常量: ``` <constant> ::= <digit> | <digit> <constant> <digit> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 ``` 接下来,我们可以编写Lex文件,用于生成词法分析器。例如,我们可以编写如下的Lex文件: ```lex %{ #include <stdio.h> #include <stdlib.h> %} DIGIT [0-9] %% {DIGIT}+ { printf("CONSTANT: %s\n", yytext); return CONSTANT; } . { return yytext[0]; } %% int yywrap() { return 1; } ``` 在上面的代码中,我们使用了Lex的正则表达式来匹配整数常量。当遇到一个整数常量时,我们会打印出它的值,并返回对应的词法单元CONSTANT。 接下来,我们编写Yacc文件,用于生成语法分析器。例如,我们可以编写如下的Yacc文件: ```yacc %{ #include <stdio.h> #include <stdlib.h> #include <string.h> int yylex(); void yyerror(char *); %} %token CONSTANT %% program: statement_list ; statement_list: statement | statement_list statement ; statement: expression_statement ; expression_statement: CONSTANT ; %% void yyerror(char *s) { fprintf(stderr, "%s\n", s); } int main() { yyparse(); return 0; } ``` 在上面的代码中,我们定义了一个简单的语法规则,用于表示一个整数常量。当遇到一个整数常量时,我们会执行对应的动作。 最后,我们还需要编写代码生成器,用于生成对应的目标代码。由于这超出了本题的范围,这里不再给出具体实现。 综上所述,上述步骤就是使用Lex和Yacc实现C编译器的基本步骤。当然,实际上还有许多细节需要考虑,例如错误处理、符号表管理等等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

HashCodeWithJava

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

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

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

打赏作者

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

抵扣说明:

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

余额充值