编译原理课程设计报告
课题名称:编译原理课程设计
C-语言词法与语法分析器的实现
提交文档学生姓名:
提交文档学生学号:
同组成员名单:
指导教师姓名:
指导教师评阅成绩:
指导教师评阅意见:
.
.
提交报告时间:年月日
C-词法与语法分析器的实现
1.课程设计目标
(1)题目实用性
C-语言拥有一个完整语言的基本属性,通过编写C-语言的词法分析和语法分析,对于理解编译原理的相关理论和知识有很大的作用。通过编写C-语言词法和语法分析程序,能够对编译原理的相关知识:正则表达式、有限自动机、语法分析等有一个比较清晰的了解和掌握。(2)C-语言的词法说明
①语言的关键字:
else if int return void while
所有的关键字都是保留字,并且必须是小写。
②专用符号:
+ - * / < <= > >= == != = ; , ( ) [ ] { } /* */
③其他标记是ID和NUM,通过下列正则表达式定义:
ID = letter letter*
NUM = digit digit*
letter = a|..|z|A|..|Z
digit = 0|..|9
注:ID表示标识符,NUM表示数字,letter表示一个字母,digit表示一个数字。
小写和大写字母是有区别的。
④空格由空白、换行符和制表符组成。空格通常被忽略。
⑤注释用通常的c语言符号/ * . . . * /围起来。注释可以放在任何空白出现的位置(即注释不能放在标记内)上,且可以超过一行。注释不能嵌套。
(3)程序设计目标
能够对一个程序正确的进行词法及语法分析。
2.分析与设计
(1)设计思想
a.词法分析
词法分析的实现主要利用有穷自动机理论。有穷自动机可用作描述在输入串中识别模式的过程,因此也能用作构造扫描程序。通过有穷自动机理论能够容易的设计出词法分析器。b.语法分析
语法分析采用递归下降分析。递归下降法是语法分析中最易懂的一种方法。它的主要原理是,对每个非终结符按其产生式结构构造相应语法分析子程序,其中终结符产生匹配命令,而非终结符则产生过程调用命令。因为文法递归相应子程序也递归,所以称这种方法为递归子程序下降法或递归下降法。其中子程序的结构与产生式结构几乎是一致的。
(2)程序流程图
程序主流程图:
词法分析: 语法分析:
读取程序
对输入的字符进行匹配判断
对应输出各行代码的词法分析结果
读取程序
进行递归下降分析匹配或建立树
输出程序对
应的语法树
Start
是否为num
是否为dight
Num
是否为id
是否为alpha
ID
是否为>,<.,!,=
是否为=
单符号
双符号
是否为+,-,*等专用符号
专用符号
是否为/
是否为*
是否为*
是否为/
错误
结果over
是 否
否
是
否
否
是
是
否
是
否
否
是
是
是
是
否
否
否
3.程序代码实现
整个词法以及语法的程序设计在一个工程里面,一共包含了8个文件,分别为main.cpp、parse.cpp、scan.cpp、util.cpp、scan.h、util.h、globals.h、parse.h,其中scan.cpp和scan.h为词法分析程序。
以下仅列出各个文件中的核心代码:
Main.cpp
#include "globals.h"
#define NO_P ARSE FALSE
#include "util.h"
#if NO_PARSE
#include "scan.h"
#else
#include "parse.h"
#endif
int lineno=0;
FILE * source;
FILE * listing;
FILE * code;
int EchoSource = TRUE;
int TraceScan=TRUE;
int TraceParse=TRUE;
int Error = FALSE;
int main(int argc,char * argv[])
{
TreeNode * syntaxTree;
char pgm[120];
scanf("%s",pgm);
source=fopen(pgm,"r");
if(source==NULL)
{
fprintf(stderr,"File %s not found\n",pgm);
exit(1);
}
listing = stdout;
fprintf(listing,"\nC COMPILA TION: %s\n",pgm); #if NO_PARSE
while(getToken()!=ENDFILE);
#else
syntaxTree = parse();
if(TraceParse){
fprintf(listing,"\nSyntaxtree:\n");
printTree(syntaxTree);
}
#endif
fclose(source);
return 0;
}
Parse.cpp
#include "globals.h"
#include "util.h"
#include "scan.h"
#include "parse.h"
static TokenType token; /* holds current token */
/* function prototypes for recursive calls */
static TreeNode * declaration_list(void);
static TreeNode * declaration(void);
static TreeNode * params(void);
static TreeNode * param_list(void);
static TreeNode * param(void);
static TreeNode * compound_stmt(void);
static TreeNode * local_declarations(void);
static TreeNode * statement_list(void);
static TreeNode * statement(void);
static TreeNode * expression_stmt(void);
static TreeNode * if_stmt(void);
static TreeNode * while_stmt(void);
static TreeNode * return_stmt(void);
static TreeNode * expression(void);
static TreeNode * var(void);
static TreeNode * simple_exp(void);
static TreeNode * additive_expression(void);
static TreeNode * term(void);
static TreeNode * factor(void);
static TreeNode * args(void);
static TreeNode * arg_list(void);
static void syntaxError(char * message)
{ fprintf(listing,"\n>>> ");
fprintf(listing,"Syntax error at line %d: %s",lineno,message); Error = TRUE;
}
/*判断读取的字符*/
static void match(TokenType expected)
{
if(token==expected)
{
token=getToken( );
}
else
{
syntaxError("unexpected token -> ");
printToken(token,tokenString);
fprintf(listing," ");
}
}
/*进行语法分析,构建语法树*/
TreeNode * declaration_list(void)
{
TreeNode * t= declaration();
TreeNode * p= t;
while ((token==INT) || (token==VOID) )
{
TreeNode *q = declaration();
if (q!=NULL) {
if (t==NULL) t = p = q;
else /* now p cannot be NULL either */
{
p->sibling = q;
p = q;
}
}
}
return t;
}
TreeNode * declaration(void)
{ TreeNode * t = NULL;
switch (token)
{
case VOID :
case INT :
t = newStmtNode(DecK);
if(token == INT)
t->type =Integer;
else
t->type = V oid;
match(token);
switch (token)
{
case ID:
t->https://www.wendangku.net/doc/f31157796.html, = copyString(tokenString);
t->kind.stmt = V arDK;
match(ID);
switch (token)
{
case LZKH:
t->kind.stmt = V arDK;
t->type = IntArray;
match(LZKH);
match(NUM);
match(RZKH);
match(SEMI);
break;
case LPAREN:
t->kind.stmt = FunDK;
match(LPAREN);
t->child[0] = params();
match(RP AREN);
t->child[1] = compound_stmt();
break;
default: match(SEMI);break;
}
break;
default:syntaxError("unexpected token -> ");
printToken(token,tokenString);
token = getToken();
break;
}
break;
default : syntaxError("unexpected token -> ");
printToken(token,tokenString);
token = getToken();
break;
} /* end case */
return t;
}
TreeNode * params(void)
{
TreeNode * t = NULL;
if(token == VOID)
{
match(token);
t = newStmtNode(ParamList);
t->child[0] = newStmtNode(ParamK);
t->child[0]->type = V oid;
}
else if(token == RP AREN)
t=NULL;
else
{
t = param_list();
}
return t;
}
TreeNode * param_list(void)
{
TreeNode * t = newStmtNode(ParamList);
int i = 1;
t->child[0] = param();
while(token != RP AREN)
{
match(DOT);
t->child[i] = param();
i++;
}
return t;
}
TreeNode * param(void)
{
TreeNode * t = NULL;
match(INT);
t= newStmtNode(ParamK);
t->type=Integer;
t->https://www.wendangku.net/doc/f31157796.html,=copyString(tokenString);
match(ID);
if(token == LZKH)
{
t->type=IntArray;
match(LZKH);
match(RZKH);
}
return t;
}
TreeNode * compound_stmt(void)
{
TreeNode * t = newStmtNode(ComK);
match(LDKH);
t->child[0] = local_declarations();
t->child[1] = statement_list();
match(RDKH);
return t;
}
TreeNode * local_declarations(void)
{
TreeNode * t = newStmtNode(LocalDecK);
int i=0;
while(token == INT || token == VOID)
{
t->child[i] = declaration();
i++;
}
return t;
}
TreeNode * statement_list(void)
{
TreeNode * t = newStmtNode(StmtList);
int i=0;
while(token != RDKH)
{
t->child[i] =statement();
i++;
}
return t;
}
TreeNode * statement(void)
{
TreeNode * t ;
switch (token) {
case IF : t = if_stmt(); break;
case WHILE : t = while_stmt(); break;
case ID :
case SEMI:
t = expression_stmt(); break;
case RETURN : t = return_stmt(); break;
case LDKH : t=compound_stmt();break;
default : syntaxError("unexpected token -> ");
printToken(token,tokenString);
token = getToken();
break;
} /* end case */
return t;
}
TreeNode * expression_stmt(void)
{
TreeNode * t = newStmtNode(ExpstmtK);
if(token == SEMI)
match(SEMI);
else
{
t = expression();
match(SEMI);
}
return t;
}
TreeNode * if_stmt(void)
{
TreeNode * t = newStmtNode(IfK);
if(t!=NULL)
{
match(IF);
match(LPAREN);
t->child[0] = expression();
match(RP AREN);
t->child[1] = statement();
if (token==ELSE)
{
match(ELSE);
if (t!=NULL) t->child[2] = newStmtNode(ElseK);
t->child[2]->child[0] = statement();
} }
return t;
}
TreeNode * while_stmt(void)
{
TreeNode * t = newStmtNode(WhileK);
match(WHILE);
match(LPAREN);
if (t!=NULL) t->child[0] = expression();
match(RP AREN);
if (t!=NULL) t->child[1] = statement();
return t;
}
TreeNode * return_stmt(void)
{
TreeNode * t = newStmtNode(RetK);
if(token == RETURN)
match(RETURN);
if(token == SEMI)
match(SEMI);
else
{
t->child[0] = expression();
match(SEMI);
}
return t;
}
TreeNode * expression(void)
{
TreeNode * t = simple_exp();
return t;
}
TreeNode* var(void)
{
TreeNode* t = newExpNode(IdK);
if ((t!=NULL) && (token==ID))
t->https://www.wendangku.net/doc/f31157796.html, = copyString(tokenString);
match(ID);
if(token == LZKH)
{
match(token);
t->type = ArrayUnit;
t->child[0] = expression();
match(RZKH);
}
return t;
}
TreeNode * simple_exp(void)
{
TreeNode * t = additive_expression();
if(t!=NULL){
if (token == L T || token == LE|| token == MT || token == ME||token ==EQ||token ==NEQ) {
TreeNode * p = newExpNode(OpK);
if(p!=NULL)
{
p->attr.op = token;
p->child[0] = t;
match(token);
p->child[1] = additive_expression();
t=p;
}
}
}
return t;
}
TreeNode* additive_expression(void)
{
TreeNode * t = term();
while(token == PLUS || token == MINUS)
{
TreeNode * p = newExpNode(OpK);
p->attr.op = token;
p->child[0] = t;
match(token);
p->child[1] = term();
t = p;
}
return t;
}
TreeNode * term(void)
{
TreeNode * t = factor();
while ((token==TIMES)||(token==OVER))
{
编译原理 C语言词法分析器 一、实验题目 编制并调试C词法分析程序。 a.txt源代码: ?main() { int sum=0 ,it=1;/* Variable declaration*/ if (sum==1) it++; else it=it+2; }? 设计其词法分析程序,能识别出所有的关键字、标识符、常数、运算符(包括复合运算符,如++)、界符;能过滤掉源程序中的注释、空格、制表符、换行符;并且能够对一些词法规则的错误进行必要的处理,如:标识符只能由字母、数字与下划线组成,且第一个字符必须为字母或下划线。实验要求:要给出所分析语言的词法说明,相应的状态转换图,单词的种别编码方案,词法分析程序的主要算法思想等。 二、实验目的 1、理解词法分析在编译程序中的作用; 2、掌握词法分析程序的实现方法与技术; 3、加深对有穷自动机模型的理解。 三、主要函数 四、设计 1、主函数void main ( ) 2 3
4、整数类型判断函数 char *key1[]={" ","(",")","[","]","{","}",",",";","'"}; /*分隔符表*/
char *key2[]={" ","+","-","*","/","%","<",">","==",">=","<=","!=","!","&&","||","<<",">>","~","|","^","&","=","?:","->","++","--","、","+=","-=","*=","/="}; /*运算符表*/ int xx0[35],xx1[10],xx2[31]; int temp_key3=0,temp_c40=0,temp_c41=0,temp_c42=0,temp_c43=0; /******* 初始化函数*******/ void load() { int mm; for (mm=0;mm<=34;mm++) { xx0[mm]=0; } for (mm=0;mm<=9;mm++) { xx1[mm]=0; } for (mm=0;mm<=30;mm++) { xx2[mm]=0; } FILE *floading; if ((floading=fopen("key0、txt","w"))==NULL) { printf("Error! Can't create file : key0、txt"); return; } fclose (floading); /*建立保留字表文件:key0、txt*/ if ((floading=fopen("key1、txt","w"))==NULL) { printf("Error! Can't create file : key1、txt"); return; } /*建立分隔符表文件:key1、txt*/ if ((floading=fopen("key2、txt","w"))==NULL) { printf("Error! Can't create file : key2、txt"); return; } fclose(floading); /*建立运算符表文件:key2、txt*/ if ((floading=fopen("key3、txt","w"))==NULL) { printf("Error! Can't create file : key3、txt");
#include
我自己写的个词法分析程序可以完成一个非常非常基本的C语言词法分析.自己鼓励下自己 :-) #include
C语言编译器的设计与实现 01计算机4班18号任春妍2号陈俊我们设计的编译程序涉及到编译五个阶段中的三个,即词法分析器、语法分析器和中间代码生成器。编译程序的输出结果包括词法分析后的二元式序列、变量名表、状态栈分析过程显示及四元式序列程序,整个编译程序分为三部分: (1) 词法分析部分 (2) 语法分析处理及四元式生成部分 (3) 输出显示部分 一.词法分析器设计 由于我们规定的程序语句中涉及单词较少,故在词法分析阶段忽略了单词输入错误的检查,而将编译程序的重点放在中间代码生成阶段。词法分析器的功能是输入源程序,输出单词符号。我们规定输出的单词符号格式为如下的二元式:(单词种别,单词自身的值) #define ACC -2 #define syl_if 0 #define syl_else 1 #define syl_while 2 #define syl_begin 3 #define syl_end 4 #define a 5 #define semicolon 6 #define e 7 #define jinghao 8 #define s 9 #define L 10 #define tempsy 11 #define EA 12 #define EO 13 #define plus 14 #define times 15 #define becomes 16 #define op_and 17 #define op_or 18 #define op_not 19 #define rop 20 #define lparent 21 #define rparent 22 #define ident 23 #define intconst 24
编译原理课程设计报告 题目: 学院: 教师: 姓名: 学号: 班级: 评分: 签字:
编译原理课程设计一:设计c语言的词法分析器 一、实验目的 了解高级语言单词的分类,了解状态图以及如何表示并识别单词规则,掌握状态图到识别程序的编程,加深对词法原理的理解。 二、实验要求 了解高级语言单词的分类,了解状态图以及如何表示并识别单词规则,掌握状态图到识别程序的编程。 三、实验设计 3.1.单词分类及表示 3.1.1 C语言的子集分类 (1)标识符:以字母开头的字母数字串 (2)整数或浮点型。 (3)保留字:for,while,do,else,if,static,int,sizeof,break,continue (4)运算符:+,-,*,/,%,>,<,=,!=,==,<=,>=,!,&,&&,||; (5)界符:"(",")",",",":",";","{","}" 3.1.2单词二元组(单词分类号、单词自身值)
3.2 词法分析器的设计 3.2.1算法设计 3.2.1.1概要设计 从文件中逐个读取字符,只要这五大类的状态序列则继续读取,否则回退字符,在对应类别进行查找,输出单元二次组至另一文件夹。
3.2.1.2状态图设计 3.2.2输入输出设计 输入:通过文件指针从文件中一个一个读取字符 输出:输出单词二元组至文件。格式为(种别码,值) 3.2.3主要函数 void Getchar(FILE *fp ) //读入一个字符 void GetBC(FILE *fp)//读入一个非空字符 void contacat()//连接字符 int letter()//判断是否为字母 int digit()//判断是否为字母 void retract(FILE *fp,char *c)//回退 int reserve (char **k)//处理保留字 int sysmbol(identifier *id)//处理标识符,查找符号表并存放位置若没有则添加int constant(constnumber *con)//存入常数表,并返回它在常数表中的位置
编译原理课程设计报告 设计题目编译代码生成器设计 学生姓名 班级 学号 指导老师 成绩
一、课程设计的目的 编译原理课程兼有很强的理论性和实践性,是计算机专业的一门非常重要的专业基础课程,它在系统软件中占有十分重要的地位,是计算机专业学生的一门主修课。为了让学生能够更好地掌握编译原理的基本理论和编译程序构造的基本方法和技巧,融会贯通本课程所学专业理论知识,提高他们的软件设计能力,特设定该课程的课程设计,通过设计一个简单的PASCAL语言(EL语言)的编译程序,提高学生设计程序的能力,加深对编译理论知识的理解与应用。 二、课程设计的要求 1、明确课程设计任务,复习编译理论知识,查阅复印相关的编译资料。 2、按要求完成课程设计内容,课程设计报告要求文字和图表工整、思路清晰、算法正 确。 3、写出完整的算法框架。 4、编写完整的编译程序。 三、课程设计的内容 课程设计是一项综合性实践环节,是对平时实验的一个补充,课程设计内容包括课程的主要理论知识,但由于编译的知识量较复杂而且综合性较强,因而对一个完整的编译程序不适合平时实验。通过课程设计可以达到综合设计编译程序的目的。本课程的课程设计要求学生编写一个完整的编译程序,包括词法分析器、语法分析器以及实现对简单程序设计语言中的逻辑运算表达式、算术运算表达式、赋值语句、IF语句、While语句以及do…while语句进行编译,并生成中间代码和直接生汇编指令的代码生成器。 四、总体设计方案及详细设计 总体设计方案: 1.总体模块 主程序 词法分析程序语法分析 程序 中间代码 生成程序
2. 表2.1 各种单词符号对应的种别码 单词符号种别码单词符号种别码bgin 1 :17 If 2 := 18 Then 3 < 20 wile 4 <> 21 do 5 <= 22 end 6 > 23 lettet(letter|digit)* 10 >= 24 dight dight* 11 = 25 + 13 ;26 —14 ( 27 * 15 ) 28 / 16 # 0 详细设计: 4.1界面导入设计 (1)一共三个选项: ①choice 1--------cifafenxi ②choice 2--------yufafenxi ③choice 3--------zhongjiandaima (2)界面演示 图一
C语言词法分析器-内容说明注释完整-可运 行代码
1.实验目的及要求 本次实验通过用C语言设计、编制、调试一个词法分析子程序,识别单词,实现一个C语言词法分析器,经过此过程可以加深对编译器解析单词流的过程的了解。 运行环境: 硬件:windows xp 软件:visual c++6.0 2.实验步骤 1.查询资料,了解词法分析器的工作过程与原理。 2.分析题目,整理出基本设计思路。 3.实践编码,将设计思想转换用c语言编码实现,编译运行。 4.测试功能,多次设置包含不同字符,关键字的待解析文件,仔细察看运行结果,检测该分析器的分析结果是否正确。通过最终的测试发现问题,逐渐完善代码中设置的分析对象与关键字表,拓宽分析范围提高分析能力。 3.实验内容 本实验中将c语言单词符号分成了四类:关键字key(特别的将main说明为主函数)、普通标示符、常数和界符。将关键字初始化在一个字符型指针数组
*key[]中,将界符分别由程序中的case列出。在词法分析过程中,关键字表和case列出的界符的内容是固定不变的(由程序中的初始化确定),因此,从源文件字符串中识别出现的关键字,界符只能从其中选取。标识符、常数是在分析过程中不断形成的。 对于一个具体源程序而言,在扫描字符串时识别出一个单词,若这个单词的类型是关键字、普通标示符、常数或界符中之一,那么就将此单词以文字说明的形式输出.每次调用词法分析程序,它均能自动继续扫描下去,形成下一个单词,直到整个源程序全部扫描完毕,从而形成相应的单词串。 输出形式例如:void $关键字 流程图、程序 流程图:
程序:
词法分析 一、实验目的 设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。 二、实验要求 2.1 待分析的简单的词法 (1)关键字: begin if then while do end 所有的关键字都是小写。 (2)运算符和界符 : = + - * / < <= <> > >= = ; ( ) # (3)其他单词是标识符(ID)和整型常数(SUM),通过以下正规式定义: ID = letter (letter | digit)* NUM = digit digit* (4)空格有空白、制表符和换行符组成。空格一般用来分隔ID、SUM、运算符、界符和关键字,词法分析阶段通常被忽略。 2.2 各种单词符号对应的种别码: 输入:所给文法的源程序字符串。 输出:二元组(syn,token或sum)构成的序列。 其中:syn为单词种别码; token为存放的单词自身字符串; sum为整型常数。 例如:对源程序begin x:=9: if x>9 then x:=2*x+1/3; end #的源文件,经过词法分析后输出如下序列: (1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)…… 三、词法分析程序的算法思想: 算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。
3.1 主程序示意图: 主程序示意图如图3-1所示。其中初始包括以下两个方面: ⑴关键字表的初值。 关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。如能查到匹配的单词,则该单词为关键字,否则为一般标识符。关键字表为一个字符串数组,其描述如下: Char *rwtab[6] = {“begin”, “if”, “then”, “while”, “do”, “end”,}; 图3-1 (2)程序中需要用到的主要变量为syn,token和sum 3.2 扫描子程序的算法思想: 首先设置3个变量:①token用来存放构成单词符号的字符串;②sum用来整型单词;③syn用来存放单词符号的种别码。扫描子程序主要部分流程如图3-2所示。
编译原理课程设计报告 课题名称:编译原理课程设计 C-语言词法与语法分析器的实现
C-词法与语法分析器的实现 1.课程设计目标 (1)题目实用性 C-语言拥有一个完整语言的基本属性,通过编写C-语言的词法分析和语法分析,对于理解编译原理的相关理论和知识有很大的作用。通过编写C-语言词法和语法分析程序,能够对编译原理的相关知识:正则表达式、有限自动机、语法分析等有一个比较清晰的了解和掌握。(2)C-语言的词法说明 ①语言的关键字: else if int return void while 所有的关键字都是保留字,并且必须是小写。 ②专用符号: + - * / < <= > >= == != = ; , ( ) [ ] { } /* */ ③其他标记是ID和NUM,通过下列正则表达式定义: ID = letter letter* NUM = digit digit* letter = a|..|z|A|..|Z digit = 0|..|9 注:ID表示标识符,NUM表示数字,letter表示一个字母,digit表示一个数字。 小写和大写字母是有区别的。 ④空格由空白、换行符和制表符组成。空格通常被忽略。 ⑤注释用通常的c语言符号/ * . . . * /围起来。注释可以放在任何空白出现的位置(即注释不能放在标记)上,且可以超过一行。注释不能嵌套。
(3)程序设计目标 能够对一个程序正确的进行词法及语法分析。 2.分析与设计 (1)设计思想 a.词法分析 词法分析的实现主要利用有穷自动机理论。有穷自动机可用作描述在输入串中识别模式的过程,因此也能用作构造扫描程序。通过有穷自动机理论能够容易的设计出词法分析器。b.语法分析 语法分析采用递归下降分析。递归下降法是语法分析中最易懂的一种方法。它的主要原理是,对每个非终结符按其产生式结构构造相应语法分析子程序,其中终结符产生匹配命令,而非终结符则产生过程调用命令。因为文法递归相应子程序也递归,所以称这种方法为递归子程序下降法或递归下降法。其中子程序的结构与产生式结构几乎是一致的。 (2)程序流程图 程序主流程图: 词法分析: 语法分析:
/********************************************** *名称:词法分析器 *版本:1.0 *作者:** *2015/4/2 ************************************************/ #include
《编译原理课程设计》课程报告题目 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|..|9 nat=digit+ signedNat=(+|-)?nat NUM=signedNat(“.”nat)? letter = a|..|z|A|..|Z ID = letter(letter|digit|“_”)+ CHAR = 'other+' STRING = “other+”
词法分析器设计 一、问题描述 处理c语言源程序,过滤掉无用符号,判断源程序中单词的合法性,并分解出正确的单词,以二元组形式存放在文件中。 二、实验思路 1、本实验思路很简单,就是逐个匹配测试文件的每个字符与程序中所标识的符号,总共分为几个比较模块,先是字母数字模块,可以识别出C语言程序中保留字,标识符和数字,其次是运算符和界符模块,可以识别出运算符和界符,最后一个模块就是未标识的符号,此时程序会报错,然后依次循环,直到文件结束。 2、采用结构体来存储符号的类型和符号本身: struct point { char *kind; char value[10]; }; 另外采用C语言文件指针和相关函数处理待测试文件以及测试结果文件。 3、程序中的函数名指示含义:keyword----保留字,Identifier---标识符,Digit---数字,CaculatorIdentifier---运算符,PatitionIdentifier---界符 4、程序中所定义的符号采用char类型,只能对C语言中最常见的单字符的符号进行定义,如‘+’,‘<’,而对于“<=”,”>=”及“++”,“--”则不能处理。因此本程序并不能实现对所有符号的归类。 三、实验代码 #include
#include"status_stack.h" #include"symbol_instr_stack.h" #include"lr.h" //打印LR分析器的工作过程 void print(status *status_p,symbol_instr *symbol_p,symbol_instr *instr_p) { int i; out_stack(status_p); for(i=0;i<20-status_p->top;i++) printf(" "); out_stack1(symbol_p); for(i=0;i<20;i++) printf(" "); out_stack2(instr_p); printf("\n"); } //状态转换函数 int goto_char(status *status_p,symbol_instr *instr_p) { char x; int y,z; x = get_top(instr_p); y = get_top(status_p); z = get_index_char(x); return table[y][z]; } //移进--规约函数 void action(status *status_p,symbol_instr *symbol_p,symbol_instr *instr_p) { int i,j,x; char a; i = goto_char(status_p,instr_p); //规约出错 if(i == -1) printf("\n===============规约出错!================\n"); //规约成功 if(i == 12) printf("\n===============规约成功!================\n"); //移进动作 if(i>=0 && i<=11) { push(status_p,i); a = pop(instr_p); push(symbol_p,a);
实验三语法分析的C语言实现 一、实验目的 加深对语法分析器工作过程的理解;能够采用一种编程语言实现简单的语法分析程序;能够使用自己编写的分析程序对简单的程序段进行语法分析。 二、实验要求 1、在实验一(用C语言实现词法分析的程序)的基础上,实现编写语法分析程序,语法 分析程序的实现可以采用任何一种编程工具。 2、对语法规则有明确的定义; 3、编写的分析程序能够对实验一的结果进行正确的语法分析; 4、对于遇到的语法错误,能够做出简单的错误处理,给出简单的错误提示,保证顺利 完成语法分析过程; 三、实验指导1(实现算术表达式的运算) (一)准备 1.阅读课本有关章节,参考P63的表6.3优先关系表。 2.初步编制程序。 3.准备一组测试数据。 (二)程序要求 1.程序输入/输出示例: 输入如下一段C语言源程序: 3+2*(5.5-5) 输出:输出运算的结果4.0。 2. 建议:实验一的词法分析结果保存到文件input.c,实验二直接从input.c读取一个token,将用到的文法规则输出并保存到文件output.c。(注:NUM由词法分析器返回) 3.可选功能:可以根据自身的情况完善语法分析程序的错误处理功能,如对遇到的语法错误给出准确的位置和错误类型提示。 三、实验指导2(用递归下降分析器实现语法分析) (一)准备 1.阅读课本有关章节,特别是P49的代码,明确语言的语法。 2.初步编制程序。 3.准备一组测试数据。 (二)程序要求 1.程序输入/输出示例: 输入如下一段C语言源程序(实现赋值语句或者if语句或者while语句,或者都实现):main() { a = 10*(b+2); if (a>b) a=b else a=c; while (a!=0) a=3+21*a; }
实验二C-语言的词法分析器(基于Lex) 1. 课程设计目标 自动构造C-语言的的词法分析器,要求能够掌握编译原理的基本理论,,理解编译程序的基本结构,掌握编译各阶段的基本理论和技术,掌握编译程序设计的基本理论和步骤.,增强编写和调试高级语言源程序的能力,掌握词法分析的基本概念和实现方法,熟悉C-语言的各种Token。 。 2. 分析与设计 基于Parser Genarator的词法分析器构造方法 Lex输入文件由3个部分组成:定义集(definition),规则集(rule)和辅助程序集(auxiliary routine)或用户程序集(user routine)。这三个部分由位于新一行第一列的双百分号分开,因此,Lex输入文件的格式如下 {definitions} %% {rules} %% {auxiliary routines} 而且第一部分用“%{”和“%}”括起来。 第一和第三个部分为C语言的代码和函数定义,第二个部分为一些规则。 定义正则表达式如下 ID = letter letter* NUM = digit digit* Letter = a|…|z|A|…|Z Dig it = 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]+ 在Lex中的规则定义构造 定义识别保留字规则"int"|"else"|"return"|"void"|"if"|"while"
C语言词法分析器 C语言词法分析器的设计与实现一(实验目的 1(强化对系统软件综合工程实现能力、规划能力的训练; 2(加强对词法分析原理、方法和基本实现技术的理解; 二(实验内容 或 C++ )作为宿主语言完成: 用C语言( 其中具体要求: 1.使用DFA实现词法分析器的设计; 2.实现对C源程序中注释的过滤; 3.利用两对半缓冲区从文件中逐一读取单词; 4.词法分析结果属性字流存放在独立文件中; 5.统计源程序每行单词的个数和整个源文件单词个数; 6.具有报告词法错误和出错位置(源程序行号和该行字符)的功能; 7.屏幕输出属性字流,每次显示10行,按ESC可中途退出,每行有统计信息,最后有词法分析的全 部信息,包括各种属性单词的个数。 三(实验验收与评分要求 1.编写C语言词法分析器的源程序并调试通过; 2.通过测试程序的验收 (测试程序名称:Test-Lexcial); 3.提交简明扼要的书面实验报告。内容包括:FA设计;源程序主要函数功能;主要数据结构设计。 四. 验收测试用例 1.测试用例一:统一验收测试用例; #include
#include
实验五LL(1)文法识别程序设计 一、实验目的 通过LL(1)文法识别程序的设计理解自顶向下的语法分析思想。 二、实验重难点 FIRST集合、FOLLOW集合、SELECT集合元素的求解,预测分析表的构造。 三、实验内容与要求 实验内容: 1.阅读并理解实验案例中LL(1)文法判别的程序实现; 2.参考实验案例,完成简单的LL(1)文法判别程序设计。 四、实验学时 4课时 五、实验设备与环境 C语言编译环境 六、实验案例 1.实验要求 参考教材93页预测分析方法,94页图5.11 预测分析程序框图,编写表达式文法的识别程序。要求对输入的LL(1)文法字符串,程序能自动判断所给字符串是否为所给文法的句子,并能给出分析过程。 表达式文法为: E→E+T|T T→T*F|F F→i|(E) 2.参考代码
为了更好的理解代码,建议将图5.11做如下标注:
/* 程序名称:LL(1)语法分析程序*/ /* E->E+T|T */ /* T->T*F|F */ /* F->(E)|i */ /*目的: 对输入LL(1)文法字符串,本程序能自动判断所给字符串是否为所给文法的句子,并能给出分析过程。 /********************************************/ /* 程序相关说明*/ /* A=E' B=T' */ /* 预测分析表中列号、行号*/ /* 0=E 1=E' 2=T 3=T' 4=F */ /* 0=i 1=+ 2=* 3=( 4=) 5=# */ /************************************/ #include"iostream" #include "stdio.h" #include "malloc.h" #include "conio.h" /*定义链表这种数据类型参见: https://www.wendangku.net/doc/f31157796.html,/link?url=_owQzf8PRZOt9H-5oXIReh4X0ClHo6zXtRdWrdSO5YBLpKl NvkCk0qWqvFFxjgO0KzueVwEQcv9aZtVKEEH8XWSQCeVTjXvy9lxLQ_mZXeS###*/ struct Lchar{ char char_ch; struct Lchar *next; }Lchar,*p,*h,*temp,*top,*base; /*p指向终结符线性链表的头结点,h指向动态建成的终结符线性链表节点,top和base分 别指向非终结符堆栈的顶和底*/
实验报告 姓名:张静学号:13031121 【实验名称】一种绘图语言的词法分析器 【实验目的】采用c语言完成词法分析器,练习使用。 【实验内容】 一、问题描述 设计一种简单的函数绘图语言的词法分析器,该绘图语言可以提供一条循环绘图语句,图形变换语句,注释语句,他的词法分析器部分是读取源程序——字符序列,并根据构词规则将其转换为记号流。它可以完成三个任务:(1)滤掉源程序中的注释和无用的成分(如空格,TAB等);(2)输出记号,供语法分析器使用;(3)识别非法输入,并将非法输入作为出错记号提供给语法分析器,以便进行出错处理。 二、问题分析 词法分析器的构造步骤:正规式——NFA——DFA——最小DFA ——编写程序——测试。 1、记号的设计 记号一般有两部分组成:极好的类别,记号的属性。根据 函数绘图语言的特点,可以将记号设计为如下的数据结构: Struct Token
{ Token_Type type;----------类别 char* lexeme;--------------属性,原是输入的字符串double value;----------属性,若记号是常数则是常数的值 double (*FuncPtr)(double);--属性,若记号是函数则是函数指针 }; 函数绘图语言的记号类别划分如下: Enum Token_Type { ORGIN, SCALE, ROT, IS, ------------保留字 TO, STEP, DRAW, FOR, FROM,---------保留字 T,--------------------------------参数 SEMICO, L_BRACKET, R_BRACKET, COMMA--分隔符 PLUS, MINUS, MUL, DIV, POWER,------运算符 FUNC,--------------------------函数 CONST_ID,-------------------常数 NONTOKEN,-----------------空记号 ERRTOKEN-------------------出错记号 }; 2、模式的正规式表示 函数绘图语言的此法可用下是正规式集合表示,其中的letter 和digit是辅助定义 描述词法的正规式
编译原理C语言词法分析器 一、实验题目 编制并调试C词法分析程序。 a.txt源代码: ?main() { int sum=0 ,it=1;/* Variable declaration*/ if (sum==1) it++; else it=it+2; }? 设计其词法分析程序,能识别出所有的关键字、标识符、常数、运算符(包括复合运算符,如++)、界符;能过滤掉源程序中的注释、空格、制表符、换行符;并且能够对一些词法规则的错误进行必要的处理,如:标识符只能由字母、数字和下划线组成,且第一个字符必须为字母或下划线。实验要求:要给出所分析语言的词法说明,相应的状态转换图,单词的种别编码方案,词法分析程序的主要算法思想等。 二、实验目的 1、理解词法分析在编译程序中的作用; 2、掌握词法分析程序的实现方法和技术; 3、加深对有穷自动机模型的理解。 三、主要函数
四、设计 1.主函数void main ( ) 2. 初始化函数void load ( ) 3. 保留字及标识符判断函数void char_search(char *word) 4. 整数类型判断函数void inta_search(char *word)
5. 浮点类型判断函数void intb_search(char *word) 6. 字符串常量判断函数void cc_search(char *word) 7. 字符常量判断函数void c_search(char *word) 同4、5函数图 8.主扫描函数void scan ( )
五、关键代码 #include