编译原理 实验 词法分析 程序源码
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#define MAX_KEYWORD 100 //关键字个数
#define MAX_OPERATE 50
//运算符个数
#define MAX_SEPARAROR 20 //分隔符个数
string keyword[MAX_KEYWORD] =
{"include", "main",
"void",
"using", "namespace",
csu
return true; }
/* * 主函数 */
int main() {
string buffer = ""; string token = ""; char ch = 's';
FILE *fp = NULL; fp = fopen("input.txt", "r");
//如果打开文件失败 if(fp==NULL) {
};
char separator[MAX_SEPARAROR] =
{' ', ',', ';', '{', '}', '(', ')', '\"',
'\'', '[', ']', '#', '\n', '\t'
};
/* * 是否为分隔符 */
csu
bool isSeparator(char ch) {
"extern", "default","friend", "try",
"throw",
"typedef", "virtual" };
char operate[MAX_OPERATE] =
{'+', '-', '*', '/', '%', '=', '<', '>',
'|', '&', '!', '^'
i++; } i += 2; } else { //输出运算符
csu
cout<<"(4, \""<<buffer[i]<<"\")"<<endl; //$$$$$判断运算符是否为符合运算符,如+=, *=等 if ( isOperate(buffer[i+1]) ) {
cout<<"(4, \""<<buffer[i+1]<<"\")"<<endl; i++; } } } //既非分隔符,又非运算符,则把字符 ch 加到字符串 token 中 else { token += buffer[i]; } }
csu
{ if (ch == operate[i]) { return true; }
} return false; }
/* * 是否为关键字 */
bool isKeyword(string str) {
for (int i=0; i<MAX_KEYWORD; i++) {
if ( !str.compare(keyword[i]) ) {
1. 定义部分:定义常量、变量、数据结构。 2. 初始化:从文件将源程序全部输入到字符缓冲区中。 3. 取单词前:去掉多余空白。 4. 取单词:利用实验一的成果读出单词的每一个字符,组成单词,分析
类型。 5. 显示结果。
csu
程序源代码: #include<iostream> #include<fstream> #include<string> using namespace std;
五、实验报告要求
详细说明你的程序的设计思路和实现过程。用有限自动机或者文法的形式 对词法定义做出详细说明,说明词法分析程序的工作过程,说明错误处理的实 现。
参考资料
一、程序要求
1、以下面一段程序为例
main() {
int a,b; a = 10; b = a + 20; }
2、需要识别的词
1. 关键字:if、int、for、while、do、return、break、continue;单 词种别码为 1。
csu
cout<<"(3, \""<<token<<"\")"<<endl; token = ""; } } //token 既非关键字,又非常量,则判断为标识符,输出 token 并置空 else { if (token.size() != 0) { cout<<"(2, \""<<token<<"\")"<<endl; token = ""; } }
"sizeof", "const", "static", "const_cast",
"if",
"else",
"while", "do",
"continue",
csu
"for",
"goto",
"break", "switch", "case",
"return",
"class", "this",
"public", "private", "protected",
//判断是否为单行注释 if (buffer[i] == '/' && buffer[i+1] =='/') {
//直到这一行结束为止
csu
while (buffer[i] != '\n') {
i++; } i += 2; } else if (buffer[i] == '/' && buffer[i+1] =='*') { //直到遇见*/为止 while ( !(buffer[i] == '*' && buffer[i+1] == '/') ) {
for (int i=0; i<MAX_SEPARAROR; i++) {
if (ch == separator[i]) {
return true; } } return false; }
/* * 是否为运算符 */
bool isOperate(char ch) {
for (int i=0; i<MAX_OPERATE; i++)
csu
(4,”+”)
(3,”20”)
(5,”;”)
(5,”}“)
二、程序设计思路
这里以开始定义的 C 语言子集的源程序作为词法分析程序的输入数据。在 词法分析中,自文件头开始扫描源程序字符,一旦发现符合“单词”定义的源 程序字符串时,将它翻译成固定长度的单词内部表示,并查、填适当的信息表。 经过词法分析后,源程序字符串(源程序的外部表示)被翻译成具有等长信息 的单词串(源程序的内部表示),并产生两个表格:常数表和标识符表,它们分 别包含了源程序中的所有常数和所有标识符。
//如果是分隔符,判断 token 并输出,并判断该分隔符是否为空格,换行符和 //制表符,如是则跳过,如不是则输出 if ( isSeparator(buffer[i]) ) {
csu
//判断 token 是否为关键字,若是则输出 token 并置空 if ( isKeyword(token) ) {
csu
return true; } } return false; }
/* * 是否为常量 */
bool isConstant(string str) {
for (int i=0; i<str.size(); i++) {
if ( str[i]<'0' || str[i]>'9' ) {
return false; } }
"int",
"long",
"short", "double", "float",
"char", "wchar_t", "true",
"false", "bool",
"signed", "unsigned", "define",
"struct","enum", "union", "new",
"de来自百度文库ete",
2. 标识符;单词种别码为 2。 3. 常数为无符号整形数;单词种别码为 3。
csu 4. 运算符包括:+、-、*、/、=、 、<、 =、<=、!= ;单词种别码为 4。 5. 分隔符包括:,、;、{、}、(、); 单词种别码为 5。 3、程序输出形式 要求输出下面的形式: (2,”main”) (5,”(“) (5,”)“) (5,”{“) (1,”int”) (2,”a”) (5,”,”) (2,”b”) (5,”;”) (2,”a”) (4,”=”) (3,”10”) (5,”;”) (2,”b”) (4,”=”) (2,”a”)
if (token.size() != 0) {
cout<<"(1, \""<<token<<"\")"<<endl; token = ""; } } //判断 token 是否为常量,若是则输出 token 并置空 else if ( isConstant(token) ) { if (token.size() != 0) {
csu
cout<<"open file failed!"<<endl; exit(1); }
//从文件将源程序全部输入到字符缓冲区中 while((ch = fgetc(fp)) != EOF) {
buffer += ch; } cout<<buffer<<endl;
//词法分析过程 for(int i=0; i<buffer.size(); i++) {
从输入的源程序中,识别出各个具有独立意义的单词,即关键字、标识符、 常数、运算符、界符。并依次输出各个单词的内部编码及单词符号自身值。(遇 到错误时可显示“Error”,然后跳过错误部分继续显示)
三、实验要求:
1. 对单词的构词规则有明确的定义; 2. 编写的分析程序能够正确识别源程序中的单词符号; 3. 识别出的单词以<种别码,值>的形式保存在符号表中,正确设计和维
cout<<"(5, \""<<buffer[i]<<"\")"<<endl; }
csu
} //如果是运算符,判断 token 并输出,且输出该运算符 else if ( isOperate(buffer[i]) ) {
//判断 token 是否为关键字,若是则输出 token 并置空 if ( isKeyword(token) ) {
csu
//token 既非关键字,又非常量,则判断为标识符,输出 token 并置空 else {
if (token.size() != 0) {
cout<<"(2, \""<<token<<"\")"<<endl; token = ""; } }
//输出分隔符,空格、换行符、制表符除外 if (buffer[i] == ' ' || buffer[i] == '\n' || buffer[i] == '\t') { } else {
护符号表; 4. 对于源程序中的词法错误,能够做出简单的错误处理,给出简单的错
误提示,保证顺利完成整个源程序的词法分析;
四、实验步骤
1. 定义目标语言的可用符号表和构词规则; 2. 依次读入源程序符号,对源程序进行单词切分和识别,直到源程序结
csu 束; 3. 对正确的单词,按照它的种别以<种别码,值>的形式保存在符号表中; 4. 对不正确的单词,做出错误处理。
实验一 词法分析程序设计与实现
一、实验目的
加深对词法分析器的工作过程的理解;加强对词法分析方法的掌握;能够 采用一种编程语言实现简单的词法分析程序;能够使用自己编写的分析程序对 简单的程序段进行词法分析。
二、实验内容
自定义一种程序设计语言,或者选择已有的一种高级语言,编制它的词法 分析程序。词法分析程序的实现可以采用任何一种编程语言和编程工具。
return 0; }
if (token.size() != 0) {
cout<<"(1, \""<<token<<"\")"<<endl; token = ""; } } //判断 token 是否为常量,若是则输出 token 并置空 else if ( isConstant(token) ) { if (token.size() != 0) { cout<<"(3, \""<<token<<"\")"<<endl; token = ""; } }