文档库 最新最全的文档下载
当前位置:文档库 › 词法分析

词法分析

词法分析
词法分析

一、设计概述(设计目的、环境、要求)

1、设计目的

本次课程设计的目的是通过使用一个通用的能够自动根据正规表达式生成词法分析程序的工具程序设计一个简单语言的词法分析器,使学生充分理解课程理论内容和工具软件的使用技巧,掌握所涉及的典型数据结构,算法及方法,为今后在大型软件系统实践中设计性能优良的软件系统打下基础。

2、设计环境

实验环境为Windows操作系统下,词法分析使用的主要工具是flex。

3、设计要求

使用Flex工具,实现Decaf语言词法分析工作,对Decaf语言编写的源程序从左至右逐个字符进行扫描,产生一个单词序列。

二、实验步骤(包括基本程序的分析步骤、测试的例子)

1、编写程序的分析步骤

(1)根据pp2所提供的scanner.l文件修改我们所需的词法分析程序scanner.l。

/*

*scanner.l

*

* Flex输入文件,生成scanner

*/

%{

#include

#include

#include

#include

#include

#include "scanner.h"

#include "hashtable.h"

#include "utility.h"

#include

/*

*Global variable: yylval

*-----------------------

*全局变量,我们可以从yylval中获得每个token的属性。

*以后这个变量由bison/yacc自动生成,在这个实验里面,我们手动定义。

*/

YYSTYPE yylval;

/*

*Global variable: yylloc

*-----------------------

*全局变量,我们可以从yylloc中获得每个token的位置属性。

*以后也由bison/yacc自动生成。

*/

struct yyltype yylloc;

static int curLineNum, curColNum;

static char curLine[512];

static void DoBeforeEachAction();

#define YY_USER_ACTION DoBeforeEachAction();

Hashtable hasht;

%}

%option stack

%s N C

%x COPY

/*

*在这里定义你的辅助定义和开始条件

*/

decimal [0-9]

HEX_decimal ({decimal}|[a-fA-F])+

HEX_INTEGER 0[Xx]{HEX_decimal}+

INTEGER {decimal}+

EXPONENT [Ee][-+]{INTEGER}

DOUBLE ({INTEGER}("."){decimal}*{EXPONENT}?)

BEG_STRING (\"[^"\n]*)

