C++语言实现词法分析器设计例题参考
词法分析

V
,
A
c
R
o
□ s
u n
u
t
m ,
: r
f
e
i
a
r
l
s
;
t
B
r E
E
s N
G
t D
I
+ .
N
c o
s
u
u
n
m :
t *
=
1
f
0
i
期望的源程序表示形式
例 某程序片段如下: VAR sum, first, count: real; BEGIN sum:=first + count * 10 END. VAR real first . sum ; + count , first BEGIN * 10 , count sum : := END
提问
写出满足下列描述的正规式
1. ={a,b},不以a开头的,以aa结尾的字符 串 2. ={a,b,c},包含至少一个a和至少一个b 的串
1. b(a|b) *aa 2. (a|b|c) *a(a|b|c) *b(a|b|c) * | (a|b|c) *b(a|b|c) *a(a|b|c) *
:
* \n var real begin end
35
36 37 15 20 23 24
$colon
$mult $return $var $real $begin $end
单词名称 标识符 无符号整数 ,
类别编码 (词法信息) 1 2 30
类别编码的助 记符 $id $int $comma
例1 某程序片段如下: VAR sum, first, count: real; BEGIN sum:=first + count * 10 END.
写一个简单的C词法分析器

写⼀个简单的C词法分析器写⼀个简单的C词法分析器在写本⽂过程中,我参考了《》中的⼀些内容。
这⾥我们主要讨论写⼀个C语⾔的词法分析器。
⼀、关键字⾸先,C语⾔中关键字有:auto、break、case、char、const、continue、default、do、double、else、enum、extern、float、for、goto、if、int、long、register、return、short、signed、sizeof、static、struct、switch、typedef、unsigned、union、void、volatile、while等共32个关键字。
⼆、运算符C语⾔中的运算符有:(、)、[、]、->、.、!、~、++、--、-、()、*、&、*、/、%、+、-、<<、>>、<、<=、>、>=、==、!=、&、^、|、&&、||、?:、=、+=、-=、*=、/=、%=、&=、^=、|=、<<=、>>=、,、等共45个运算符。
说明:-减号与-负号在词法阶段⽆法判别,需要在语法或予以阶段判别;同理*乘号与*指针操作符也是这样的。
三、界符另外C语⾔还有以下界符:;、{、}、:四、标⽰符C语⾔中标⽰符的定义为:开头可以是下划线或字母,后⾯可以是下划线、字母或数字。
五、常数整形数和浮点数六、空⽩符C语⾔中的空⽩符有:空格符、制表符、换⾏符,这些空⽩符在词法分析阶段可以被忽略。
七、注释C语⾔中的注释形式为:/*…*/,可以多⾏注释。
下⾯我们给出C程序中token和其对应的种别码:单词符号种别码单词符号种别码单词符号种别码auto1union28[55break2unsigned29]56case3void30^57char4volatile31^=58const5while32{59continue6-33|60default7--34||61do8-=35|=62double9->36}63else10!37~64enum11!=38+65extern12%39++66float13%=40+=67for14&41< 68goto15&&42<< 69if16&=43<<=70int17(44<=71long18)45=72sizeof2350>>=77static2451"78struct2552/*注释*/79switch2653常数80typedef2754标识符81我们的词法分析程序根据所给的源代码程序,输出的是⼆元组:<单词符号, 种别码>。
C语言词法分析器和C-语言语法分析器编译原理课程设计

《编译原理课程设计》课程报告题目 C语言词法分析器和C-语言语法分析器学生姓名学生学号指导教师提交报告时间 2019 年 6 月 8 日C语言词法分析器1 实验目的及意义1.熟悉C语言词法2.掌握构造DFA的过程3.掌握利用DFA实现C语言的词法分析器4.理解编译器词法分析的工作原理2 词法特点及正则表达式2.1词法特点2.1.1 保留字AUTO, BREAK , CASE , CHAR , CONST , CONTINUE , DEFAULT , DO , DOUBLE , ELSE,ENUM , EXTERN , FLOAT , FOR , GOTO,IF , INT , LONG , REGISTER , RETURN,SHORT , SIGNED , SIZEOF , STATIC , STRUCT ,SWITCH , TYPEDEF , UNION , UNSIGNED , VOID,VOLATILE , WHILE,2.1.2 符号+ - * / ++ -- += -= *= < <= > >= == != = ; , ( ) [ ] { } /* */ :2.2 正则表达式whitespace = (newline|blank|tab|comment)+digit=0|..|9nat=digit+signedNat=(+|-)?natNUM=signedNat(“.”nat)?letter = a|..|z|A|..|ZID = letter(letter|digit|“_”)+CHAR = 'other+' STRING = “other+”3 Token定义3.2 tokenType类型代码4 DFA设计4.1 注释的DFA设计注释的DFA如下所示,一共分为5个状态,在开始状态1时,如果输入的字符为/, 则进入状态2,此时有可能进入注释状态,如果在状态2时,输入的字符为*,则进入注释状态,状态将转到3,如果在状态3时,输入的字符为*,则有可能结束注释状态,此时状态将转到状态4,如果在状态4时输入的字符为/,则注释状态结束,状态转移到结束状态。
实验一实现简单词法分析器实验内容

