c语言实现语法分析器
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验报告
姓名:张静学号: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是辅助定义
描述词法的正规式
Letter = [a-zA-Z]
Digit = [0-9]
COMMENT =“//”|“--”
WHITE_SPACE =(“”|\t|\n)+
SEMICO =“;”
L_BRACKET = “(”
R_BRACKET = “)”
COMMA = “,”
PLUS = “ +”
MINUS = “-”
MUL =“ *”
DIV =“ /”
POWER =“ **”
CONST_ID =digit+(“.”digit*)?
ID =letter+(letter|digit)*
用于我们是手工构造词法分析器,而正规越少越便于程序的编写,因此设计上采用相同模式的记号公用一个正规式的方法。常数的字面值部分设计为CONST_ID, 而常量名则合并到ID
中。但这却带来一个问题,函数绘图语言中的保留字、常量名、参数名,以及函数名均被识别为ID, 当时别出ID时,如何再仔细分它们?为解决上述问题,我们可以设计一个预定义的符号表
3、区分记号的符号表
将所有符合ID模式的保留字、常量名、参数名和函数名等均放进符号表中,具体内容如下:
static Token TokenTab[]= //符号表内容
{
{CONST_ID, "PI", 3.1415926, NULL},
{CONST_ID, "E", 2.71828, NULL},
{T, "T", 0.0, NULL},
{FUNC, "SIN", 0.0, sin},
{FUNC, "COS", 0.0, cos},
{FUNC, "TAN", 0.0, tan},
{FUNC, "LN", 0.0, log},
{FUNC, "EXP", 0.0, exp},
{FUNC, "SQRT", 0.0, sqrt},
{ORIGIN, "ORIGIN", 0.0, NULL},
{SCALE, "SCALE", 0.0, NULL},
{ROT, "ROT", 0.0, NULL},
{IS, "IS", 0.0, NULL},
{FOR, "FOR", 0.0, NULL},
{FROM, "FROM", 0.0, NULL},
{TO, "TO", 0.0, NULL},
{STEP, "STEP", 0.0, NULL},
{DRAW, "DRAW", 0.0, NULL}, };
当词法分析器识别出一个ID时,就可以通过查找符号表来确定具体是哪一个记号。
4、正规式的DFA
根据上述的正规式和DFA的构造算法,可以得到最终的简化DFA如图:
三、解决方案
1、词法分析器的程序框架
根据上述DFA,可以得到程序框架如下:
struct Token token={ERRTOKEN, “”, 0.0, NULL}; // 用于返回记号
token.lexeme = TokenBuffer; // 记号的字符指针指向字符缓冲区
char =GetChar(); // 从源文件中读取一个字符