STRING ({BEG_STRING}\")

IDENTIFIER ([a-zA-Z][a-zA-Z0-9_]*)

OPERATOR [+\-*/%=<>\\,.;!(){}\[\]]

BEG_COMMENT ("/*")

END_COMMENT ("*/")

SINGLE_COMMENT ("//"[^\n]*)

WHITE [ \t]*

/*

*以下是你的识别规则(patten&action)。

* 注意空格问题和括号\引号匹配问题,一旦出错很难查出。

*/

%%

.* { strncpy(curLine, yytext, sizeof(curLine));

curColNum = 1;

yy_pop_state(); yyless(0); }

<> { yy_pop_state();}

<*>\n { curLineNum++; curColNum = 1;

if (YYSTATE != COPY) yy_push_state(COPY); } {WHITE} { /* ignore space & tabs in normal or comment */ } /* -------------------- Comments ----------------------------- */

{BEG_COMMENT} { yy_push_state(C); }

{END_COMMENT} { yy_pop_state(); }

<> { ReportError(&yylloc,

"Input ends with unterminated comment.");

return 0; }

[^*\n/]* { /* grab all non-star, non-slash, non-newline */} . { /* ignore everything else that doesn't match */ } {SINGLE_COMMENT} { /* skip to end of line for // comment */ }

/* --------------------- Keywords ------------------------------- */

"void" { return T_Void; }

"int" { return T_Int; }

"double" { return T_Double; }

"bool" { return T_Bool; }

"string" { return T_String; }

"class" { return T_Class; }

"extends" { return T_Extends; }

"this" { return T_This; }

"null" { return T_Null; }

"while" { return T_While; }

"for" { return T_For; }

"if" { return T_If; }

"else" { return T_Else; }

"return" { return T_Return; }

"New" { return T_New; }

"NewArray" { return T_NewArray; }

"Print" { return T_Print; }

"ReadInteger" { return T_ReadInteger; }

"ReadLine" { return T_ReadLine; }

/* -------------------- Operators ----------------------------- */

"<=" { return T_LessEqual; }

">=" { return T_GreaterEqual;}

"==" { return T_Equal; }

"!=" { return T_NotEqual; }

"&&" { return T_And; }

"||" { return T_Or; }

{OPERATOR} { return yytext[0]; }

/* -------------------- Constants ------------------------------ */

"true"|"false" { yylval.boolConstant = (yytext[0] == 't');

return T_BoolConstant; }

{INTEGER} { yylval.integerConstant = strtol(yytext, NULL, 10); return T_IntConstant; }

{HEX_INTEGER} { yylval.integerConstant = strtol(yytext, NULL, 16); return T_IntConstant; }

{DOUBLE} { yylval.doubleConstant = atof(yytext);

return T_DoubleConstant; }

{STRING} { strcpy(yylval.stringConstant,yytext);

return T_StringConstant; }

{BEG_STRING}/\n { ReportError(&yylloc,

"Illegal newline in string constant %s", yytext); } {BEG_STRING} { ReportError(&yylloc,

"Input ends with unterminated string %s", yytext);} /* -------------------- Identifiers --------------------------- */

{IDENTIFIER} {

Declaration *temp;

if((temp=hasht.st_lookup(strdup(yytext)))==NULL)

{

temp=new Declaration(yytext,yylloc.first_line,1);

hasht.st_insert(*temp);

}

else

{

temp->IncrementOccurrences();

}

yylval.decl=temp;

return T_Identifier;}

/* -------------------- Default rule (error) -------------------- */

. {ReportError(&yylloc,"Unrecognized char: '%c'", yytext[0]); }

%%

void yyerror(char *msg)

{

ReportError(&yylloc, "%s", msg);

}

void Inityylex()

{

BEGIN(N); // Start in Normal state

yy_push_state(COPY); // but copy first line at start

curLineNum = 1;

curColNum = 1;

}

int yywrap()

{

return (1);

}

static void DoBeforeEachAction()

{

yylloc.first_line = curLineNum;

yylloc.first_column = curColNum;

https://www.wendangku.net/doc/f590175.html,st_column = curColNum + yyleng - 1;

curColNum += yyleng;

}

const char *GetLineNumbered(int num) {

return (num == curLineNum) ? curLine : NULL;

}

(2)根据pp1所提供的SYMTAB.C和SYMTAB.H文件修改我们所需要的哈希表的头文件hashtable.h和实现哈希表的程序hashtable.cpp

①由于在数据结构方面为了实现很方便的进行查找,插入,删除等操作。于是把它的数

据结构设计成一哈稀表结构,哈稀表的查找,插入等操作是快速的。所设计的哈稀结构符号表结构如下:

②对标识符的处理

③程序

《hashtable.cpp》

/*

Hashtable.cpp:

add your code below:

*/

#include

#include "stdlib.h"

#include "declaration.h"

#include "hashtable.h"

/* SHIFT is the power of two used as multiplier

in hash function */

#define SHIFT 4

int Hashtable::hash ( const char * key )

{ int temp = 0;

int i = 0;

while (key[i] != '\0')

{ temp = ((temp << SHIFT) + key[i]) % SIZE;

++i;

}

return temp;

}

void Hashtable::st_insert( Declaration declation)

{ int h =hash(declation.GetName());

LineList l = hashTable[h];

while ((l != NULL) && (strcmp(declation.GetName(),l->declation.GetName()) != 0))

l = l->next;

if (l == NULL)

{ l = (LineList) malloc(sizeof(struct LineListRec));

l->declation = declation;

l->next = hashTable[h];

hashTable[h]=l;

}

}

Declaration * Hashtable::st_lookup (const char* name)

{ int h = hash(name);

LineList l = hashTable[h];

while ((l != NULL) && (strcmp(name,l->declation.GetName()) != 0))

l = l->next;

if (l == NULL) return NULL;

else return &(l->declation);

}

《hashtable.h》

/*

hashtable:

hashtable的实现方法不会影响最后的结果,所以大家可以自由发挥。

允许大家使用类\struct等方法,不过要做相应的改动。

hashtable主要存储变量的声明,由于经常查询,所以要用速度比较快的hashtable 来实现

*/

#ifndef _H_hashtable

#define _H_hashtable

#include

#include "declaration.h

"

#define MaxDecla 256

class Declaration;

#define SIZE 211

typedef struct LineListRec

{

Declaration declation;

struct LineListRec * next;

}*LineList;

static LineList hashTable[SIZE];

static int location = 0;

class Hashtable {

private:

public:

int hash(const char *key);

void st_insert(Declaration declation);

Declaration *st_lookup(const char *name );

};

#endif

(3)修改变量声明declaration.cpp文件,实现delcaration类《 declaration.cpp》

/*

*declaration.cpp

*delcaration类的实现。

*pp1需要你来实现它

*/

#include "declaration.h"

#include

#include

Declaration::Declaration(const char *str,int lineNum,int num)

{

name=strdup(str);

lineFound=lineNum;

numoccur=num;

}

const char * Declaration::GetName()

{

return name;

}

int Declaration::GetLineFound()

{

return lineFound;

}

int Declaration::GetOccurrences()

{

return numoccur;

}

void Declaration::IncrementOccurrences()

{

numoccur++;

}

/*

*Print()

*------

*由main.c调用,注意控制输出格式,使得你的输出和例子中的输出保持一致。

*/

void Declaration::Print()

{

printf("(%s seen %d time(s), first on line %d)\n",name,numoccur,lineFound);

}

注:因为name是字符串,所以在初始化时必须调用strdup

(2)测试例子

首先运行pp1 badbool.frag >badbool.my,此时bad1.my存储的就是用pp1进行词法分析的结果。然后使用文件比较工具Textdiff比较badbool.my与badbool.out。

用TextDiff进行验证

再运行pp1 ident.frag >ident.my,此时ident.my存储的就是用pp1进行词法分析的结果。然后使用文件比较工具Textdiff比较ident.my与ident.out。

用TextDiff进行验证

三、扩展功能(如无,则不写)

四、课程设计心得

1、本次课程设计是一个词法分析器的设计,本来我们需要修改四个部分,分别为

scanner.l、hashtable.h、hashtable.cpp、declaration.cpp 。实现各个部分功能的程序都比较复杂,我在修改过程中遇到了很多困难,之后参考了老师所提供的S YMTAB.C 和SYMTAB.H文件以及查找相关资料,对哈希表的插入,查找等才有了些许掌握,总算能够运行成功。

2、此次实验declaration类的实现应该是最简单的一个修改内容,通过这次课程设计,在

一定程度上提高了编程能力,对编译原理这一门课程也有了更深的了解。由于所学知识不够全面,课程设计在很多方面还有待完善,在以后的学习过程中,会掌握更多知识,力求做到更好。同时也让我借此机会对类和对象的封装继承有了进一步的了解与掌握,也深刻认识到对与面向对象的内容还需不断学习与巩固。

实验一 词法分析器的设计

实验一词法分析器的设计 (2) 1.1 词法分析器的结构和主要任务 (2) 1.1.1 输入输出接口 (2) 1.1.2 条件限制 (2) 1.2 词法分析程序的总体设计 (3) 1.3 词法分析程序的详细设计 (4) 1.4实验步骤 (5) 1.5输入数据 (15) 1.6结果输出 (15)

实验一词法分析器的设计 实验目的:掌握词法分析的概念,设计方法,熟悉高级语言中词法的定义,词法分析程序的编写。 实验要求:在8学时内实现SAMPLE语言的词法分析器,要求用VC窗口界面实现。 实验内容:分为4次实验完成。 1.1 词法分析器的结构和主要任务 1.1.1 输入输出接口 图1-1词法分析器的输入输出界面 词法分析程序的主要任务是从左到右扫描每行源程序,拼成单词,换成统一的内部表示(token)输出,送给语法分析器。具体包括: 1.组织源程序的输入; 2.按规则拼单词,并转换成二元形式; 3.滤掉空白符,跳过注释、换行符及一些无用的符号(如字符常数的引号) 4.进行行列计数,用于指出出错的行列号,并复制出错部分; 5.列表打印源程序; 6.发现并定位词法错误; 7.生成符号表。 token文件和符号表用作语法分析的输入部分。 1.1.2 条件限制 本实验可以作如下假定: (1) 假定SAMPLE语言采用自由格式书写; (2) 可以使用注解,用/*……*/或者{……}标识,但注解不能插在单词内部,注解要在一行内结束,若一行结束,没有遇到注释后面的结束标记,自动认为注释也结束; (3) 一行可以有多个语句,一个语句也可以分布在多行中,单词之间和语句之间可以插入任意空格,单词中间不能有空白符号,单词中间也不能有回车换行符,即单词不能跨行书写; (4) 关键字都是保留字。

词法分析报告程序设计与实现

实验一词法分析程序设计与实现 一、实验目的及内容 调试并完成一个词法分析程序,加深对词法分析原理的理解。 二、实验原理(状态转换图) 1、C语言子集 (1)关键字: begin if then while do end 所有关键字都是小写。 (2)运算符和界符: := + – * / < <= <> > >= = ; ( ) # (3)其他单词是标识符(ID)和整型常数(NUM),通过以下正规式定义:ID=letter(letter| digit)* NUM=digit digit * (4)空格由空白、制表符和换行符组成。空格一般用来分隔ID、NUM,运算符、界符和关键字,词法分析阶段通常被忽略。 2、各种单词符号对应的种别码

3、词法分析程序的功能 输入:所给文法的源程序字符串。 输出:二元组(syn,token或sum)构成的序列。 其中:syn为单词种别码; token为存放的单词自身字符串; sum为整型常数。 二、软件平台及工具 PC机以及VISUAL C++6.0软件。 三、实验方法、步骤(或:程序代码或操作过程)(1)程序代码: #include #include #include char prog[80],token[8]; char ch; int syn,p,m=0,n,row,sum=0; char *rwtab[6]={"begin","if","then","while","do","end"}; void scaner() { for(n=0;n<8;n++) token[n]=NULL; ch=prog[p++]; while(ch==' ') { ch=prog[p]; p++; }

词法分析小结

词法分析小结 词法分析是编译器工作的第一阶段,它的工作就是从输入(源代码)中取得token,以作为parser(语法分析)的输入,一般在词法分析阶段都会把一些无用的空白字符(whitespace,即空格、tab和换行)以及注释剔除,以降低下一步分析的复杂度,词法分析器一般会提供一个gettoken()这样的方法,parser可以在做语法分析时调用词法分析器的这个方法来得到下一个token,所以词法分析器并不是一次性遍历所有源代码,而是采取这种on-demand的方式:只在parser需要时才工作,并且每次只取一个token。 token和lexeme 首先,token不等于lexeme。token和lexeme的关系就类似于面向对象语言中“类”和“实例”(或“对象”)之间的关系,这个用中文不知该如何解释才好,比如语言中的变量a和b,它们都属于同一种token:identifier,而a的lexeme是”a”,b则是”b”,而每个关键字都是一种token。token可以附带有一个值属性,例如变量a,当调用词法分析器的gettoken()时,会返回一个identifier类型的token,这个token带有一个属性“a”,属性可以是多样的,例如表示数字的token

可以带有一个表示数字值的属性,它是整型的。 如下代码: intage=23; intcount=50; 可以依次提取出8个token:int(值为”int”),id(值为”age”),assign(值为”=”),number(值为整型数值23),int(值为”int”),id(值为”count”),assign(值为”=”),number(值为50) 正则表达式 正则表达式可以用来描述字符串模式,例如我们可以用digit+来表示number的token,其中digit表示单个数字(这里说正则表达式并不完全和实现的正则引擎所识别的正则表达式等价,这里只是为了描述问题而已)。 然而像c语言的的多行注释,用正则表达式来描述就比较麻烦,此时更倾向于直接用有穷自动机(finiteautomaton)来描述,因为用它来描述非常直观且很容易。

编译原理词法分析报告

1、实验目的 1、为初等函数运算语言构造词法分析器。 2、掌握生成词法分析器的方法,加深对词法分析原理的理解。 3、掌握设计、编制并调试词法分析程序的思想和方法 2、实验内容 一、根据下面的要求设计初等函数运算语言的词法模式,并用正则式表达出来 1、初等函数运算语言的常量为实数类型,其定义方式为实数的最一般书写方式,如: 123.321。具体要求:不支持整数部分大于。时首数字为0;不支持小数点后结尾为 0;不支持科学记数法;不支持仅为整数时有小数点;支持负数符号,不支持正数 符号。 2、初等函数运算语言的变量采用与C语言的标识符定义一样的方式:首字符为字母或 下划线;其他的为字母、数字及下划线的混合串;区分大小写;变量长度不超过32 个字符。 3、初等函数运算语言需要处理的函数仅为表一中所列举的内容。函数的格式及参数内 容也如表一所示。 4、初等函数运算语言支持四则运算,其计算的符号与C语言相同,为:+-*/。 5、初等函数运算语言的合法的分隔符包括:空格、制表符、、分行符圆括号(左、右)、 分号。其中空格、制表符、分行符可以出现在任何两个不同的单词中间;圆括号(左、右)用于表达式中,用于改变运算的优先级,以及标识函数的参数;分号用于标识一个语句的结束。 6、初等函数运算语言支持的常量还包括:PI,Eo其中,PI为圆周率,E为自然常数。 二、将正则式转化为最小DFA,给出该DFA的形式化表示和图形表示。 三、根据DFA给出状态转换表。 四、给出初等函数运算语言的记号表,即词法分析中,语言中的记号将分为多少类,每一类型的编码、类型、属性等内容是什么。 五、编写词法分析器,将输入的字符串转化成为记号流,便于后续的语法分析工作。要求词法分析器中能够识别词法错误。

编译原理 简单样本语言的词法分析器

昆明理工大学信息工程与自动化学院学生实验报告 (2012 —2013 学年第 1 学期) 课程名称:编译原理开课实验室:信自楼44 年月日 一、实验目的及内容 设计、编制、调试一个词法分析子程序-识别单词,加深对词法分析原理的理解。 二、实验原理及基本技术路线图(方框原理图或程序流程图) 对给定的程序通过词法分析器弄够识别一个个单词符号,并以二元式(单词种别码,单词符号的属性值)显示。而本程序则是通过对给定路径的文件的分析后以单词符号和文字提示显示。 三、所用仪器、材料(设备名称、型号、规格等或使用软件) W INDOWS下的VISUAL C++6.0; 四、实验方法、步骤(或:程序代码或操作过程) #include #include using namespace std;

#define MAX 22 char ch =' '; string key[15]={"begin","end","if","then","else","while","write","read", "do", "call","const","char","until","procedure","repeat"}; int Iskey(string c){ //关键字判断 int i; for(i=0;i='a'))||((c<='Z')&&(c>='A'))) return 1; else return 0; } int IsDigit(char c){ //判断是否为数字 if(c>='0'&&c<='9') return 1; else return 0; } void analyse(FILE *fpin){ string arr=""; while((ch=fgetc(fpin))!=EOF) { arr=""; if(ch==' '||ch=='\t'||ch=='\n'){} else if(IsLetter(ch)){ while(IsLetter(ch)||IsDigit(ch)) { if((ch<='Z')&&(ch>='A')) ch=ch+32; arr=arr+ch; ch=fgetc(fpin); } fseek(fpin,-1L,SEEK_CUR); if (Iskey(arr)){cout<

编译原理 实验2 词法分析器

编译原理实验2 词法分析器 一、实验目的 1. 通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。 2. 掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。 3. 编制一个读单词的程序,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符和分隔符五大类。并依次输出各个单词的内部编码及单词符号自身值。(遇到错误时可显示“Error”,然后跳过错误部分继续显示) 二、词法分析的基础知识 1. 词法分析器的功能和输出格式 词法分析器的功能是输入源程序,输出单词符号。词法分析器的单词符号常常表示成以下的二元式(单词种别码,单词符号的属性值)。在本实验中,采用的是一类符号一种别码的方式。 标识符的BNF表示: <标识符>-> <字母><字母数字串> ) <字母数字串>-><字母><字母数字串>|<数字><字母数字串>|ε 无符号整数的BNF表示: <无符号整数>-> <数字><数字串> <数字串>-> <数字><数字串> |ε 运算符的BNF表示: <加法运算符>-> + <减法运算符>-> - <大于关系运算符>-> > <大于等于关系运算符>-> >= 2. 超前搜索 ; 词法分析时,常常会用到超前搜索方法。如当前待分析字符串为“a > i”,当前字符为“>”,此时,分析器到底是将其分析为大于关系运算符还是大于等于关系运算符呢显然,只有知道下一个字符是什么才能下结论。于是分析器读入下一个字符“+”,这时可知应将“>”解释为大于运算符。但此时,超前读了一个字符“i”,所以要回退一个字符,词法分析器才能正常运行。在分析标识符,无符号整数等时也有类似情况。 三、程序要求 1. 程序输入示例: 如源程序为C语言,输入如下一段: main() { int a, b; a = 10; b = a+20; } ; 2. 程序输出示例:

实验一词法分析实验报告

实验一词法分析 一、实验目的 通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。 编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。并依次输出各个单词的内部编码及单词符号自身值。(遇到错误时可显示“Error”,然后跳过错误部分继续显示) 二、实验要求 使用一符一种的分法 关键字、运算符和分界符可以每一个均为一种 标识符和常数仍然一类一种 三、实验内容 功能描述: 1、待分析的简单语言的词法 (1)关键字: begin if then while do end (2)运算符和界符: := + –* / < <= <> > >= = ; ( ) # (3)其他单词是标识符(ID)和整型常数(NUM),通过以下正规式定义: ID=letter(letter| digit)* NUM=digit digit * (4)空格由空白、制表符和换行符组成。空格一般用来分隔ID、NUM,运算符、界符和关键字,词法分析阶段通常被忽略。 2、各种单词符号对应的种别码 图 1

程序结构描述: 图 2 四、实验结果 输入begin x:=9: if x>9 then x:=2*x+1/3; end # 后经词法分析输出如下序列:(begin 1)(x 10)(:17)(= 18)(9 11)(;26)(if 2)……如图3所示:

图3 输入private x:=9;if x>0 then x:=2*x+1/3; end#后经词法分析输出如下序列:(private 10)(x 10)(:17)(= 18)(9 11)(;26)(if 2)……如图4所示: 图4 显然,private是关键字,却被识别成了标示符,这是因为图1中没有定义private关键字的种别码,所以把private当成了标示符。 输入private x:=9;if x>0 then x:=2*x+1/3; @ end#后经词法分析输出如下序列:(private 10)(x 10)(:17)(= 18)(9 11)(;26)(if 2)……如图5所示