实验一实现简单词法分析器实验内容实验一实现简单的词法分析器一、实验内容实现一个C语言子集的词法分析程序。
二、实验要求1、要求能识别整数、自定义标识符及以下关键字:+-*/===!==||=()[]{}:;,voidintfloatcharifelsewhiledo!main2、自己任意书写一小段包含上述部分关键字的C语言代码,编写词法分析程序分析所写的代码,可以用任何语言实现,输出程序中所有关键字、整数、自定义标识符对应的二元式。
3、关键字、自定义标识符、整数的类号自己确定,要求将确定的类号以表格的形式书写在纸质实验报告上。
4、要求输出的格式是:假设float的类号是28,则识别float的输出结果是(float,28);对于整数与自定义标识符,假设标识符的类号是1,则识别标识符的输出结果是(标识符名称,1),同时将该标识符放入一张符号表。
5、实例如下:三、提示1、程序代码提交给课代表。
2、纸质实验报告内容:实验内容、自己写的待扫描的C语言源程序,类号分配表,所实现代码的核心代码,词法分析结果。
实验指导一、实验涉及的数据结构与变量1、关键字列表struct{charsymbol[30];intclassID;}keywordtable[33];用于存放实验要求的33个关键字,可以在定义该结构数组时直接初始化,给每个关键字分配唯一的类号。
2、符号表struct{charname[20];inttype;}symtable[100];用于存放源程序中的自定义标识符与整数(不考虑浮点数),其中整数的类号与自定义标识符的类号自行确定,但是不能与关键字的类号相同。
3、二元式列表struct{charsign[20];intclassID;}eryuanshi[100];用于存放所有识别的二元式,包含关键字、整数、自定义标识符。
4、几个变量intkey_count=33;//关键字的个数intsym_count;//符号表计数器interyuanshi_count;//二元式计数器二、实验涉及的函数1、voidlookup(char*p)【功能说明】首先在关键字列表keywordtable中查询字符串p,若存在就将该字符串及对应的类号插入二元式列表eryuanshi;若没有,在符号表symtable中查询,如果symtable中不存在p就将p插入,这里要分p 是标识符还是整数区别对待,设置不同的type值。
编译原理课程设计报告C语言词法与语法分析器的实现

编写原理课程设计报告题目:编译原理课程设计C语言词法和语法分析器的实现C-词法和语法分析器的实现1.课程设计目标(1)题目的实用性C语言具有完整语言的基本属性,写C语言的词法分析和语法分析对理解编译原理的相关理论和知识会起到很大的作用。
通过编写C语言词法和语法分析程序,可以对编译原理的相关知识:正则表达式、有限自动机、语法分析等有一个清晰的认识和掌握。
(2)C语言的词法描述①语言的关键词:else if int返回void while的所有关键字都是保留字,必须小写。
②特殊符号:+ - * / < <= > >= == != = ;, ( ) [ ] { } /* */③其他标记是ID和NUM,它们由以下正则表达式定义:ID =字母字母*NUM =数字数字*字母= a|..|z|A|..|Zdigit = 0|..|9注:ID表示标识符,NUM表示数字,letter表示字母,digit表示数字。
小写字母和大写字母是有区别的。
④它由空格、换行符和制表符组成。
空格通常会被忽略。
⑤用常用的C语言符号/*将注释括起来...*/.注释可以放在任何空白位置(也就是注释不能放在标记上),可以多行。
注释不能嵌套。
(3)规划目标能够正确分析程序的词法和语法。
2.分析和设计(1)设计理念a.词汇分析词法分析的实现主要使用有限自动机理论。
有限自动机可以用来描述识别输入字符串中模式的过程,因此也可以用来构造扫描程序。
词法分析器可以很容易地用有限自动机理论来设计。
b.语法分析语法分析采用递归下降分析法。
递归下降法是语法分析中最容易理解的方法。
其主要原理是根据每个非终结符的产生式结构为其构造相应的解析子程序,其中终结符生成匹配命令,非终结符生成过程调用命令。
这种方法被称为递归子例程下降法或递归下降法,因为语法递归的相应子例程也是递归的。
子程序的结构与产生式的结构几乎相同。
(2)程序流程图主程序流程图:词法分析:语法分析:词汇分析子流程图:语法分析子流程图:3.程序代码实现整个词法与语法程序设计在同一个项目中,包含八个文件,分别是main.cpp、parse.cpp、scan.cpp、util.cpp、scan.h、util.h、globals.h和parse.h,其中scan.cpp和scan.h是词法分析程序。
编译原理课程设计-词法分析器的设计及实现(C)

