实验1:用lex构造c子集词法分析器
基于LEX语言的词法分析程序自动构造过程

数 时 控制程 序 中 的 限制 条 件 为 已 接 收 字符 串长度
是否大于
,
所有这些
都 有 相 同 的初 态
。
,
初态
均为
二
长度 为
,
识别这三个单,来自准 备 识 别 单 词 的状 态
词 时 控 制程 序 中 的 限 制 条 件 为 已 接 收 字 符 串长 度 按 相 同 的初
,
,
将各类单词正规 式对应 的
呈鱼
一万石厂几丝迹
“
”
十
“
”
十
“
”
。十
二
十
。十
二
‘
图
使用
生成 词 法分析 器
玫对 目
以初
业
“
”
十
‘
环
“
”
“
” 十
,
“
比
。。
源程序
比
语 言是 一 种 描 述 性 语 言
、
“
”
,
“
,
”
。。 十
‘
源程序 主要
“
”
。。
‘
,
。
用来 描述 各 类语 言 的 词 法
比 源 程 序 由三 部 分 组
作间隔
“
”
十
闷
一
初态
,
,
作
,
,
,
,
,
,
,
,
,
一
,
,
,
川
,
,
,
,
,
,
,
,
,
,
为 当 前 状 态 从 源 文 件 中读 入 一 个 字 符
lex工具实例

翻译规则部分(续)
为避免二义性,在Ri中 若需出现空格、回车或 制表符,则应用‘\s’, ‘\n’,‘\t’表示。 每个代码段Actioni可 引用已定义的常量、全 局变量和外部变量,也 可以调用在辅助函数部 分定义的函数。
注意:Actioni中的C
程序语句多于一条时, 必须用花括号{ }将 它们括起来,否 则,LEX将会报错
词法分析程序的使用
用户可通过调用函数yylex()使用词法分析程序。每调 用yylex()函数一次,yylex()将从输入流中识别一个单词, 并返回一个整型值(被识别出的单词之内部码)。 所谓单词的内部码是指词法分析程序在识别出某一类 单词时所返回的整型数值(也称为类别码),它由用 户自行定义其取值。 例如,用户可定义标识符Id的内部码为300,实型数 RealNo的内部码为450等等。一般说来,用户自定义的 单词类别码应大于256,而小于256的内部码值可用于 字符单词的类别码,用其ASCII码值来表示。如单词 '+'的内部码可定义为‘+’的ASCII码值43。
LEX的命令格式及选项
格式:lex [-ctvn -V -Q[y|n]] [files] 选项: -c 指明动作为C语句(缺省设置). -t 输出到stdout 而不是 lex.yy.c(缺省设置); -v 提供一个两行的统计概述 -n 不输出-v的概述 -V 在stderr上输出lex的版本信息. -Q[y|n] y:在输出文件lex.yy.c上打印版本信息. n:不打印(缺省设置). 若files为多个文件,则被视为一个,若files为空,则使用stdin.
1.声明(declaration)
LEX的声明又可以分两个
基于LEX的C语言词法分析器

基于LEX的C语言词法分析器下面是一个基于LEX的C语言词法分析器的示例代码:```c#include <stdio.h>%}letter [a-zA-Z]digit [0-9]id {letter}({letter},{digit})*number {digit}+(\.{digit}+)?([eE][+-]?{digit}+)?%%{number} { printf("Number: %s\n", yytext); }{if} { printf("If: %s\n", yytext); }{else} { printf("Else: %s\n", yytext); }{while} { printf("While: %s\n", yytext); }{for} { printf("For: %s\n", yytext); }{id} { printf("Identifier: %s\n", yytext); }[ \t\n]+ // ignore white space. { printf("Unrecognized character: %c\n", yytext[0]); }%%int maiyylex(;return 0;```在上述代码中,首先是一些初始化的定义,定义了一些正则表达式模式,例如`letter`表示字母,`digit`表示数字,`id`表示标识符,`number`表示数字。
然后是各个模式的匹配规则和对应的处理逻辑。
其中,`{number}`表示如果匹配到了数字模式,就打印出该数字;`{if}`、`{else}`、`{while}`、`{for}`和`{id}`分别表示匹配到了if、else、while、for关键字和标识符,就打印出对应的信息;`[ \t\n]+`表示忽略空格和换行符;`.`表示匹配到了其他未定义的字符,就打印出异常信息。
(完整版)基于LEX的词法分析器实验报告

定义识别标识符规则
{id}
{printf("%d行",lineno);
printf("%s ID\n",yytext);}//
定义识别错误的字符串规则当开头为数字的后面为字母的字符串时,是错误的标识符。{error_id}
yylex();/*start the analysis*/
printf("ok2\n");
printf(" No of words: %d\n number: %d\n", wordCount, numcount);
return0;
}
int yywrap()
{
return1;
}
2、新建文本文件,更名为b.c,敲入下面代码此为输入源代码
{printf("error:%s\n",yytext);}//以数字开头的字符自动报错定义忽略空格规则
{whitespace}{/*skip whitespace*/}//忽略空格定义忽略回车规则
{enter}
{lineno++;}//遇到回车自动加行号忽略辅助程序集中包括
主函数main()和辅助函数toupper()。程序代码实现
二、实验原理及方法
Lex输入文件由3个部分组成:定义集(definition),规则集(rule)和辅助程序集(auxiliary routine)或用户程序集(user routine)。这三个部分由位于新一行第一列 的双百分号分开,因此,Lex输入文件的格式如下
{definitions}
(完整版)基于LEX的词法分析器实验报告