词法分析器实验报告

词法分析器实验报告 词法分析器设计 一、实验目的: 对C语言的一个子集设计并实现一个简单的词法分析器,掌握利用状 态转换图设计词法分析器的基本方法。利用该词法分析器完成对源程 序字符串的词法分析。输出形式是源程序的单词符号二元式的代码, 并保存到文件中。 二、实验内容: 1. 设计原理 词法分析的任务:从左至右逐个字符地对源程序进行扫描,产生一个个单词符号。 理论基础:有限自动机、正规文法、正规式 词法分析器(Lexical Analyzer) 又称扫描器(Scanner):执行词法分析的程序 2. 词法分析器的功能和输出形式 功能:输入源程序、输出单词符号 程序语言的单词符号一般分为以下五种:关键字、标识符、常数、运算符,界符 3. 输出的单词符号的表示形式: 单词种别用整数编码,关键字一字一种,标识符统归为一种,常数一种,各种符号各一种。 4. 词法分析器的结构 单词符号 5. 状态转换图实现

三、程序设计 1.总体模块设计 /*用来存储目标文件名*/ string file_name; /*提取文本文件中的信息。*/ string GetText(); /*获得一个单词符号,从位置i开始查找。并且有一个引用参数j,用来返回这个单词最后一个字符在str的位置。*/ string GetWord(string str,int i,int& j); /*这个函数用来除去字符串中连续的空格和换行 int DeleteNull(string str,int i); /*判断i当前所指的字符是否为一个分界符,是的话返回真,反之假*/ bool IsBoundary(string str,int i); /*判断i当前所指的字符是否为一个运算符,是的话返回真,反之假*/ bool IsOperation(string str,int i);

