设计 词法分析之基于lex实现词法分析
编译原理 利用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语言的过程中,更多的只是跟着老师说的改,至于为什么这么改并不是很清楚,这其中一个原因是对各种模式的运用和理解的欠缺。
因此需要不断进行总结。
七. 实验结果(关键源代码)单词符号输出形式(表格)如下:。
基于LEX语言的词法分析程序自动构造过程

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

第2章 词法分析 %{ #include "stdio.h" int linenum;
%}
int float %% {int} {float} . %% printf("Int : %s\n",yytext); [0-9]+ [0-9]*\.[0-9]+
printf("Float : %s\n",yytext); printf("Unknown : %c\n",yytext[0]);
16 letter (letter∣digit)*
{return (16,null);return (id) };
else return (keyword (id)) } 17 digit (digit)* {val=int (id); return (17, null); return (val)}
第2章 词法分析
词法分析器的工作过程
输入流 词法分析器(Scanner) DFA TokenList
error
NFA
词法描述(正则表达式)
第2章 词法分析
词法分析器的设计
人工构造词法分析器过程: 1.确定词法分析器的接口,即确定词法分析 器是作为语法分析的一个子程序还是作为 独立一遍。 2.确定单词分类和Token结构。 3.根据2步,构造每一类单词的描述 正则表达式NFADFA。 4.根据3步设计算法实现DFA。 利用工具自动生成:ScanGen Lex
第2章 词法分析
LEX是由美国Bell实验室的M.Lesk和Schmidt于1975 年用C语言研制的一个词法分析程序的自动生成工具。 对任何高级程序语言,用户必须用正规表达式描述该 语言的各个词法类(这一描述称为LEX的源程序), LEX就可以自动生成该语言的词法分析程序。LEX及 其编译系统的作用如图2–29所示。
基于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]+`表示忽略空格和换行符;`.`表示匹配到了其他未定义的字符,就打印出异常信息。
基于某flex地词法分析报告器地设计和实现

课程设计1 基于Flex的词法分析器设计及实现1.1 需求分析1.1.1 问题定义1、通过对 flex 基本知识的阅读,了解其工作原理和过程以及其匹配模式和规则,掌握简单的 lex 语法和规则;2、在上述基础上能够自主编写出简单且可以运行的词法分析器,实现简单的词法分析功能;3、通过实验,设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解,并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。
1.1.2 功能描述本次编制调试的词法分析器基本可以实现如下简单功能:1、可以匹配识别关键字:else if switch for int float return void while (所有的关键字都是保留字,并且必须是小写);2、可以匹配识别专用符号: + - * / < <= > >= == != = ; ,( ) [ ] { } /* */;3、标识符(ID)和数字(NU )通过下列正则表达式定义: ID = letter letter* NUM = digit digit* letter = a|..|z|A|..|Z digit = 0|..|9;4、可以匹配识别空格(空格由空白、换行符和制表符组成,空格通常被忽略,除了它必须分开 ID、NUM 关键字);5、可以识别简单的注释(/* 注释内容*/);1.1.3 开发环境及工具介绍1、Window环境下载Visual Studio之后,利用其命令提示窗口进行操作。
下载并安装Flex。
2、vs2010的编译器cl.exe。
3、flex:词法分析器Flex是用来生成程序的工具,他们所生成的程序能够处理结构化输入,最初的Flex是用来生成编译器的,但是后来他们被证明在其他领域也非常有效。
Flex是一个SourceForge项目。
其依赖于GNU m4宏处理器。
Linux和BSD都应该有m4,对于Windos用户来说,Flex被包含在Cygein Linux模拟环境中。
词法分析程序的设计与实现

词法分析程序的设计与实现方法1:采用C作为实现语言,手工编制一.文法及状态转换图1.语言说明:C语言有以下记号及单词:(1)标识符:以字母开头的、后跟字母或数字组成的符号串。
(2)关键字:标识符集合的子集,该语言定义的关键字有32个,即auto,break,case,char,const,continue,default,do,double,else,enum, extern,float,for,goto,if,int,long,register,return,short,signed,static, sizeof,struct,switch,typedef ,union,unsigned ,void, volatile和while。
(3)无符号数:即常数。
(4)关系运算符:<,<=,==,>,>=,!=。
(5)逻辑运算符:&&、||、!。
(6)赋值号:=。
(7)标点符号:+、++、-、--、*、:、;、(、)、?、/、%、#、&、|、“”、,、.、{}、[]、_、^等(8)注释标记:以“/*”开始,以“*/”结束。
(9)单词符号间的分隔符:空格。
2.记号的正规文法:仅给出各种单词符号的文法产生式(1)标识符的文法id->letter ridrid->ε|letter rid|digit rid(2)无符号整数的文法digits->digit remainderremainder->ε|digit remainder(3)无符号数的文法num->digit num1num1->digit num1|. num2|E num4|εnum2->digit num3num3->digit num3|E num4|εnum4->+digits|-digits|digit num5digits->digit num5num5->digit num5|ε(4)关系运算符的文法relop-> <|<=|==|>|>=|!=(5)赋值号的文法assign_op->=(6)标点符号的文法special_symbol->+|-|*|%|#|^|(|)|{|}|[|]|:|;|”|?|/|,|.& (7)逻辑运算符的文法logic->&&| || | !(8)注释头符号的文法note->/starstar->*3.状态转换图其中,状态0是初始状态,若此时读入的符号是字母,则转换到状态1,进入标识符识别过程;如果读入的是数字,则转换到状态2,进入无符号数识别过程;……;若读入的符号是/,转换到状态11,再读入下一个符号,如果读入的符号是*,则转换到状态12,进入注释处理状态;如果在状态0读入的符号不是语言所定义的单词符号的开始字符,则转换到状态13,进入错误处理状态。
LEX简介及TEST语言词法分析程序的LEX实现

17 23
digit [0-9] number {digit}+ letter [a-zA-Z] identifier {letter}+ newline [\n] whitespace [ \t]+
使用LEX生成TEST语言的词法分析程序
使用LEX生成TEST语言的词法分析程序
19 23
"(" {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);}
词法分析器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, ';'}
设计2词法分析之基于Lex实现词法分析报告

词法分析程序一、设计目的通过编写并上机调试一个词法分析程序,掌握在对程序设计语言的源程序进行扫描的过程中,将其分解成各类单词的词法分析方法。
二、设计要求要求将用模拟语言书写的源程序进行词法分析,输出源程序清单,Token文件和错误信息文件,若有错误,必须输出错误在源程序中行号和列号,并将符号表和字符串以文件的形式写出来。
三、设计说明基于Parser Genarator的词法分析器构造方法。
Lex输入文件由3个部分组成:定义集(definition),规则集(rule)和辅助程序集(auxiliary routine)或用户程序集(user routine)。
这三个部分由位于新一行第一列的双百分号分开,因此,Lex输入文件的格式如下{definitions}%%{rules}%%{auxiliary routines}而且第一部分用“%{”和“%}”括起来。
第一和第三个部分为C语言的代码和函数定义,第二个部分为一些规则。
3.1正规式定义定义正则表达式如下ID = letter letter*NUM = digit digit*Letter = a|…|z|A|…|ZDigit = 0|…|9Keyword = else|if|int|return|void|whileSpecial symbol = +|-|*|/|<|<=|>|>=|==|!=|=|;|,|(|)|[|]|{|}|/*|*/ White space = “ ”Enter = \n在lex中的构造letter [A-Za-z]digit [0-9]id ({letter}|[_])({letter}|{digit}|[_])*error_id ({digit})+({letter})+num {digit}+whitespace [ \t]+enter [\n]+3.2转换规则定义在Lex中的规则定义构造定义识别保留字规则"int"|"else"|"return"|"void"|"if"|"while"{Upper(yytext,yyleng);printf("%d 行 ",lineno);printf("%s reserved word\n",yytext);}//保留字定义识别数字规则{num}{printf("%d 行 ",lineno);printf("%s NUM\n",yytext);}//数字定义识别专用符号规则","|";"|"("|")"|"{"|"}"|"*"|"/"|"+"|"-"|">"|"<"|">="|"<="|"=="|" !="|"="|"/*"|"*/"{printf("%d 行 ",lineno);printf("%s special symbol\n",yytext);}//特殊符号定义识别标识符规则{id}{printf("%d 行 ",lineno);printf("%s ID\n",yytext);}//标识符定义识别错误的字符串规则当开头为数字的后面为字母的字符串时,是错误的标识符。
CH03--词法分析-LEX

a
2 b b
abb
开始
3
a
4 a
5
6
b b 8
{a}*b{b}*
Wensheng Li BUPT
开始
7
15
合并为一个NFA M
开始
1 3 7
a a a b
2 4 b 8 b
0
5
b
6
Wensheng Li BUPT
16
将该NFA M确定化为DFA D
DFA D=({a,b},{A,B,C,D,E,F},A,{B.C.E.F},) 其中:A={0,1,3,7} B={2,4,7} C={8} D={7} E={5,8} F={6,8}
Wensheng Li BUPT
18
Wensheng Li BUPT
4
2.翻译规则
形式:
P1 P2 … Pn { 动作1 } { 动作2 } { 动作n }
Pi 是一个正规表达式,描述一种记号的模式。 动作i 是C语言的程序语句,表示当一个串匹配模式 Pi时,词法分析器应执行的动作。
5
Wensheng Li BUPT
3.辅助过程
Wensheng Li BUPT
7
相应的 LEX 源程序 框架
/* 说明部分 */ %{ #include <stdio.h> /* C语言描述的标识符常量的定义,如 LT、LE、EQ、NE、GT、 GE、IF、THEN、ELSE、ID、NUMBER、RELOP */ extern yylval; %} /* 正规定义式 */ delim [ \t\n] ws {delim}+ letter [A-Za-z] digit [0-9] id {letter}({letter}|{digit})* num {digit}+(\.{digit}+)?(E[+\-]?{digit}+)? %%
实验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保存在同一文件夹下。
第6讲 词法分析程序自动生成--LEX

词法分析程序自动生成--LEX
正规式、正规集、DFA
DIM,IF, DO,STOP,END number, name, age 125, 2169 …
DIM IF DO STOP END letter(letter|digit)* digit(digit)*
FA
正规集
DFA
正规式
NFA
易于人工设计
视频区域DFAຫໍສະໝຸດ 词法分析器的自动产生--LEX
LEX源程序 lex.l
LEX编译器
(FLEX)
词法分析程序 lex.yy.c
词法分析程序 lex.yy.c
输入串
C编译器
词法分视析频程区域序
lex.out/lex.exe
词法分析程序
控制执行程序 状态转换矩阵
单词符号
词法分析器的自动产生--LEX
AUXILIARY DEFINITION
12 ,
{ RETURN (12,-) }
13 (
{ RETURN (13,-) }
14 )
{ RETURN (14,-) }
词法分析器的自动产生--LEX
LEX的工作过程
对每条识别规则Pi构造一个相应的
非确定有限自动机Mi;
X
ε ε
引进一个新初态X,通过ε弧,将这 ε …
些自动机连接成一个新的NFA;
把M确定化、最小化,生成该DFA
的状态转换表和控制执行程序
FA
正规集
DFA
M1
P1
视M频2 区域 P2
…
…
Mm
Pm
DFA
正规式
NFA
6 letter(letter|digit)* { RETURN (6, TOKEN) }
实验四 Lex词法分析

实验四Lex词法分析1、实验目的和要求通过编制词法分析程序,分析理解一个教学型编译程序的基础上,对其词法分析程序进行部分修改扩充,以加强课堂学习的有关概念和方法,并真正了解词法分析的实质内容。
要求择一种熟悉的高级语言,编制词法分析程序。
2、实验内容定义模拟的简单语言的词法构成,编制词法分析程序,要求将用模拟语言书写的源程序进行词法分析,输出源程序清单,Token文件和错误信息文件,若有错误,必须输出错误在源程序中行号和列号,并将符号表和字符串以文件的形式写出来。
3、实验仪器4、实验学时学习工具flex有详细的使用说明。
想查的话在Linux/Cygwin的控制台里敲man flex 不过在控制台里一页一页的看很烦人,不如敲man flex>flextut.txt 然后用UltraEdit慢慢看。
另外,网上关于flex使用的文章很多。
至于C#Lex,相关的文章不多,遇到问题可以找有关JLex的文档。
写脚本把代码转成Html源文件的第一步应该是替换特殊字符,看看用flex怎么写。
%option noyywrap%%" " {printf(" ");}"<" {printf("<");}">" {printf(">");}"\n" {printf("<br>");}"\t" {printf(" ");}%%int main(){printf("<FONT face=\"Courier New\" size=2>");yylex();printf("</FONT>");}flex的输入文件(.l)文件由%%分成了三部分,大致上可以把他们看作是函数(yylex( ))前,函数内和函数后。
词法分析器(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的C语言词法分析器组长:辛敏(00947042)组员:斯琴(00947035)宗华(00947003)张俊(00947068)刘中文(00947047)一、实验目的了解词法分析器生成工具LEX,利用词法分析自动构造工具构造一个识别C 语言的词法分析程序,了解LEX工具的基本运用,巩固有关正则表达式的知识。
二、实验设计1、LEX的配置过程<1>、总体环境配置:工具->选项->目录<2>执行具体程序时配置:工程->设置->Win32 Debug<3>执行具体程序时配置:工程->设置->Win32 Release2、基于C语言单词的归类设计如下正则表达式:<1>、空格:delim [ \t]<2>、换行:newline [\n]<3>、注释:zhush:(\/\*[^*]*\*+([^/]*\*+)*\/)|(\/\/(.)*)<4>、浮点型:Float:[-+]?(([0-9]+\.[0-9]*)|([0-9]*\.[0-9]+))[fF]<5>、double型:Double:[-+]?(([0-9]+\.[0-9]*)|([0-9]*\.[0-9]+))([dD]?)<6>关键字:Guanjianzi:"auto"|"break"|"case"|"char"|"const"|"continue"|"default"|"do"|"double"|"else"|"enum"|"extern"|"floa"|"for"|"goto"|"if"|"int"|"long"|"register"|"return"|"short"|"signed"|"sizeof"|"static"|"struct"|"switch"|"typedef"|"unsigned"|"void"|"while"<7>字符串:Zifucuan : \"[^"]*\"<8>字符:Zifu: \'[^']\'<9>标识符:Biaozifu:[a-zA-Z][a-zA-Z0-9]*<10>关系运算符:guanxiYunsuanfu:"~"|"("|")"|"["|"]"|"->"|">>"|"<<"|">"|"<"<11>算数运算符:suanshuyunsuanfu :"++"|"--"|"*"|"/"|"%"|"+"|"-"|"^"<12>逻辑运算符:luojiYunsuanfu :"&&"|"||"|"|"|"&"|"!"<13>条件运算符: tiaojieYunsuanfu:":"|"?"<14>赋值运算符:fuzhiyunsuanfu: ">="|"<="|"=="|"!="|"+="|"-="|"*="|"/="|"%="|">>="|"<<="|"&="|"^="|"="<13>八进制:Bajizhi:0([-+]?)[0-7]+<14>无符号数:Wufuhao :[0-9]+[uU]<15>十六进制:Shiliujinzhi 0[xX]([-+]?)[a-fA-F0-9]+<16>分界符:Fengefu:[;,]<17>标识符错误:error1:({digit})+({letter})+<18>中文;与,识别错误:Error2 :";"|","3、定义识别规则delim {;}newline {printf("\n");}{Zhengshu} {if(process()) printf("整数:%s\t",yytext);}{Error2} {printf("符号错误-中文符号:%s\t",yytext);} {Fengefu} {printf("分隔符:%s\t",yytext);}{Zhushi} {printf("注释:%s\t",yytext);}{Zhizhen} {if(process()) printf("字符串指针:%s\t",yytext);} {Kexuejishu} {if(process()) printf("科学计数法:%s\t",yytext);} {Float} {if(process()) printf("float型:%s\t",yytext);} {Double} {if(process()) printf("double型:%s\t",yytext);}{Bajizhi} {if(process()) printf("八进制整数:%s\t",yytext);} {Wufuhao} {if(process()) printf("无符号整数:%s\t",yytext);} {Shiliujinzhi} {if(process()) printf("十六进制整数:%s\t",yytext);}{Zifucuan} {printf("字符串常量:%s\t",yytext);}{Zifu} {printf("字符常量:%s\t",yytext);}{Guanjianzi} {printf("关键字:%s\t",yytext);}{Error1} {printf("错误词性:%s\t",yytext);}{Biaozifu} {if(process()) printf("标识符:%s\t",yytext);} {suanshuYunsuanfu} {printf("算数运算符:%s\t",yytext);} {guanxiYunsuanfu} {printf("关系运算符运算符:%s\t",yytext);} {luojiYunsuanfu} {printf("逻辑运算符:%s\t",yytext);} {tiaojieYunsuanfu} {printf("条件运算符:%s\t",yytext);} {fuzhiYunsuanfu} {printf("赋值运算符:%s\t",yytext);}4、判断数据长度是否超出范围的函数int process(){char *c=yytext;//strcpy_s(c,yytext);//printf("该数据长度为:%d\t",strlen(c));if(strlen(c)>20){printf("该数据长度超出范围:%s\t",c);return 0;}elsereturn 1;}三、测试过程1、测试例void main(){int a=12;double b=-23.3d;int c=3.4e3;float d=3.14f;folat e=+34l;int f=23,44;int h=0xa8;char ch='k';char chsdddddddddddddddddddddddddd='t'; //错误:长度超出范围if(a==39)a++;elsechar *t="ddhgfdd";for(int r=0;r<a;r++){a--;}d=d-1; //分号错误}/*此为注释*/2、测试结果四、各自的贡献斯琴(00947035)、宗华(00947003)收集资料,熟悉lex的使用。
实验一词法分析器设计和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个记录。
实验二 词法分析lex实验报告

void main() { yylex(); return 0; } int yywrap() { return 1;
/* start the analysis*/
}Leabharlann 编制一个读单词过程从输入的源程序中识别出各个具有独立意义的单词token即基本保留字标识符常量运算符分隔符五大类并依次输出各个单词的内部编码及单词符号自身值
《实验一
词法分析》实验报告
题目
词法分析
日期 2012-10-28
姓名及 (组长)康黎明 swe10029 分工
组员: 陈俊杰 swe10031 组员: 许冬青 swe10033 组员:王吉 swe10028
四、源程序:
%{ int yywrap();
int lineno=1; %} delim [ \t] ws {delim}+ letter [A-Za-z] digit [0-9] id {letter}({letter}|{digit})* number {digit}+ error_id ({digit})+({letter})+ enter [ \n] spchar ("{"|"}"|"["|"]"|"("|")"|";"|"="|",") ariop ("+"|"-"|"*"|"/") relop ("<"|"<="|">"|">="|"=="|"!=") comment \/\*(\*[^/]|[^*])*\*\/ reswd (int|else|return|void|if|while|main)
《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. 运⾏结果及分析输⼊⽂件如果所⽰:输出结果如图:对于输⼊的每⼀⾏进⾏词法分析,表⽰出保留字,标识符,以及终结符。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
词法分析程序
一、设计目的
通过编写并上机调试一个词法分析程序,掌握在对程序设计语言的源程序进行扫描的过程中,将其分解成各类单词的词法分析方法。
二、设计要求
要求将用模拟语言书写的源程序进行词法分析,输出源程序清单,Token文件和错误信息文件,若有错误,必须输出错误在源程序中行号和列号,并将符号表和字符串以文件的形式写出来。
三、设计说明
基于Parser Genarator的词法分析器构造方法。
Lex输入文件由3个部分组成:定义集(definition),规则集(rule)和辅助程序集(auxiliary routine)或用户程序集(user routine)。
这三个部分由位于新一行第一列的双百分号分开,因此,Lex输入文件的格式如下
{definitions}
%%
{rules}
%%
{auxiliary routines}
而且第一部分用“%{”和“%}”括起来。
第一和第三个部分为C语言的代码和函数定义,第二个部分为一些规则。
3.1正规式定义
定义正则表达式如下
ID = letter letter*
NUM = digit digit*
Letter = a|…|z|A|…|Z
D igit = 0|…|9
Keyword = else|if|int|return|void|while
Special symbol = +|-|*|/|<|<=|>|>=|==|!=|=|;|,|(|)|[|]|{|}|/*|*/
White space = “ ”
Enter = \n
在lex中的构造
letter [A-Za-z]
digit [0-9]
id ({letter}|[_])({letter}|{digit}|[_])*
error_id ({digit})+({letter})+
num {digit}+
whitespace [ \t]+
enter [\n]+
3.2转换规则定义
在Lex中的规则定义构造
定义识别保留字规则
"int"|"else"|"return"|"void"|"if"|"while"
{Upper(yytext,yyleng);
printf("%d 行 ",lineno);
printf("%s reserved word\n",yytext);}//保留字
定义识别数字规则
{num}
{printf("%d 行 ",lineno);
printf("%s NUM\n",yytext);}//数字
定义识别专用符号规则","|";"|"("|")"|"{"|"}"|"*"|"/"|"+"|"-"|">"|"<"|">="|"<="|"=="|"!="|"="|"/*"|"*/" {printf("%d 行 ",lineno);
printf("%s special symbol\n",yytext);}//特殊符号
定义识别标识符规则
{id}
{printf("%d 行 ",lineno);
printf("%s ID\n",yytext);}//标识符
定义识别错误的字符串规则
当开头为数字的后面为字母的字符串时,是错误的标识符。
{error_id}
{printf("error:%s\n",yytext);}//以数字开头的字符自动报错
定义忽略空格规则
{whitespace}
{/* skip whitespace */}//忽略空格
定义忽略回车规则
{enter}
{lineno++;}//遇到回车自动加行号忽略
3.3辅助程序
辅助程序集中包括
主函数main ()和辅助函数toupper()。
3.3程序代码实现
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int yywrap();
int lineno=1;
%}
delim [ \t]
ws {delim}+
letter [A-Za-z]
digit [0-9]
id {letter}({letter}|{digit})*
number {digit}+
error_id ({digit})+({letter})+
enter [ \n]
spchar ("{"|"}"|"["|"]"|"("|")"|";"|"="|",")
ariop ("+"|"-"|"*"|"/")
relop ("<"|"<="|">"|">="|"=="|"!=")
comment \/\*(\*[^/]|[^*])*\*\/
reswd (int|else|return|void|if|while)
%%
{ws} {}
{comment} {}
{enter} {lineno++;}
{reswd} {fprintf(yyout,"%d行\tkeywod\t%s\n",lineno,yytext);} {spchar} {fprintf(yyout,"%d行\tspchar\t%s\n",lineno,yytext);} {id} {fprintf(yyout,"%d行\tidentifier\t%s\n",lineno,yytext);} {number} {fprintf(yyout,"%d行\tnumber\t%s\n",lineno,yytext);} {error_id} {fprintf(yyout,"%d行\terror_id\t%s\n",lineno,yytext);} {ariop} {fprintf(yyout,"%d行\tari_op\t%s\n",lineno,yytext);} {relop} {fprintf(yyout,"%d行\trel_op\t%s\n",lineno,yytext);}
%%
int yywrap() {return 1;}
int main(void)
{
char infilename[100];
printf("输入文件名:");
scanf("%s",infilename);
yyin = fopen(infilename,"r");
yyout = fopen("out","w");
yylex();
return 0;
}
四、运行结果及分析
测试的C语言代码:
测试结果:
测试的C语言代码:
测试结果:
测试代码:
测试结果:
五、总结
通过本次课程设计的练习,学会运用Lex自动构造词法分析器,学会了基于Parser Genarator的词法分析器构造方法。
掌握了词法分析器的原理以及功能。
词法分析是编译过程中的一个阶段,在语法分析前进行。
也可以和语法分析结合在一起作为一遍,由语法分析程序调用词法分析程序来获得当前单词供语法分析使用。
词法分析程序的主要任务:读源程序,产生单词符号。
词法分析程序的其他任务:滤掉空格,跳过注释、换行符追踪换行标志,复制出错源程序,宏展开,等等等等。
词法分析工作从语法分析工作独立出来的原因:简化设计,改进编译效率,增加编译系统的可移植性。
而且从划分关键字,运算符,界符,标识符和常量,才发现数字,字母及符号组合有很多很多,无法全部枚举,所以在新建的文本文档中只象征性的列出几种符号,但这并不影响此法分析结果的完成。
总之,通过本次实验,一点点分析词法分析器的功能,并努力实现它,掌握了课程设计内容的
同时也锻炼了自己分析解决问题的能力以及编程能力,收获颇丰!。