2、ห้องสมุดไป่ตู้用lex生成此法分析器:
新建文本文件,更改名称为a.lex,敲入下面代码■------词法分析器的源代码
%{
int wordCount= 0;
Lex代码
//定义集,包括头文件和变量定义
%{
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int lineno=1;//定义行号
%}
//定义正则表达式letter [A-Za-z]//字母digit[0-9] //数字id ({letter}|[_])({letter}|{digit}|[_])* error_id ({digit})+({letter})+ num {digit}+ whitespace[\t]+ enter [\n]+//定义识别规则
/*increase the word count by one*/}
{whitespace}{ /*do nothing*/}
([0-9])+ {numcount++;/* one maywant to add someprocessinghere*/}
%%
void main()
{
printf("ok1\n");
num {digit}+whitespace [ \t]+ en ter [\n ]+
lex用法

lex用法
"lex"是一种文本分析工具,主要用于编写词法分析器。
它能够根据用户所定义的模式匹配规则,自动生成C语言代码实现词法分析功能。
具体来说,使用"lex"需要以下几个步骤:
1. 编写"lex"文件:该文件包含"lex"语法及模式匹配规则,决定了如何从输入的字符流中识别
和提取出各种符号和单词。
2. 使用"lex"命令编译生成C程序:命令格式为: `lex -o output.c input.l`,其中"output.c"为生成
的C源程序文件,"input.l"为"lex"文件名。
3. 编译并链接生成的C程序:使用C语言编译器(如gcc)编译生成的C源程序文件,并将其与主程序进行链接,形成可执行文件。
4. 运行程序并测试:将待分析的文本输入到程序中,程序会按照模式匹配规则进行词法分析,并输出分析结果。
"lex"的优点在于可以大大简化词法分析器的编写和维护工作,同时也增强了程序的可读性和
可移植性。
它常被用于编写编译器、解释器、文本编辑器等需要对文本内容进行识别和分析的应
用程序中。
词法分析器Lex实验报告

实验内容(算法、程序、步骤和方法)
1.基于Lex构造词法分析器的方法
1.1Lex文件格式
Lex文件分成三个部分,分别为definitions、rules以及auxiliary routines,中间用%%分割开。
Definitions包括要加入到生成的C程序的头部的代码,包括#include语句、#define语句及一些全局变量的定义。同时,正则表达式可以在这个部分定义,如identifier的定义:
{LCURVE, '{'} {INT, 'int'} {ID, 't'} {SEMICOLON, ';'}
{ID, 'k'} {ASSIGN, '='} {ID, 'minloc'} {LPARENTHESIS, '('} {ID, 'a'} {COMMA, ','} {ID, 'i'} {COMMA, ','} {ID, 'high'}{RPARENTHESIS, ')'} {SEMICOLON, ';'}
{LCURVE, '{'} {INT, 'int'} {ID, 'i'} {SEMICOLON, ';'} {INT, 'int'} {ID, 'k'} {SEMICOLON, ';'}
{ID, 'i'} {ASSIGN, '='} {ID, 'low'} {SEMICOLON, ';'}
编译原理实验报告 COMPILE_使用SLex自动生成词法分析程序

编译原理实验报告—使用SLex自动生成词法分析程序实验1.3 使用SLex自动生成词法分析程序一、实验目的1.掌握词法分析程序自动生成系统LEX的原理与过程。
2.熟悉LEX源程序语法。
3.学习使用自动构造软件Slex。
4.分析自动生成的词法分析程序结构。
二、实验平台Windows + Slex三、实验内容编写LEX源程序, 分别实现以下功能1)将输入文件中的小写字母转换成大写字母,并输出到屏幕上。
2)识别出文件中的标识符, 然后将识别出的标识符输出到屏幕上。
3)将输入串中所有能被7整除的整数加上3, 将结果输出到屏幕上. 其余部分照原样输出.四、实验步骤一、在cygwin\home\Administrator文件夹下,创建一个1.txt文件,构造lex 源程序,然后将1.txt改成1.lex.代码如下:%{#include <stdio.h>#include <string.h>#include <stdlib.h>%}%%[a-z] printf("%c",yytext[0]+'A'-'a');%%main(){yylex();return 0;}int yywrap(){return 1;}2、运行Cygwin1)在Dom环境下输入:flex 1.lex,系统自动生成lex.yy.c 2)输入gcc.lex.yy.c,系统自动生成a.exe.3)输入./ a.exe,可运行a.exe文件。
3、运行结果二.同理编写2.lex.代码如下%{#include <stdio.h>#include <stdlib.h>%}%%[a-zA-Z][a-zA-Z0-9]* { printf("%s\n",yytext); }%%main(){yylex();return 0;}int yywrap(){return 1;}2、运行Cygwin1)在Dom环境下输入:flex 2.lex,系统自动生成lex.yy.c 2)输入gcc.lex.yy.c,系统自动生成a.exe.3)输入./ a.exe,可运行a.exe文件。
编译原理 实验报告(词法分析器)

实验LEX词法分析器自动生成器一、实验内容:用词法分析自动生成器LEX构造一个简单词法分析器,它能识别文件新行并为其添加行号,并将分析结果发送到屏幕上。
二、实验目的:1.掌握LEX源程序的编写方法。
2.掌握自动生成词法分析器LEX的使用方法和工作原理。
LEX源程序*.L通过LEX编译程序,产生一个C语言版本的词法分析程序*.C。
然后通过C语言编译器,将词法分析程序*.C转换成一个可执行文件*.EXE。
再编制一个测试文本文件*.TXT。
用生成的词法分析程序的可执行文件,对测试程序进行词法分析.三、实验要求1.写好实验预习报告;2.编写上机源程序和测试程序;3.写出实验结果;4.实验完后要上交实验报告;四、相关说明LEX上机过程部分:1)利用编辑器如EDIT编写LEX源程序和测试程序,如SHIYAN11.L和TEST.TXT;2)用LEX编译器编译LEX源程序SHIYAN11.L,格式为:LEX SHIYAN11.L↙如果LEX源程序没有语法错误,将得到一个用C语言描述的没有语法错误词法分析器SHIYAN11.C;3)在TC环境下,对SHIYAN11.C进行编译、连接,从而得到可执行的词法分析器SHIYAN11.EXE;4)利用SHIYAN11.EXE对TEST.TXT进行词法分析,格式为:SHIYAN0.EXE<TEST.TXT↙如果没有写测试程序TEST.TXT,则可测试其他某个程序如SHIYAN11.L。
LEX上机过程如下图所示(alt+c):五、实验器材硬件:PC机一台软件:Turbo C、LEX.EXE六、参考程序1.LEX源程序:shiyan11.L%{#include "stdio.h"int lineno=1;()%}line .*\n%%{line} {printf("%2d %s",lineno++,yytext);}%%main(){yylex();return 0;}2.shiyan11.EXE分析shiyan11.L的实验效果如下图所示:。
词法分析器(lex实现)

院系:计算机学院实验课程:编译原理实验项目:C++源代码单词扫描程序(词法分析)指导老师:陈寅开课时间:2014~2015年度第1学期专业:数据库班级:2班学生:雷楚楚学号:20122100158C++源代码单词扫描程序(词法分析)一、实验目的设计并实现一个词法分析器,深刻理解编译原理中词法分析器的原理。
二、实验内容1、C++源代码扫描程序识别C++记号。
C++语言包含了几种类型的记号:标识符,关键字,数(包括整数、浮点数),字符串,注释,特殊符号(分解符)和运算符号等。
2、打开一个C++源文件,打印出所有以上的记号。
3、选作部分:为了提高C++源程序的可读性,C++程序在书写过程中加入了空行、空格、缩进、注释等。
假设你想牺牲可读性,以节省磁盘空间,那么你可以存贮一个删除了所有不必要空格和注释的C++源程序的压缩文本。
因此,程序中还看可以有这样的压缩功能。
4、进一步实现减少源文件大小的压缩功能。
5、完善软件文档。
二、实验过程1、对C++文法中的各类单词分类(1)保留字:asm、do、if、return、typedef、auto、double、inline、short、typeid、bool、try、include、long、sizeof、union、case、enum、mutable、static、unsigned、long、sizeof、union、case、enum、mutable、static、unsigned、catch、explicit、namespace、using、char、export、int、signed、break、else、new、struct、virtual、class、extern、operator、switch、void、const、false、private、template、volatile、float、protected、this、continue、for、public、throw、while、default、friend、register、true、delete、goto、try、include、std、iomanip、setw、setprecision、endl、setiosflags、ios (2)数字:包括整数和浮点数(3)标识符:由字母打头的字母和数字的字符串,可包含下划线(4)运算符:"&="、"^="、"、="、"<<="、">>="、"*="、"/="、"%="、"+="、"-="、"="、"?:"、"、、"、"&&"、"、"、"^"、"&"、"=="、"!="、">"、">="、"<"、"<="、"<<"、">>"、"+"、"-"、"*"、"/"、"%"、".*"、"->*"、"&"、"+"、"-"、"++"、"--"、"->"、"::"(5)界符:"{"、"}"、"("、")"、"#"、","、":"、";"、"."、"\""(6)注释:包括//和/**/两种类型的注释(7)字符串:包含在“”里面的内容2、将各类单词对应到Flex中:(1)保留字:asm|do|if|return|typedef|auto|double|inline|short|typeid|bool|try|include|long|sizeof|union|case|enum|mutable|static|unsigned|long|sizeof|union|case|enum|mutable|static|unsigned|catch|explicit|namespace|using|char|export|int|signed|break|else|new|struct|virtual|class|extern|operator|switch|void|const|false|private|template|volatile|float|protected|this|continue|for|public|throw|while|default|friend|register|true|delete|goto|try|include|std|iomanip|setw|setprecision|endl|setiosflags|ios(2)数字:包括整数和浮点数(正负)[+-]?([0-9]*|0|([0-9]*\.[0-9]*))(3)标识符:由字母打头的字母和数字的字符串,包含下划线[A-Za-z]([A-Za-z]|[0-9]|_)*(4)运算符:"&="|"^="|"|="|"<<="|">>="|"*="|"/="|"%="|"+="|"-="|"="|"?:"|"||"|"&&"|"|"|"^"|"&"|"=="|"!="|">"|">="|"<"|"<="|"<<"|">>"|"+"|"-"|"*"|"/"|"%"|".*"|"->*"|"&"|"+"|"-"|"++"|"--"|"->"|"::"(5)界符:"{"|"}"|"("|")"|"#"|","|":"|";"|"."|"\""(6)注释:包括//和/**/两种类型的注释\/\*(\s|.)*?\*\/(/**/)\/\/[^\n]*(//)(7)字符串:包含在“”里面的内容'[^'\n]*'|\"[^\"]*\"(8)除其他情况之外判断为出错3、跳过空行和空格[\t]+{}/*空格*/ \n|.{}/*空行*/4、为lex制定一些规则5、写子程序让用户输入要进行词法扫描的文件,当lex读完输入文件之后就会调用函数yywrap。
编译原理 lex使用

编译原理 lex使用
Lex是一种常用的词法分析工具,它可以解析输入字符串并将其分解为标记(token)。
在编译原理课程中,我们经常需要使用lex来生成词法分析器,以便将源代码转换为可执行代码。
使用Lex的基本步骤如下:
1. 编写一个类似于正则表达式的规则文件,描述如何匹配输入的字符串。
2. 使用lex工具将规则文件转换为C语言代码。
3. 编写一个main函数,调用生成的词法分析器来读取输入文件并解析出标记。
4. 在解析出的标记中执行语法分析,并将其转换为可执行代码。
需要注意的是,Lex的规则文件是基于正则表达式的,因此熟悉正则表达式的语法和特性是非常重要的。
在编写规则文件时,可以使用一些特殊的符号来描述字符类、重复次数、分组等特性,例如:
- []表示字符类,例如[0-9]表示匹配所有数字字符。
- {}表示重复次数,例如{1,3}表示重复1到3次。
- ()表示分组,例如(a|b)表示匹配a或b。
除了这些基本特性之外,Lex还提供了一些高级功能,例如:
- 跳过某些特定的字符,例如空格、注释、预处理指令等。
- 可以对不同的输入文件使用不同的规则文件。
- 可以为不同的标记指定不同的操作,例如输出、转换等。
总之,使用Lex可以大大简化词法分析的过程,提高代码的可维
护性和可读性。
如果你正在学习编译原理或者需要开发一个编译器,那么掌握Lex的使用是必不可少的。
词法分析实验

词法分析实验一、实验题目编写Tiny语言的词法分析程序。
二、实验目的1,构造Tiny词法分析程序,程序要求能对输入的字符串流进行词法分析。
2,在实验的过程中,学会应用单词分析的方法——构造NFA(非确定有穷自动机)和DFA(确定有穷自动机)。
3,使用Lex工具分析词法。
三、实验要求1、独立完成实验2、由老师现场检查程序代码和运行结果3、提交代码实验报告:包含程序代码和运行结果截图四、实验环境操作系统:Windows/Linux开发语言:C/C++开发工具:Cygwin (在windows平台上运行的UNIX模拟环境);Lex词法分析工具。
五、实验内容采用下面两种方式对给定的样本语言Tiny实现一个扫描程序:1、使用Lex自动生成词法分析程序,2、自己编写一个Tiny词法分析程序。
输出结果包含1、打印出符号(Token)所在的源代码中的行数,2、以二元组方式打印符号,例如<1, IF>,3、打印该符号的类型:(保留字(Reserved word)、特殊符号(Special Symbol)和“其他”(Other))。
Tiny语言介绍Tiny语言在语法上是一个由分号分隔开的语句序列。
没有过程,没有声明,所有变量都是整形变量。
Tiny语言有两个控制语句,分别是if语句和repeat语句。
Tiny的记号分为3个典型类型:保留字、特殊符号和“其他”记号。
1,保留字if、then、else、end、repeat、until、read、write2,特殊符号+ - * / = < ( ) ; :=3,其他数(NUM)和标识符(ID),ID和NUM通过以下正则表达式表示:ID = letter letter*NUM = digit digit*letter = a|..|z|A|..|Zdigit = 0|..|9除了记号之外,Tiny程序还要遵循以下的词法惯例:注释应放在花括号{...}中,且不可嵌套;代码应是自由格式;空白格由空格、换行符和制表符组成。
词法分析器生成工具lex使用

模式:letter {动作 letter的数目加一}
辅助函数:
%% void main() {
yylex(); /* start the analysis*/ printf("no of letter:%d",id_num); }
int yywrap(请刷新页面重试持续报错请尝试更换浏览器或网络环境
词法分析器生成工具 lex使用
一个lex程序具有如下形式:
声明部分:包括变量和明示常量,可以将一些c语言的东西写在%{....... %},并且可以在转换规则中调用
%{ #include <stdio.h> int id_num; /*常量量*/
%}
letter [A-Za-z] /*正则变量*/
start start
/*正则变量*/
stop stop /*正则变量*/
转换规则:通过在声明部分的正则变量,识别输入流中的单词,并可以执行一些动作
lex程序中的每个转换规则具有如下形式:
模式 {动作}
%% letter {id_num++;} start {printf("start received");} stop {printf("stop received");}
编译原理实验1词法分析器构造

《编译原理》课程实验报告实验一词法分析器构造专业班级:学生姓名:学生学号:一、实验目的和要求通过对给定源语言词法分析程序的设计,加深对词法分析原理的理解,掌握源语言的接收、存贮、预处理和扫描分析,生成正确的单词符号串二元式序列。
二、实验内容编程实现下述C语言子集的词法分析程序,C语言子集的文法描述如下:语句→赋值语句|条件语句|转移语句|带标号的赋值语句带标号的赋值语句→〈标号〉〈赋值语句〉赋值语句→变量=算术表达式条件语句→IF <布尔表达式> THEN 语句|IF <布尔表达式> THEN 语句ELSE语句转移语句→GOTO标号变量→标识符标识符→字母|<标识符><数字>字母→A|B|…|Z|a|b|…|z数字→0|1|…|9算术表达式→项|算术表达式+项|算术表达式-项项→因子|项*因子|项/因子|因子↑项因子→变量|常数|(表达式)布尔表达式→<算术表达式><关系符><算术表达式>关系符→>|<|>=|<=|=|<>标号→常数常数→数字|<常数><数字>对语言的几点限制:关键字不允许作为标识符使用。
关键字、标识符、常数、标号之间若没有确定的运算符或界符,则必须用空格符隔开。
源程序书写按C标准格式。
续行最多不得超过5行。
三、实验的实现1. 主要设计思想大体分为三个步骤:(1) 预处理用正则表达式去掉源文件中的注释,将’\’ 换行内容整理为一行,用split() 进行分割,使源文件变成一个一个的表达式。
(2) 识别对每一个表达式用正则表达式将表达式以符号分割,对分割出的每一项进行类型判断,打印结果并返回该表达式中的所有项的二元式组成的列表(3) 保存将之前的二元式列表合并后保存到文件中。
2. 实现算法及程序流程图3. 主要技术问题的处理方法(1) 开始时只能用正则表达式匹配单行注释,无法识别/* */之间有换行符的情况。
实验一词法分析器设计和Lex工具的使用

实验一词法分析器设计和Lex工具的使用一.实验目的:1、掌握词法分析器设计方法。
2、熟悉LEX工具的使用,理解LEX工具的工作原理和利用LEX工具设计词法分析器的方法。
二.实验内容(按以下实验内容完成1、3项中任意一项即可):1、在VC下打开阅读附件一mlex.dsw,阅读工程一mlex和mlex2源程序,mlex为课本P45词法分析器的实现,工程二mlex2采用另一种方式实现P45的状态转换图。
通过该例了解状态自动机的实现方法和手工编写词法分析器的基本方法。
Mlex词法分析器简单说明:功能:从左至右逐个字符地对c语言子集源程序src.txt进行扫描,产生单词符号流token.txt(参见课本,单词用二元组<单词种别,单词值>表示)。
程序框图:输入c语言子集源程序,为文本文件。
注意读到文件结束符EOF意味着分析结束。
输出词法分析程序的运行结果是:输出一个单词序列(屏幕显示或保存在文件中)和一个常数表、一个符号表(保存在文件中)、一个常数表(保存在文件中),并输出错误信息。
说明:单词序列:读入源程序,每从源程序中发现一个符号串构成一个单词,即输出一个二元式(单词种别,单词值)。
其中单词种别用整数说明。
标识符的单词值为其在符号表中的记录号。
非负整常数的单词值为其在常数表中的记录号。
符号表:存放标识符的具体信息,记录格式为(记录号,构成标识符的字符串)。
相同的标识符在符号表中只登录一个记录。
常数表:存放非负整数的具体信息,记录格式为(记录号,构成非负整数的字符串)。
相同的非负整数在符号表中只登录一个记录。
标识符的识别:见下例,分析abc后,应在符号表中登录一项(1,abc),并往单词序列中加一项(6,1),表示单词种别为标识符<6>,单词的具体信息见符号表第1个记录。
常数的识别:见下例,分析134后,应在常数表中登录一项(1,134),并往单词序列中加一项(7,1),表示单词种别为常数<7>,单词的具体信息见常数表第1个记录。
《C-语言的词法分析器(基于Lex)》课程设计报告

《C-语⾔的词法分析器(基于Lex)》课程设计报告《编译原理与实践》课程报告课题名称: C-语⾔的词法分析器实现(基于Lex)课题负责⼈名(学号):李恒(0643111198)同组成员名单(⾓⾊):⽆指导教师:于中华评阅成绩:评阅意见:提交报告时间:2007 年12 ⽉31⽇1. ⽬的与意义词法分析是编译原理中⼀个重要的部分。
它可将源程序读作字符⽂件并将其分为若⼲个记号,每⼀个记号都是表⽰源程序中信息单元的字符序列。
词法分析器是翻译步骤的第⼀步,它对于编译器接下来要进⾏的⼯作起着开头的作⽤,因此要想实现对C-语⾔的编译器,词法分析器必不可少。
2. 基于Parser Generator的词法分析器构造⽅法利⽤Parser Generator构造词法分析器规则,⽣成对应的c语⾔及其头⽂件。
然后进⾏编译。
3. C-语⾔词法分析的设计重要数据类型:关键字枚举:typedef enum{ENDFILE, ERROR,/* reserved words */ELSE, IF, INT, RETURN, VOID, WHILE,/* multicharacter tokens */ID, NUM,/* special symbols */PLUS, MINUS, TIMES, OVER, LT, LE, GT, GE, EQU, NEQU,ASSIGN, SEMI, COMMA, LPAREN, RPAREN, LBRKT, RBRKT, LBRC, RBRC, LCOM, RCOM}TokenType;关键字声明:digit [0-9]number {digit}+letter [a-zA-Z]identifier {letter}+newline \nwhitespace [ \t]+c-语⾔的词法规则:"else" {return ELSE;} "if" {return IF;}"int" {return INT;} "return" {return RETURN;} "void" {return VOID;} "while" {return WHILE;} "+" {return PLUS;} "-" {return MINUS;} "*" {return TIMES;} "/" {return OVER;} "<" {return LT;}"<=" {return LE;} ">" {return GT;}">=" {return GE;}"==" {return EQU;}"!=" {return NEQU;} "=" {return ASSIGN;} ";" {return SEMI;} "," {return COMMA;} "(" {return LPAREN;} ")" {return RPAREN;} "[" {return LBRKT;} "]" {return RBRKT;} "{" {return LBRC;} "}" {return RBRC;} {number} {return NUM;} {identifier} {return ID;} {newline} {lineNo++} {whitespace} {/* skip */} "/*" { char c;do{ c = input();if (c == EOF ) break;if (c == '\n' ) lineNo++;} while ( c != '/*');}{return ERROR;}重要处理程序设计:⽂件util.c执⾏输出结果的打印:void printToken(TokenType token, const char* tokenString) { switch (token){case ELSE:case IF:case INT:case RETURN:case VOID:case WHILE:fprintf(listing, "reserved word: %s\n", tokenString);break;case PLUS:fprintf(listing, "+\n");break;case MINUS:fprintf(listing, "-\n");break;case TIMES:fprintf(listing, "*\n");break;case OVER:fprintf(listing, "/\n");break;case LT:fprintf(listing, "<\n");break;case LE:fprintf(listing, "<=\n");break;fprintf(listing, ">\n"); break;case GE:fprintf(listing, ">=\n"); break;case EQU:fprintf(listing, "==\n"); break;case NEQU:fprintf(listing, "!=\n"); break;case ASSIGN: fprintf(listing, "=\n"); break;case SEMI:fprintf(listing, ";\n"); break;case COMMA: fprintf(listing, ",\n"); break;case LPAREN: fprintf(listing, "(\n"); break;case RPAREN: fprintf(listing, ")\n"); break;case LBRKT: fprintf(listing, "[\n"); break;case RBRKT: fprintf(listing, "]\n"); break;case LBRC:fprintf(listing, "{\n");case RBRC:fprintf(listing, "}\n");break;case LCOM:fprintf(listing, "/*\n");break;case RCOM:fprintf(listing, "*/\n");break;case ENDFILE:fprintf(listing,"EOF\n");break;case NUM:fprintf(listing, "NUM,val=%s\n",tokenString); break;case ID:fprintf(listing, "ID, name=%s\n",tokenString); break;case ERROR:fprintf(listing, "ERROR: %s\n",tokenString); break;default:break;}}函数getToken获取下⼀个token:TokenType getToken(void){ static int firstTime = TRUE; TokenType currentToken;if (firstTime){ firstTime = FALSE;lineNo++;yyin = source;yyout = listing;}currentToken = yylex();strncpy(tokenString,yytext,MAXTOKENLEN);if (TraceScan) {fprintf(listing, "\t%d: ", lineNo);printToken(currentToken,tokenString);}return currentToken;}4. 运⾏结果及分析输⼊⽂件如果所⽰:输出结果如图:对于输⼊的每⼀⾏进⾏词法分析,表⽰出保留字,标识符,以及终结符。
编译原理实验:C语言的Lex词法分析程序

%{#include <stdlib.h>#include <stdio.h>int ID = 0;intNumber_float = 0;int Number = 0;int STRING = 0;int CHAR = 0;int ERROR = 0;int OPERATOR = 0;intReserved_word = 0;int b = 0;int f = 0;%}hulue [\t\n ]capitalLetter [A-Z]smallLetter [a-z]writespace {hulue}+letter ({capitalLetter}|{smallLetter})digit [0-9]id (_|{letter})(_|{letter}|{digit})*number {digit}+float {digit}*(\.{digit}+)(E[+\-]?{digit}+)?tempChar1 [ -!#-~]tempChar2 [ -&(-~]char \'((\\{smallLetter})|({tempChar2}|(\\\')))\'string \"({tempChar1}|(\\\"))*\"%%{writespace} {}include {++Reserved_word; printf(" reserved word : %s\n", yytext);} stdio.h {++Reserved_word; printf(" reserved word : %s\n", yytext);} stdlib.h {++Reserved_word; printf(" reserved word : %s\n", yytext);} main {++Reserved_word; printf(" reserved word : %s\n", yytext);} auto {++Reserved_word; printf(" reserved word : %s\n", yytext);} break {++Reserved_word; printf(" reserved word : %s\n", yytext);} case {++Reserved_word; printf(" reserved word : %s\n", yytext);} char {++Reserved_word; printf(" reserved word : %s\n", yytext);} continue {++Reserved_word; printf(" reserved word : %s\n", yytext);}default {++Reserved_word; printf(" reserved word : %s\n", yytext);} const {++Reserved_word; printf(" reserved word : %s\n", yytext);} do {++Reserved_word; printf(" reserved word : %s\n", yytext);} double {++Reserved_word; printf(" reserved word : %s\n", yytext);} else {++Reserved_word; printf(" reserved word : %s\n", yytext);} enum {++Reserved_word; printf(" reserved word : %s\n", yytext);} extern {++Reserved_word; printf(" reserved word : %s\n", yytext);} float {++Reserved_word; printf(" reserved word : %s\n", yytext);}for {++Reserved_word; printf(" reserved word : %s\n", yytext);} goto {++Reserved_word; printf(" reserved word : %s\n", yytext);}if {++Reserved_word; printf(" reserved word : %s\n", yytext);}int {++Reserved_word; printf(" reserved word : %s\n", yytext);} long {++Reserved_word; printf(" reserved word : %s\n", yytext);} register {++Reserved_word; printf(" reserved word : %s\n", yytext);} return {++Reserved_word; printf(" reserved word : %s\n", yytext);} short {++Reserved_word; printf(" reserved word : %s\n", yytext);} signed {++Reserved_word; printf(" reserved word : %s\n", yytext);} sizeof {++Reserved_word; printf(" reserved word : %s\n", yytext);} static {++Reserved_word; printf(" reserved word : %s\n", yytext);} struct {++Reserved_word; printf(" reserved word : %s\n", yytext);} switch {++Reserved_word; printf(" reserved word : %s\n", yytext);} typedef {++Reserved_word; printf(" reserved word : %s\n", yytext);} union {++Reserved_word; printf(" reserved word : %s\n", yytext);} unsigned {++Reserved_word; printf(" reserved word : %s\n", yytext);} void {++Reserved_word; printf(" reserved word : %s\n", yytext);} volatile {++Reserved_word; printf(" reserved word : %s\n", yytext);} while {++Reserved_word; printf(" reserved word : %s\n", yytext);} scanf {++Reserved_word; printf(" reserved word : %s\n", yytext);} printf {++Reserved_word; printf(" reserved word : %s\n", yytext);}"(" { ++f; printf(" fengehao : %s\n", yytext);}")" { ++f; printf(" fengehao : %s\n", yytext);}":" { ++f; printf(" fengehao : %s\n", yytext);}";" { ++f; printf(" fengehao : %s\n", yytext);}"[" { ++f; printf(" fengehao : %s\n", yytext);}"]" { ++f; printf(" fengehao : %s\n", yytext);}"{" { ++f; printf(" fengehao : %s\n", yytext);}"}" { ++f; printf(" fengehao : %s\n", yytext);}"." {++OPERATOR; printf(" operator : %s\n", yytext);}"->" {++OPERATOR; printf(" operator : %s\n", yytext);}"++" {++OPERATOR; printf(" operator : %s\n", yytext);}"--" {++OPERATOR; printf(" operator : %s\n", yytext);}"~" {++OPERATOR; printf(" operator : %s\n", yytext);}"!" {++OPERATOR; printf(" operator : %s\n", yytext);}"-" {++OPERATOR; printf(" operator : %s\n", yytext);}"+" {++OPERATOR; printf(" operator : %s\n", yytext);}"*" {++OPERATOR; printf(" operator : %s\n", yytext);}"&" {++OPERATOR; printf(" operator : %s\n", yytext);}"/" {++OPERATOR; printf(" operator : %s\n", yytext);}"%" {++OPERATOR; printf(" operator : %s\n", yytext);}"<<" {++OPERATOR; printf(" operator : %s\n", yytext);}">>" {++OPERATOR; printf(" operator : %s\n", yytext);}">" {++OPERATOR; printf(" operator : %s\n", yytext);}"<" {++OPERATOR; printf(" operator : %s\n", yytext);}"<=" {++OPERATOR; printf(" operator : %s\n", yytext);}">=" {++OPERATOR; printf(" operator : %s\n", yytext);}"=" {++OPERATOR; printf(" operator : %s\n", yytext);}"==" {++OPERATOR; printf(" operator : %s\n", yytext);}"!=" {++OPERATOR; printf(" operator : %s\n", yytext);}"&&" {++OPERATOR; printf(" operator : %s\n", yytext);}"^" {++OPERATOR; printf(" operator : %s\n", yytext);}"|" {++OPERATOR; printf(" operator : %s\n", yytext);}"||" {++OPERATOR; printf(" operator : %s\n", yytext);}"," {++OPERATOR; printf(" operator : %s\n", yytext);}"*=" {++OPERATOR; printf(" operator : %s\n", yytext);}"-=" {++OPERATOR; printf(" operator : %s\n", yytext);}"+=" {++OPERATOR; printf(" operator : %s\n", yytext);}"&=" {++OPERATOR; printf(" operator : %s\n", yytext);}"/=" {++OPERATOR; printf(" operator : %s\n", yytext);}"<<=" {++OPERATOR; printf(" operator : %s\n", yytext);}"|=" {++OPERATOR; printf(" operator : %s\n", yytext);}">>=" {++OPERATOR; printf(" operator : %s\n", yytext);}"^=" {++OPERATOR; printf(" operator : %s\n", yytext);}"#" {++OPERATOR; printf(" operator : %s\n", yytext);}"/*"[^*]*[*]+([^*/][^*]*[*]+)*[*]*"/" {++b; printf(" C declaration : %s\n", yytext);}{number} {++Number; printf(" number : %s\n", yytext);}{float} {++Number_float; printf("float : %s\n", yytext);}{string} {++STRING; printf(" string : %s\n", yytext);}{char} {++CHAR; printf(" char : %s\n", yytext);}{id} {++ID; printf(" id : %s\n", yytext);}. {++ERROR; printf(" error : %s\n", yytext);}%%int main(){printf("----------------------press Ctrl + D to end input------------------------\n"); yylex();printf("-------------------------------------------------------------------------\n"); printf("number of reserved word : %d\n",Reserved_word);printf("number of id : %d\n",ID);printf("number of number : %d\n",Number);printf("number of float : %d\n",Number_float);printf("number of string : %d\n",STRING);printf("number of char : %d\n",CHAR);printf("number of error symbol : %d\n",ERROR);printf("number of operator : %d\n",OPERATOR);printf("number of fengefuhao : %d\n",f);printf("number of declaration : %d\n",b);return 0;}intyywrap(){return 1;}。
实验1:用lex构造c子集词法分析器

实验报告实验项目名称:用lex构造c子集词法分析器学时:2学时一.实验目的和要求用lex构造c子集词法分析器,能实现识别c子集源程序的单词序列。
二.实验环境VC/tc dos三.实验过程A:lex使用方法1在“运行“中输入:cmd进入dos环境2 进入LEX所在文件夹。
(cd 命令若LEX在f盘根目录下>f:>cd lex3 LEX使用步骤:(直接在屏幕显示词法分析结果,不保留的)1、编写LEX源程序,如“1.L”,将“1.L”与FLEX.EXE 保存在同一文件夹下。
2、进入DOS环境FLEX.EXE所在文件夹,运行FLEX.EXE程序。
FLEX 1.L3、运行FLEX后,产生“LEXYY.C”程序4、用VC打开“LEXYY.C”程序,编译后产生“LEXYY.EXE”程序。
5、进入DOS环境“LEXYY.EXE”所在文件夹,编写1.c程序,运行“LEXYY.EXE”程序。
>LEXYY.EXE 1.c 的结果。
1.L源程序:实现功能将所有小写字母转换成大写。
%{#include <stdio.h>%}%%[a-z] printf("%c",yytext[0]+'A'-'a'); %%main( argc, argv )int argc;char **argv;{++argv, --argc; /* skip over program name */if ( argc > 0 )yyin = fopen( argv[0], "r" );//yyin存放LEXYY的输入源程序elseyyin = stdin;++argv, --argc; /* skip over input name */if ( argc > 0 )yyout = fopen( argv[0], "w" );//yyout存放LEXYY的输出程序elseyyout = stdout;yylex();}int yywrap(){return 1;}B:构造c子集词法分析器1、编写c子集的LEX源程序,如“lex.L”,将“lex.L”与FLEX.EXE保存在同一文件夹下。
编译原理 利用lex生成c语言的词法分析程序 实验报告

《编译原理》课程实验报告题目利用lex生成c语言的词法分析程序专业班级学号姓名一. 实验题目利用lex生成c语言的词法分析程序二. 实验日期三. 实验环境(操作系统,开发语言)操作系统是Windows开发语言是C语言四. 实验内容(实验要求)利用flex,仿教材p227的pascal语言的词法分析程序,经过适当修改后,遵照教材p48-图4.1和p50-表4.1编写自己的类别码。
要求:1.生成的词法分析程序要求能够对给定的任意c程序进行词法分析,并生成文档输出。
2.词法分析程序能够识别关键字、运算符、分界符、标识符、常量(至少是整形常量,可以自己扩充识别其它常量)等,并能处理注释、部分复合运算符(如>=等)。
3.交 .l 文件,c源文件、输出分析结果文件及实验报告。
五. 实验步骤(1)遵照教材p48-图4.1和p50-表4.1,自己编写自己的类别编码。
(2)仿教材p227,pascal语言的词法分析程序,经过适当的修改后输入记事本中,保存格式为.l文件。
(3)在DOS环境下,利用flex运行.l文件,生成lex.yy.c文件。
(4)用c-free打开lex.yy.c文件,检查是否有错误并运行,生成lex.yy.exe 文件。
(5)可利用此程序运行任意的c程序进行词法分析。
六. 实验体会(包括收获、心得体会、存在的问题及解决问题的方法、建议等)1.此次实验让我进一步熟悉了词法分析程序lex的运用,熟悉了模式的运用方法及其格式的运用。
2.要使词法分析程序能够识别c程序中任意的关键字、运算符、分界符、标识符、常量,必须对这五类单词符号非常熟悉,因此还需要加强巩固c语言这方面的知识。
3.由于对pascal语言的陌生,在将代码修改为c语言的过程中,更多的只是跟着老师说的改,至于为什么这么改并不是很清楚,这其中一个原因是对各种模式的运用和理解的欠缺。
因此需要不断进行总结。
七. 实验结果(关键源代码)单词符号输出形式(表格)如下:。
编译原理lexyacc的联合使用实验报告(特选借鉴)

编译原理lexyacc的联合使用实验报告(特选借鉴)《编译原理》课程实验报告题目lex yacc 的联合使用专业班级学号姓名一. 实验题目lex yacc 的联合使用二. 实验日期三. 实验环境(操作系统,开发语言)操作系统是Windows开发语言是C语言四. 实验内容(实验要求)目的:熟悉lex和yacc的接口要求:(1)能对整数、实数进行带变量的四则运算(2)词法分析用lex实现(3)语法分析用yacc实现(4)交源代码和实验报告五. 实验步骤1.在实验二的基础上修改代码,并添加上以下的代码:double { return DOUBLE;}EOF { return 0;}{ID} { return ID;}2.在DOS环境下按照之前的步骤利用flex运行myleb.l,修改其中的错误之后,生成lex.yy.c文件。
3.参照书中第14章第7节和myparser-fifth.y文件中的代码,和老师说的思路修改myparser-sixth.y文件,按照实验要求修改代码。
4.在DOS环境下利用yacc运行myparser-sixth.y文件,会有出错提示,按照出错的地方指示,修改代码,使其最终能通过运行,生成y.tab.c文件。
(此步骤还未完成)5.打开c-free5.0,新建工程,在Source files文件夹中添加之前生成的lex.yy.c文件和y.tab.c文件,然后找到已给的calc.h文件,将其添加到新建工程中的Header files文件夹中,这时就能将三个文件组成一个类似于.exe文件类型的文件,最后运行。
6.运行并调试成功。
六. 实验体会(包括收获、心得体会、存在的问题及解决问题的方法、建议等)。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验报告实验项目名称:用lex构造c子集词法分析器学时:2学时一.实验目的和要求用lex构造c子集词法分析器,能实现识别c子集源程序的单词序列。
二.实验环境VC/tc dos三.实验过程A:lex使用方法1在“运行“中输入:cmd进入dos环境2 进入LEX所在文件夹。
(cd 命令若LEX在f盘根目录下>f:>cd lex3 LEX使用步骤:(直接在屏幕显示词法分析结果,不保留的)1、编写LEX源程序,如“1.L”,将“1.L”与FLEX.EXE 保存在同一文件夹下。
2、进入DOS环境FLEX.EXE所在文件夹,运行FLEX.EXE程序。
FLEX 1.L3、运行FLEX后,产生“LEXYY.C”程序4、用VC打开“LEXYY.C”程序,编译后产生“LEXYY.EXE”程序。
5、进入DOS环境“LEXYY.EXE”所在文件夹,编写1.c程序,运行“LEXYY.EXE”程序。
>LEXYY.EXE 1.c 的结果。
1.L源程序:实现功能将所有小写字母转换成大写。
%{#include <stdio.h>%}%%[a-z] printf("%c",yytext[0]+'A'-'a'); %%main( argc, argv )int argc;char **argv;{++argv, --argc; /* skip over program name */if ( argc > 0 )yyin = fopen( argv[0], "r" );//yyin存放LEXYY的输入源程序elseyyin = stdin;++argv, --argc; /* skip over input name */if ( argc > 0 )yyout = fopen( argv[0], "w" );//yyout存放LEXYY的输出程序elseyyout = stdout;yylex();}int yywrap(){return 1;}B:构造c子集词法分析器1、编写c子集的LEX源程序,如“lex.L”,将“lex.L”与FLEX.EXE保存在同一文件夹下。
2、运行FLEX.EXE程序。
3、运行FLEX后,产生“LEXYY.C”程序4、用VC打开“LEXYY.C”程序,编译后产生“LEXYY.EXE”程序。
5、编写一个c子集源程序A.c (每个人的源程序不相同)main(){int a;real b;a=2*32;b=3.124;}运行“LEXYY.EXE”程序。
>LEXYY.EXE A.c 看词法分析的结果。
四实验结果将词法分析的结果抄到实验报告五:错误分析由于该词法分析程序是分析c子集,case等关键字不能识别,字符型不能识别,部分运算符号和界符不能识别。
编写c源程序需注意c子集范围。
Lex1.L 源程序:%{#include <stdio.h>#ifndef FALSE#define FALSE 0#endif#ifndef TRUE#define TRUE 1#endif%}digit [0-9]number {digit}+letter [a-zA-Z]identifier {letter}+newline [\n]whitespace [ \t]+%%"main" printf("baoliuzi: %s\n", yytext);"if" printf("baoliuzi: %s\n", yytext);"else" printf("baoliuzi: %s\n", yytext);"for" printf("baoliuzi: %s\n", yytext);"while" printf("baoliuzi: %s\n", yytext);"do" printf("baoliuzi: %s\n", yytext);"int" printf("baoliuzi: %s\n", yytext);"=" printf("yunsuanfu: %s\n", yytext);"+" printf("yunsuanfu: %s\n", yytext);"-" printf("yunsuanfu: %s\n", yytext);"*" printf("yunsuanfu: %s\n", yytext);"/" printf("yunsuanfu:%s\n", yytext);"<" printf("yunsuanfu: %s\n", yytext);">" printf("yunsuanfu: %s\n", yytext);"(" printf("jiefu: %s\n", yytext);")" printf("jiefu: %s\n", yytext);"[" printf("jiefu: %s\n", yytext);"]" printf("jiefu: %s\n", yytext);"{" printf("jiefu: %s\n", yytext);"}" printf("jiefu: %s\n", yytext);";" printf("jiefu: %s\n", yytext);":" printf("jiefu: %s\n", yytext);"'" printf("jiefu: %s\n", yytext);"\"" printf("yunsuanfu: %s\n", yytext);"," printf("jiefu: %s\n", yytext);"==" printf("yunsuanfu: %s\n", yytext);">=" printf("yunsuanfu: %s\n", yytext);"<=" printf("yunsuanfu: %s\n", yytext);"!=" printf("yunsuanfu: %s\n", yytext);{number} printf("int: %s length:%d\n",yytext,yyleng); //求数字的长度{identifier} printf("id: %s\n",yytext);{whitespace} {/* skip whitespace */}"/*" { char c ;int done = FALSE;do{ while ((c=input())!='*');while ( (c=input()) == '*');if (c == '/') done = TRUE;} while (!done);}. {fprintf(yyout,"%s, %s\n", "ERROR",yytext);}%%main( argc, argv )int argc;char **argv;{++argv, --argc; /* skip over program name */if ( argc > 0 )yyin = fopen( argv[0], "r" );//yyin存放LEXYY的输入源程序elseyyin = stdin;++argv, --argc; /* skip over input name */if ( argc > 0 )yyout = fopen( argv[0], "w" );//yyout存放LEXYY的输出程序elseyyout = stdout;yylex();}int yywrap(){return 1;}思考题:1该源程序中只给出了标识符符定义为字母,如何将规则改为识别字母数字的?2 参照整型变量的定义,怎样将实型变量定义出来?3 完善定义部分。
附录:若需要将词法分析器结果作为文件保留起来的,则需要修改程序LEX使用步骤:(需要将词法分析器结果保留起来的)1、编写LEX源程序,如“Cffx.l”,将“Cffx.l”与FLEX.EXE保存在同一文件夹下。
2、进入DOS环境FLEX.EXE所在文件夹,运行FLEX.EXE程序。
FLEX cffx.l3、运行FLEX后,产生“LEXYY.C”程序4、用VC打开“LEXYY.C”程序,编译后产生“LEXYY.EXE”程序。
5、编写C子集语言源程序,保存为A.TEST,并与“LEXYY.EXE”保存在同一文件夹下。
6、进入DOS环境“LEXYY.EXE”所在文件夹,运行“LEXYY.EXE”程序。
>LEXYY.EXE A.TEST B.TXT7、打开“B.TXT”,看词法分析的结果。
Cffx.l源程序:%{#include <stdio.h>#ifndef FALSE#define FALSE 0#endif#ifndef TRUE#define TRUE 1#endif%}digit [0-9]number {digit}+letter [a-zA-Z]identifier {letter}+newline [\n]whitespace [ \t]+%%"if" {fprintf(yyout,"%s %s\n", yytext,yytext);} "else" {fprintf(yyout,"%s %s\n", yytext,yytext);} "for" {fprintf(yyout,"%s %s\n", yytext,yytext);} "while" {fprintf(yyout,"%s %s\n", yytext,yytext);} "do" {fprintf(yyout,"%s %s\n", yytext,yytext);} "int" {fprintf(yyout,"%s %s\n", yytext,yytext);} "=" {fprintf(yyout,"%s %s\n", yytext,yytext);}"+" {fprintf(yyout,"%s %s\n", yytext,yytext);} "-" {fprintf(yyout,"%s %s\n", yytext,yytext);}"*" {fprintf(yyout,"%s %s\n", yytext,yytext);}"/" {fprintf(yyout,"%s %s\n", yytext,yytext);}"<" {fprintf(yyout,"%s %s\n", yytext,yytext);} ">" {fprintf(yyout,"%s %s\n", yytext,yytext);} "(" {fprintf(yyout,"%s %s\n", yytext,yytext);}")" {fprintf(yyout,"%s %s\n", yytext,yytext);}"[" {fprintf(yyout,"%s %s\n", yytext,yytext);}"]" {fprintf(yyout,"%s %s\n", yytext,yytext);}"{" {fprintf(yyout,"%s %s\n", yytext,yytext);}"}" {fprintf(yyout,"%s %s\n", yytext,yytext);}";" {fprintf(yyout,"%s %s\n", yytext,yytext);}":" {fprintf(yyout,"%s %s\n", yytext,yytext);}"'" {fprintf(yyout,"%s %s\n", yytext,yytext);} "\"" {fprintf(yyout,"%s %s\n", yytext,yytext);} "," {fprintf(yyout,"%s %s\n", yytext,yytext);}"==" {fprintf(yyout,"%s %s\n", yytext,yytext);}">=" {fprintf(yyout,"%s %s\n", yytext,yytext);}"<=" {fprintf(yyout,"%s %s\n", yytext,yytext);}"!=" {fprintf(yyout,"%s %s\n", yytext,yytext);}{number} {fprintf(yyout,"%s %s\n", "NUM",yytext);}{identifier} {fprintf(yyout,"%s %s\n", "ID",yytext);}{whitespace} {/* skip whitespace */}"/*" { char c ;int done = FALSE;do{ while ((c=input())!='*');while ( (c=input()) == '*');if (c == '/') done = TRUE;} while (!done);}. {fprintf(yyout,"%s, %s\n", "ERROR",yytext);}%%main( argc, argv )int argc;char **argv;{++argv, --argc; /* skip over program name */if ( argc > 0 )yyin = fopen( argv[0], "r" );//yyin存放LEXYY的输入源程序elseyyin = stdin;++argv, --argc; /* skip over input name */if ( argc > 0 )yyout = fopen( argv[0], "w" );//yyout存放LEXYY的输出程序elseyyout = stdout;yylex();}int yywrap(){return 1;}。