词法分析实验报告

词法分析器 一、实验目的: 通过设计编制调试一个具体的词法分析程序,加深对词法分析原理的理解。并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。 编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词,即基本保留字、标识符、常数、运算符、分隔符五大类。并依次输出各个单词的内部编码及单词符号自身值。 二、实验要求 如源程序为C语言。输入如下一段:Array main() { int a,b; a = 10; b = a + 20; }# 要求输出如右图。 要求: 1、将单词分为五种 识别关键字:main、if、int、for、while、do、return、break、continue; 单词种别码为1。 标识符;单词种别码为2。 常数为无符号整形数;单词种别码为3。 运算符包括:+、-、*、/、=、>、<、>=、<=、!= ; 单词种别码为4。 分隔符包括:,、;、{、}、(、);单词种别码为5。 2、使用一符一种的分法 关键字、运算符和分界符可以每一个均为一种 标识符和常数仍然一类一种 三、实验内容 1、功能描述 改程序是一个实现词法分析的功能,能识别5种单词,其他单词报错。 2、程序结构描述 int IsKey(char *Word)关键字匹配函数,查询是否为关键字,若是,返回值为1,否则为0。 int IsAlpha(char c) 查看是否为字母,若是,返回值为1,否则为0。 int IsNum(char c) 查看是否为数字,若是,返回值为1,否则为0。 void scanner(FILE *fp) 扫描函数,扫描程序中的字符串并调用上述三种函数检查是否是字母、 数字,是否是关键字,并输出。 fseek(fp,-1,1)回退一个字符。 fgetc(fp)从数据流中区下一个字符。 fopen 文件打开函数,返回指向文件第一个字符的指针 四、实验结果 测试内容为 main() {

编译原理实验报告一 简单样本语言的词法分析器

理工大学信息工程与自动化学院学生实验报告 (2012 —2013学年第一学期) 一、实验目的及容 编译技术是理论与实践并重的课程,而其实验课要综合运用所学的多门课程的容,用来完成一个小型编译程序。从而巩固和加强对词法分析、语法分析、语义分析、代码生成和报错处理等理论的认识和理解;培养学生对完整系统的独立分析和设计的能力,进一步培养学生的独立编程能力。 调试并完成一个词法分析程序,加深对词法分析原理的理解。 二、实验原理及基本技术路线图(框原理图或程序流程图) 1、待分析的简单语言的词法 (1)关键字: begin if then while do end 所有关键字都是小写。 (2)运算符和界符: := + –* / < <= <> > >= = ; ( ) #

(3)其他单词是标识符(ID)和整型常数(NUM),通过以下正规式定义:ID=letter(letter| digit)* NUM=digit digit * (4)空格由空白、制表符和换行符组成。空格一般用来分隔ID、NUM,运算符、界符和关键字,词法分析阶段通常被忽略。 2、各种单词符号对应的种别码 3、词法分析程序的功能 输入:所给文法的源程序字符串。 输出:二元组(syn,token或sum)构成的序列。 其中:syn为单词种别码; token为存放的单词自身字符串; sum为整型常数。 二、所用仪器、材料(设备名称、型号、规格等或使用软件)

1台PC以及VISUAL C++6.0软件。 三、实验法、步骤(或:程序代码或操作过程) (1)程序代码: #include #include #include char prog[80],token[8]; char ch; int syn,p,m=0,n,row,sum=0; char *rwtab[6]={"begin","if","then","while","do","end"}; void scaner() { for(n=0;n<8;n++) token[n]=NULL; ch=prog[p++]; while(ch==' ') { ch=prog[p]; p++; } if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) { m=0; while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')) { token[m++]=ch; ch=prog[p++]; } token[m++]='\0'; p--; syn=10; for(n=0;n<6;n++)

词法分析

实验二:词法分析 一、实验目的:编制一个读单词过程,从输入的源程序中,识别出各个具有独立意义的单词, 即基本保留字、标识符、常数、运算符、分隔符五大类。并依次输出各个单词的内部编码及 Error”,然后跳过错误部分继续显示) 二、估计实验时间:1.课余准备15小时;2.上机二次4小时;3.完成实验报告5小时。 三、实验过程和指导: (一)准备:1.阅读课本有关章节,花一周时间明确语言的语法,写出基本保留字、标识符、 常数、运算符、分隔符和程序例。2.初步编制好程序。3.准备好多组测试数据。 (二)上课上机:将源代码拷贝到机上调试,发现错误,再修改完善。第二次上机调试通过。 (三)程序要求:Array程序输入/输出示例: 如源程序为C语言。输入如下一段: main() { int a,b; a = 10; b = a + 20; } 要求输出如右图。 要求: 识别保留字:if、int、for、while、do、return、break、 其他的都识别为标识符;

常数为无符号整形数; 运算符包括:+、-、*、/、=、>、<、>=、<=、!= 分隔符包括:,、;、{、}、(、) 程序思路(仅供参考): 0.定义部分:定义常量、变量、数据结构。 1.初始化:从文件将源程序全部输入到字符缓冲区中。 2.取单词前:去掉多余空白。 3.取单词后:去掉多余空白(可选,看着办)。 4.取单词:利用实验一的成果读出单词的每一个字符,组成单词,分析类型。(关键是如何判断取单词结束?取到的单词是什么类型的单词?) 5.显示结果。 (四)练习该实验的目的和思路: 程序开始变得复杂起来,可能是大家以前编过的程序中最复杂的,但相对于以后的程序来说还是简单的。因此要认真把握这个过渡期的练习。程序规模大概为200行。本实验和以后的实验相关。通过练习,掌握对字符进行灵活处理的方法。 (五)为了能设计好程序,主意以下事情: 1.模块设计:将程序分成合理的多个模块(函数),每个模块做具体的同一事情。 2.写出(画出)设计方案:模块关系简图、流程图、全局变量、函数接口等。 3.编程时注意编程风格:空行的使用、注释的使用、缩进的使用等。 四、上交: 1.程序源代码;