词法分析器的设计 一. 设计说明及设计要求 一般来说,编译程序的整个过程可以划分为五个阶段:词法分析、语法分析、中间代码生成、优化和目标代码生成。本课程设计即为词法分析阶段。词法分析阶段是编译过程的第一个阶段。这个阶段的任务是从左到右一个字符一个字符地读入源程序,对构成源程序的字符流进行扫描和分解,从而识别出一个个单词(也称单词符号或符号)。如保留字(关键字或基本字)、标志符、常数、算符和界符等等。
二. 设计中相关关键字说明 1. 基本字:也称关键字,如C语言中的 if , else , while , do ,for,case,break, return 等。 2. 标志符:用来表示各种名字,如常量名、变量名和过程名等。 3. 常数:各种类型的常数,如12,6.88,和“ABC”等。 4. 运算符:如 + ,- , * , / ,%, < , > ,<= , >= 等。 5. 界符,如逗点,冒号,分号,括号,# ,〈〈 , 〉〉等。
三 、程序分析
词法分析是编译的第一个阶段,它的主要任务是从左到右逐个字符地对源程序进行 扫描,产生一个个单词序列,用以语法分析。词法分析工作可以是独立的一遍,把字符流的源程序变为单词序列,输出在一个中间文件上,这个文件做为语法分析程序的输入而继续编译过程。然而,更一般的情况,常将词法分析程序设计成一个子程序,每当语法分析程序需要一个单词时,则调用该子程序。词法分析程序每得到一次调用,便从源程序文件中读入一些字符,直到识别出一个单词,或说直到下一个单词的第一个字符为止。 四 、模块设计 下面是程序的流程图 五 、 程序介绍 在程序当前目录里建立一个文本文档,取名为infile.txt,所有需要分析的程序都写在此文本文档里,程序的结尾必须以“@”标志符结束。程序结果输出在同一个目录下,文件名为outfile.txt,此文件为自动生成。本程序所输出的单词符号采用以下二元式表示:(单词种别,单词自身的值)如程序输出结果 (57,"#")(33,"include")(52,"<")(33,"iostream") 等。 程序的功能:(1) 能识别C语言中所有关键字(共32个)(单词种别分别为1 — 32 ,详情见程序代码相关部分,下同) (2) 能识别C语言中自定义的标示符 (单词种别为 33)
词法分析程序的设计与实现

词法分析程序的设计与实现方法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,进入错误处理状态。
词法分析器(C语言版)