东南大学编译原理词法分析器实验报告

词法分析设计 1. 实验目的 通过本实验的编程实践,了解词法分析的任务,掌握词法分析程序设计的原理和构造方法,对编译的基本概念、原理和方法有完整的和清楚的理解,并能正确地、熟练地运用。 2. 实验内容 用C++语言实现对C++语言子集的源程序进行词法分析。通过输入源程序从左到右对字符串进行扫描和分解,依次输出各个单词的内部编码及单词符号自身值;若遇到错误则显示“Error”,然后跳过错误部分继续显示;同时进行标识符登记符号表的管理。 3. 实验原理 本次实验采用NFA->DFA->DFA0的过程: 对待分析的简单的词法(关键词/id/num/运算符/空白符等)先分别建立自己的FA,然后将他们用产生式连接起来并设置一个唯一的开始符,终结符不合并。 待分析的简单的词法 (1)关键字: "asm","auto","bool","break","case","catch","char","class","

const","const_cast"等 (2)界符(查表) ";",",","(",")","[","]","{","}" (3)运算符 "*","/","%","+","-","<<","=",">>","&","^","|","++","--"," +=","-=","*=","/=","%=","&=","^=","|=" relop: (4)其他单词是标识符(ID)和整型常数(SUM),通过正规式定义。 id/keywords: digit: (5)空格有空白、制表符和换行符组成。空格一般用来分隔ID、SUM、运算符、界符和关键字,词法分析阶段通常被忽略。

简单词法分析器

简单词法分析器 1、将源文件中的单词识别出来,以用'$'为首的标识符标记识别出的单词 2、单词符号及内部表示如表: 单词符号种别编码助记符内码值 DIM 1 $DOM — IF 2 $IF — DO 3 $DO — STOP 4 $STOP — END 5 $END — 标识符 6 $ID 内部字符串 常数7 $INT 标准二进制形式= 8 $ASSIGN — + 9 $PLUS — * 10 $STAR — ** 11 $POWER — ; 12 $SEMICOLON — { 13 $LBRACE — } 14 $RBRACE — /* * 词法分析:将源文件中的单词符号一一识别 * 并将其与助记符保存到文本文件 */ #include "iostream" #include "string" using namespace std; //reserve保留字 string reserve[5] = {"DIM","IF","DO","STOP","END"}; //结构体数组,保存已识别的单词 struct table { string str; string name; }table[400]; int count = 0; //判断是否为保留字