putc('\n',fw);
}
if(num==2) //处理常数
{
_num=con->cont[val-1];
i=_num/10;
while(i>0)
{
_num=_num-10*i;
c=(i+'0');
printf("%c",c);
putc(c,fw);
i=_num/10;
void concat()
{
char * ct=&character;
strcat(token,ct);
}
//判断是否为字母。
int letter()
{
return isalpha(character);
}
//判断是否为数字
int digit()
{
return isdigit(character);
fputs(CODE[num-1],fw);
putc('#',fw);
putc('\n',fw);
}
}
//将错误写入到文件或输出到屏幕
void error()
{
printf("(ERROR,");
printf("%c",character);
printf(")");
printf("\n");
fputs("(ERROR,",fw);
{
int i;
int _num=num;
char c;
c='(';
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1 给同学们的一段话 《编译原理》计算机软件专业的一门重要专业课程。该课程系统地向学生介绍编译程序的结构、工作流程及编译程序各组成部分的设计原理和实现技术。由于该课程理论性和实践性都比较强,内容较为抽象复杂,涉及到大量的软件设计算法,因此,一直是一门比较难学的课程。为了使学生更好地理解和掌握编译技术的基本概念、基本原理和实现方法,实践环节非常重要,只有通过上机进行程序设计,才能使学生对比较抽象的教学内容产生具体的感性认识,增强学生综合分析问题、解决问题的能力,并对提高学生软件设计水平大有益处。 编译原理涉及词法分析,语法分析,语义分析及优化设计等各方面。词法分析阶段是编译过程的第一个阶段,是编译的基础。这个阶段的任务是从左到右一个字符一个字符地读入源程序,即对构成源程序的字符流进行扫描然后根据构词规则识别单词(也称单词符号或符号)。从左到右逐个字符对构成源程序的字符串进行扫描,依据词法规则,识别出一个一个的标记(token),把源程序变为等价的标记串序列。执行词法分析的程序称为词法分析器,也称为扫描器。本例题是一个词法分析的设计,采用C++代码实现。 希望大家复习回顾以前学习的《C++程序设计》课程相关知识。
一、设计内容和要求 1、设计内容 对C语言的一个子集设计并实现一个简单的词法分析器,掌握利用状态转换图设计词法分析器的基本方法。
2、设计要求 利用该词法分析器完成对源程序字符串的词法分析。输出形式是源程序的单词符号二元式的代码,并保存到文件中。 (1) 假设该语言中的单词符号及种别编码如下表所示。 单词符号及种别编码 单词符号 种别编码 单词符号 种别编码 main 1 [ 28 int 2 ] 29 char 3 { 30 2
if 4 } 31 else 5 , 32 for 6 : 33 while 7 ; 34 标识符ID 10 > 35 整型常数NUM 20 < 36 = 21 >= 37 + 22 <= 38 - 23 == 39 * 24 != 40 / 25 & 41 ( 26 && 42 ) 27 || 43 (2) 关键字main int char if else for while都是小写并都是保留字。 (3)算符和界符 = + - * / & < <= > >= == != && || , : ; { } [ ] ( ) ID和NUM的正规定义式为: ID→letter(letter | didit)* NUM→digit digit* letter→a | … | z | A | … | Z digit→ 0 | … | 9 如果关键字、标识符和常数之间没有确定的算符或界符作间隔,则至少用一个空格作间隔。空格由空白、制表符和换行符组成。
二、设计原理 1、 符号分类 程序语言的单词符号一般分为以下五种: 关键字 标识符 常数 运算符 界符
2、词法分析器的二元输出 (单词种别,单词符号的属性值) 单词种别用整数编码,关键字一字一种,标识符统归为一种,常数一种,各种符号各一种。 3
3、正规式和状态转换图 三、 程序设计 1、 总体模块设计 /*用来存储目标文件名*/ string file_name;
/*提取文本文件中的信息。*/ string GetText();
/*获得一个单词符号,从位置i开始查找。 4
//并且有一个引用参数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);
/*此函数将一个pair数组输出到一个文件中*/ void OutFile(vector > v);
/*此函数接受一个字符串数组,对它进行词法分析,返回一个pair型数组*/ vector > analyst(vector vec);
/*此函数判断传递的参数是否为关键字,是的话,返回真,反之返回假*/ bool IsKey(string str);
2 、各模块设计 1.首先根据上面单词符号表及ID和NUM的正规定义式,构造出状态转换图; 2.定义相关的变量和数据结构。关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。如能查到匹配的单词,则该单词为关键字,否则为一般标识符。关键字表为一个字符串数组,其描述如下: char KEY_WORDS[7]={″main″,″int″,″char″,″if″,″else″,″for″,″while″}; 用以存放单词符号二元式的数据结构可如下定义: class Word_Analyzer { public: char Content[MAXLENGTH] ; int val ; void print( ); } ;
3.按照编译程序一遍扫描的要求,把词法分析器Scaner作为一个独立的子程序来设计,通过对Scaner的反复调用识别出所有的单词符号; 4.当Scaner识别出一个单词符号时,则将该单词符号的二元式写入到输出文件中。若Scaner无法识别出一个单词符号时,则调用错误处理程序PrintError,显示当前扫描 5
到的字符及其所在行、列位置,并跳过该字符重新开始识别单词符号。 四、 程序测试 1、正常测试 测试该设计词法分析器,可对下面的源程序进行词法分析: main() { int i = 10; while(i) i = i - 1; } 输出如下二元式代码序列: (1,main) (26,() (27,)) (30,{) (2,int) (10,i) (21,=) (20,10) (34,;) (7,while) (26,() (10,i) (27,)) (10,i) (21, =) (10,i) (23,-) (20,1) (34,;) (31,})
五、 结论 该词法分析器功能良好,可以完成预定的要求。
六、参考文献 《程序设计语言编译原理》 陈火旺 《C++程序设计》 谭浩强
七、附录:
程序清单: #include #include #include #include
using namespace std; /*用来存储目标文件名*/ 6
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);
/*此函数将一个pair数组输出到一个文件中*/ void OutFile(vector > v);
/*此函数接受一个字符串数组,对它进行词法分析,返回一个pair型数组*/ vector > analyst(vector vec);
/*此函数判断传递的参数是否为关键字,是的话,返回真,反之返回假*/ bool IsKey(string str);
int main() {
string com1=" "; string com2="\n"; string fileline=GetText(); int begin=0,end=0; vector array; do { begin=DeleteNull(fileline,begin); string nowString; nowString=GetWord(fileline,begin,end); if(end==-1) break; if(nowString.compare(com1)&&nowString.compare(com2))