bool Reserve(string str) { bool flag = false; for(int i=0; i>filename; if((fp = fopen(filename,"r")) == NULL) { cout<<"file not found"<

词法分析课程设计

《词法分析》设计说明书 学生姓名 学 号 5011110122 5011110133 5011110128 所属学院 信息工程学院 专 业 计算机科学与技术 班 级 计算机15-1班 信息工程学院 《编译原理及实践》结课大作 业

摘要 编译,简单的说,就是把源程序转换为可执行程序。从hellow worl说程序运行机制里面简单的说明了程序运行的过程,以及一个程序是如何一步步变成可执行文件的。在这个过程中,编译器做了很多重要的工作。对于编译的内部实现,也就是编译的原理。 这篇论文主要说的是编译器前端,词法分析器的原理,最后会给出一个词法分析器的简单实现。 编译简单的说,就是把源程序转化为另一种形式的程序,而其中关键的部分就是理解源程序所要表达的意思,才能转化为另一种源程序。 可以用一个比喻来说明问题:人A和人B想要交谈,但是他们都不知道彼此的语言,这就需要一个翻译C,同时懂得A和B的语言。有了C做中间层,A和B才能正常交流。C的作用就有点像编译器,它必须能理解源程序所要表达的意思,才能把信息传递给另一个。编译器也一样,它的输入是语言的源文件(一般可以是文本文件)对于输入的文件,首先要分离出这个输入文件的每个元素(关键字、变量、符号、、),然后根据语言的文法,分析这些元素的组合是否合法,以及这些组合所表达的意思。 程序设计语言和自然语言不一样,都是用符号来描述,每个特定的符号表示特定的意思,而且程序设计语言是上下文无关的。上下文无关就是某一个特定语句所要表达的意思和它所处的上下文没有关系,只有它自身决定。 这篇论文主要说的就是词法分析,也就是把输入的符号串整理成特定的词素。 关键词:单片机;词法分析

编译原理实验报告2-词法分析程序的设计

实验2 词法分析程序的设计 一、实验目的 掌握计算机语言的词法分析程序的开发方法。 二、实验内容 编制一个能够分析三种整数、标识符、主要运算符和主要关键字的词法分析程序。 三、实验要求 1、根据以下的正规式,编制正规文法,画出状态图; 标识符<字母>(<字母>|<数字字符>)* 十进制整数0 | ((1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)*) 八进制整数0(1|2|3|4|5|6|7)(0|1|2|3|4|5|6|7)* 十六进制整数0x(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)* 运算符和界符+ - * / > < = ( ) ; 关键字if then else while do 2、根据状态图,设计词法分析函数int scan( ),完成以下功能: 1)从文本文件中读入测试源代码,根据状态转换图,分析出一个单词, 2)以二元式形式输出单词<单词种类,单词属性> 其中单词种类用整数表示: 0:标识符 1:十进制整数 2:八进制整数 3:十六进制整数 运算符和界符,关键字采用一字一符,不编码 其中单词属性表示如下: 标识符,整数由于采用一类一符,属性用单词表示 运算符和界符,关键字采用一字一符,属性为空 3、编写测试程序,反复调用函数scan( ),输出单词种别和属性。 四、实验环境 PC微机 DOS操作系统或Windows 操作系统 Turbo C 程序集成环境或Visual C++ 程序集成环境 五、实验步骤 1、根据正规式,画出状态转换图;

词法分析

词法分析器的实现 开篇 编译,简单的说,就是把源程序转换为可执行程序。从hello world 说程序运行机制里面简单的说明了程序运行的过程,以及一个程序是如何一步步变成可执行文件的。在这个过程中,编译器做了很多重要的工作。对底层该兴趣的我,自然的,也就迫切想搞清楚编译的内部实现,也就是编译的原理。 这篇文章主要说的是编译器前端,词法分析器的原理,最后会给出一个词法分析器的简单实现。 介绍 编译简单的说,就是把源程序转化为另一种形式的程序,而其中关键的部分就是理解源程序所要表达的意思,才能转化为另一种源程序。 可以用一个比喻来说明问题:人A和人B想要交谈,但是他们都不知道彼此的语言,这就需要一个翻译C,同时懂得A和B的语言。有了C做中间层,A和B才能正常交流。C的作用就有点像编译器,它必须能理解源程序所要表达的意思,才能把信息传递给另一个。 编译器也一样,它的输入是语言的源文件(一般可以是文本文件)对于输入的文件,首先要分离出这个输入文件的每个元素(关键字、变量、符号、、) 然后根据语言的文法,分析这些元素的组合是否合法,以及这些组合所表达的意思。 程序设计语言和自然语言不一样,都是用符号来描述,每个特定的符号表示特定的意思,而且程序设计语言是上下文无关的。上下文无关就是某一个特定语句所要表达的意思和它所处的上下文没有关系,只有它自身决定。 这篇博文主要说的就是词法分析,也就是把输入的符号串整理成特定的词素。 词法分析 定义: 词法分析器的功能输入源程序,按照构词规则分解成一系列单词符号。单词是语言中具有独立意义的最小单位,包括关键字、标识符、运算符、界符和常量等 (1) 关键字是由程序语言定义的具有固定意义的标识符。例如,Pascal 中的begin,en d,if,while都是保留字。这些字通常不用作一般标识符。 (2) 标识符用来表示各种名字,如变量名,数组名,过程名等等。 (3) 常数常数的类型一般有整型、实型、布尔型、文字型等。 (4) 运算符如+、-、*、/等等。 (5) 界符如逗号、分号、括号、等等。 输出:

词法分析说明

一、创建环境 1.将java拷贝到c:盘根目录下。 2.设置环境变量: 在“计算机”图标上单击右键--------属性------高级系统设置------环境变量-----系统变量 path中设置内容为: c:\java\jdk1.6.0_10\bin; classpath中设置内容为: c:\java\jdk1.6.0_10\lib\dt.jar; c:\java\jdk1.6.0_10\lib\tools.jar; c:\java\jre6\lib\rt.jar; .; c:\1000; 3.在c盘要建立1000 文件夹,将SimpleLexer文件夹复制到该文件 夹内(注意字母的大小写)。 二、词法分析 1. 运行cmd 命令 输入cmd回车

输入cd\ 回车,使输入符号到c:\> 状态 再输入cd 1000 回车。进入到c:\1000> 状态 2.编译程序 先编译Token.java文件,再编译Main.java文件,最后编译lexer.java 文件。如下图所示。 3.运行程序 test.in 是词法分析器的输入程序(即输入的源程序,此程序由学生给出)。运行后,自动在1000目录下生成result.out文件。(test.in 和result.out文件都可由记事本查看内容)

test.in 文件内容如下: result.out文件内容如下:

如果test.in中输入有误,则运行时提示:

4.编译原理课程设计内容如下:(注:每个同学从下列关键字中各选 五个,从运算符中各选四个,标识符和界符都要设计) 单词符号分为关键字,标识符,运算符,界符等: 关键字:begin end if then else while do void switch catch try case for continue break default return long short int float double char abstract Boolean

词法分析实验报告

词法分析实验报告 中北大学软件学院 实验报告 专业课程名称学号姓名 辅导教师成绩 实验日期实验时间 1实验名称 :词法分析器的设计与实现 2、实验目的 (1)掌握C语言单词符号的划分、正规式、状态转换图及词法分析器的实现。 (2)掌握词法分析程序的作用。 3、实验要求 (1)对任给的一个C语言源程序,能够滤掉空格、回车换行符、tab键及注释。 (2)识别各类单词符号,如关键字、标识符、运算符、常数、界符,结果以二元式形式输出,并构造符号表。 (3)输出有词法错误的单词及所在行号。(在此阶段只能识别有限的词法错误) 4、实验原理 根据扫描到的单词符号的第一个字符的种类,分别转到相应的程序进行处理。这些程序的功能就是识别以相应字符开头的各类单词符号。 5、实验步骤 (1)根据C语言各类单词的正规式,构造能识别各类单词的状态转换图。 (2)根据状态转换图,构造识别各类单词的词法分析器。 6、状态转换图及词法分析程序 (1)标识符(ID)和整型常数(NUM)的正规式如下:

ID = _ | letter (letter | digit)* NUM = digit digit* 其中标识符的状态转换图为: 其词法分析程序为: if(((ch>='A')&&(ch<='Z'))||((ch>='a')&&(ch<='z'))||(ch=='_')) { /*以字母开头*/ while(((ch>='A')&&(ch<='Z'))||((ch>='a')&&(ch<='z'))||(ch =='_')||((ch>='0')&&(ch<='9'))) { array[i++]=ch; ch=fgetc(fpin); } word=(char *)malloc((i+1)*sizeof(char)); memcpy(word,array,i); word[i]='\0'; is_id_key(word); if(ch!=EOF) fseek(fpin,-1L,SEEK_CUR); } 常数的状态转换图为: 其词法分析程序为: else if(ch>='0'&&ch<='9') { /*以数字开头*/ while(ch>='0'&&ch<='9')

词法分析报告设计实验报告材料(附代码)

实验一词法分析设计 实验学时:4 实验类型:综合 实验要求:必修 一、实验目的 通过本实验的编程实践,使学生了解词法分析的任务,掌握词法分析程序设计的原理和构造方法,使学生对编译的基本概念、原理和方法有完整的和清楚的理解,并能正确地、熟练地运用。 二、实验容 用VC++/VB/JAVA语言实现对C语言子集的源程序进行词法分析。通过输入源程序从左到右对字符串进行扫描和分解,依次输出各个单词的部编码及单词符号自身值;若遇到错误则显示“Error”,然后跳过错误部分继续显示;同时进行标识符登记符号表的管理。 以下是实现词法分析设计的主要工作: (1)从源程序文件中读入字符。 (2)统计行数和列数用于错误单词的定位。 (3)删除空格类字符,包括回车、制表符空格。 (4)按拼写单词,并用(码,属性)二元式表示。(属性值——token的机表示) (5)如果发现错误则报告出错 (6)根据需要是否填写标识符表供以后各阶段使用。 单词的基本分类: ◆关键字:由程序语言定义的具有固定意义的标识符。也称为保留字例如if、for、while、printf ;单词种别码为1。 ◆标识符:用以表示各种名字,如变量名、数组名、函数名; ◆常数:任何数值常数。如125, 1,0.5,3.1416; ◆运算符:+、-、*、/; ◆关系运算符:<、<=、= 、>、>=、<>; ◆分界符:;、,、(、)、[、]; 三、实验要求

1、编程时注意编程风格:空行的使用、注释的使用、缩进的使用等。 2、将标识符填写的相应符号表须提供给编译程序的以后各阶段使用。 3、根据测试数据进行测试。测试实例应包括以下三个部分: ◆全部合法的输入。 ◆各种组合的非法输入。 ◆由记号组成的句子。 4、词法分析程序设计要求输出形式: 例:输入VC++语言的实例程序: If i=0 then n++; a﹤= 3b %); 输出形式为: 单词二元序列类型位置(行,列)(单词种别,单词属性) for (1,for ) 关键字(1,1)i ( 6,i ) 标识符(1,2)= ( 4,= ) 关系运算符(1,3)0 ( 5,0 ) 常数(1,4)then ( 1,then) 关键字(1,5)n (6,n ) 标识符(1,6)++ Error Error (1,7);( 2, ; ) 分界符(1,8)a (6,a ) 标识符(2,1)

实验一(词法分析)

实验一词法分析 一.实验目的 1、学会针对DFA转换图实现相应的高级语言源程序。 2、深刻领会状态转换图的含义,逐步理解有限自动机。 3、掌握手工生成词法分析器的方法,了解词法分析器的内部工作原理。 二.实验内容 TINY计算机语言的编译程序的词法分析部分实现。 从左到右扫描每行该语言源程序的符号,拼成单词,换成统一的内部表示(token)送给语法分析程序。 为了简化程序的编写,有具体的要求如下: (1)数仅仅是整数。 (2)空白符仅仅是空格、回车符、制表符。 (3)代码是自由格式。 (4)注释应放在花括号之内,并且不允许嵌套 三.实验要求 要求实现编译器的以下功能: (1)按规则拼单词,并转换成二元式形式 (2)删除注释行 (3)删除空白符(空格、回车符、制表符) (4)列表打印源程序,按照源程序的行打印,在每行的前面加上行号,并且打印出每行包含的记号的二元形式

(5)发现并定位错误 ,词法分析进行具体的要求: (1)记号的二元式形式中种类采用枚举方法定义;其中保留字和特殊字符是每个都一个种类,标示符自己是一类,数字是一类;单词的属性就是表示的字符串值。 (2)词法分析的具体功能实现是一个函数GetToken(),每次调用都对剩余的字符串分析得到一个单词或记号识别其种类,收集该记号的符号串属性,当识别一个单词完毕,采用返回值的形式返回符号的种类,同时采用程序变量的形式提供当前识别出记号的属性值。这样配合语法分析程序的分析需要的记号及其属性,生成一个语法树。 (3)标示符和保留字的词法构成相同,为了更好的实现,把语言的保留字建立一个表格存储,这样可以把保留字的识别放在标示符之后,用识别出的标示符对比该表格,如果存在该表格中则是保留字,否则是一般标示符。 源程序: /* 注意: 测试时把测试的源程序存入当前目录中,并改名为source.txt */ #include #include #include #include #include usingnamespacestd;

词法分析的实验报告

《词法分析》 实验报告 目录 目录 0 1 实验目的 (1) 2 实验内容 (1) 2、1 TINY计算机语言描述 (1) 2、2 实验要求 (1) 3 此法分析器的程序实现 (2) 3、1 状态转换图 (2) 3、2 程序源码 (3) 3、3 实验运行效果截图 (8) 4 实验体会 (8)

1实验目的 1、学会针对DFA转换图实现相应的高级语言源程序。 2、深刻领会状态转换图的含义,逐步理解有限自动机。 3、掌握手工生成词法分析器的方法,了解词法分析器的内部工作原理。 2实验内容 2.1TINY计算机语言描述 TINY计算机语言的编译程序的词法分析部分实现。 从左到右扫描每行该语言源程序的符号,拼成单词,换成统一的内部表示(token)送给语法分析程序。 为了简化程序的编写,有具体的要求如下: 1、数仅仅就是整数。 2、空白符仅仅就是空格、回车符、制表符。 3、代码就是自由格式。 4、注释应放在花括号之内,并且不允许嵌套 TINY语言的单词 2.2实验要求 要求实现编译器的以下功能 1、按规则拼单词,并转换成二元式形式 2、删除注释行 3、删除空白符(空格、回车符、制表符)

4、列表打印源程序,按照源程序的行打印,在每行的前面加上行号,并且打印出每行包含的记号的二元形式 5、发现并定位错误 词法分析进行具体的要求 1、记号的二元式形式中种类采用枚举方法定义;其中保留字与特殊字符就是每个都一个种类,标示符自己就是一类,数字就是一类;单词的属性就就是表示的字符串值。 2、词法分析的具体功能实现就是一个函数GetToken(),每次调用都对剩余的字符串分析得到一个单词或记号识别其种类,收集该记号的符号串属性,当识别一个单词完毕,采用返回值的形式返回符号的种类,同时采用程序变量的形式提供当前识别出记号的属性值。这样配合语法分析程序的分析需要的记号及其属性,生成一个语法树。 3、标示符与保留字的词法构成相同,为了更好的实现,把语言的保留字建立一个表格存储,这样可以把保留字的识别放在标示符之后,用识别出的标示符对比该表格,如果存在该表格中则就是保留字,否则就是一般标示符。 3此法分析器的程序实现 3.1状态转换图 图1 TINY语言的确定有限自动机(DFA)

相关文档
相关文档 最新文档