使用C/C++语言编写PL/0编译程序的语法分析程序 预期输入输出如上

时间: 2023-07-30 09:07:01 浏览: 57
很好,PL/0语言的语法分析程序可以分为三个部分:词法分析器、语法分析器和代码生成器。下面是一个简单的C语言实现示例,其中使用了类似于递归下降的方法: ```c #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> // 定义符号表结构体 typedef struct { char name[10]; int kind; int value; int level; int addr; } Symbol; // 定义符号表数组和指针 Symbol symbol_table[100]; int symbol_ptr = 0; // 定义PL/0语言的关键字 const char *keywords[] = { "begin", "call", "const", "do", "end", "if", "odd", "procedure", "read", "then", "var", "while", "write" }; // 定义PL/0语言的符号 const char *symbols[] = { "+", "-", "*", "/", "(", ")", "=", ",", ".", "<", ">", "<=", ">=", "<>", ";", ":=" }; // 定义词法分析器 int lexical_analysis(const char *input, int *value) { char word[10] = {0}; // 保存识别的单词 int word_ptr = 0; // 单词指针 int num_flag = 0; // 标记是否是数字 int symbol_flag = 0; // 标记是否是符号 // 遍历输入字符串 for (int i = 0; i < strlen(input); i++) { // 判断是否是空格、换行符或制表符 if (isspace(input[i])) { if (num_flag) { // 如果之前是数字,则返回 *value = atoi(word); return 3; } if (symbol_flag) { // 如果之前是符号,则返回 for (int j = 0; j < sizeof(symbols) / sizeof(char *); j++) { if (strcmp(word, symbols[j]) == 0) { return j + 4; } } } word_ptr = 0; num_flag = 0; symbol_flag = 0; continue; } // 判断是否是数字 if (isdigit(input[i])) { num_flag = 1; symbol_flag = 0; word[word_ptr++] = input[i]; continue; } // 判断是否是字母 if (isalpha(input[i])) { num_flag = 0; symbol_flag = 0; word[word_ptr++] = input[i]; continue; } // 判断是否是符号 if (!isdigit(input[i]) && !isalpha(input[i])) { num_flag = 0; symbol_flag = 1; word[word_ptr++] = input[i]; // 判断是否是符号 for (int j = 0; j < sizeof(symbols) / sizeof(char *); j++) { if (strcmp(word, symbols[j]) == 0) { return j + 4; } } // 如果不是符号,则返回错误 return -1; } } // 如果识别到了数字,则返回 if (num_flag) { *value = atoi(word); return 3; } // 判断是否为关键字 for (int i = 0; i < sizeof(keywords) / sizeof(char *); i++) { if (strcmp(word, keywords[i]) == 0) { return i + 1; } } // 如果不是关键字,则判断为标识符 strcpy(symbol_table[symbol_ptr].name, word); symbol_table[symbol_ptr].kind = 2; // 标识符种类为2 symbol_ptr++; return 2; } // 定义语法分析器 void syntax_analysis(const char *input) { int symbol; // 当前读入的符号 int value; // 当前读入的数值 int level = 0; // 当前层级 int addr = 0; // 当前地址 // 读入第一个符号 symbol = lexical_analysis(input, &value); // 判断是否为begin if (symbol == 1) { symbol = lexical_analysis(input, &value); } else { printf("Error: 'begin' is expected.\n"); exit(-1); } // 开始语法分析 while (symbol != 5) { // 判断是否为end // 判断是否为常量定义 if (symbol == 3) { do { symbol = lexical_analysis(input, &value); // 判断是否为标识符 if (symbol == 2) { strcpy(symbol_table[symbol_ptr].name, input); symbol_table[symbol_ptr].kind = 1; // 常量种类为1 symbol_table[symbol_ptr].value = value; symbol_ptr++; } else { printf("Error: Identifier is expected.\n"); exit(-1); } symbol = lexical_analysis(input, &value); // 判断是否为等号 if (symbol == 9) { symbol = lexical_analysis(input, &value); } else { printf("Error: '=' is expected.\n"); exit(-1); } // 判断是否为数字 if (symbol == 3) { symbol_table[symbol_ptr - 1].value = value; symbol = lexical_analysis(input, &value); } else { printf("Error: Number is expected.\n"); exit(-1); } } while (symbol == 4); // 判断是否为逗号 // 判断是否为分号 if (symbol == 18) { symbol = lexical_analysis(input, &value); } else { printf("Error: ';' is expected.\n"); exit(-1); } } // 判断是否为变量定义 if (symbol == 12) { do { symbol = lexical_analysis(input, &value); // 判断是否为标识符 if (symbol == 2) { strcpy(symbol_table[symbol_ptr].name, input); symbol_table[symbol_ptr].kind = 3; // 变量种类为3 symbol_table[symbol_ptr].level = level; symbol_table[symbol_ptr].addr = addr; symbol_ptr++; addr++; } else { printf("Error: Identifier is expected.\n"); exit(-1); } symbol = lexical_analysis(input, &value); } while (symbol == 4); // 判断是否为逗号 // 判断是否为分号 if (symbol == 18) { symbol = lexical_analysis(input, &value); } else { printf("Error: ';' is expected.\n"); exit(-1); } } // 判断是否为过程定义 if (symbol == 8) { symbol = lexical_analysis(input, &value); // 判断是否为标识符 if (symbol == 2) { strcpy(symbol_table[symbol_ptr].name, input); symbol_table[symbol_ptr].kind = 4; // 过程种类为4 symbol_table[symbol_ptr].level = level; symbol_table[symbol_ptr].addr = addr; symbol_ptr++; addr++; } else { printf("Error: Identifier is expected.\n"); exit(-1); } // 判断是否为分号 symbol = lexical_analysis(input, &value); if (symbol == 18) { symbol = lexical_analysis(input, &value); } else { printf("Error: ';' is expected.\n"); exit(-1); } level++; } // 判断是否为语句 if (symbol == 2) { symbol = lexical_analysis(input, &value); // 判断是否为赋值语句 if (symbol == 20) { symbol = lexical_analysis(input, &value); // 判断是否为表达式 // TODO: 添加表达式分析函数 if (symbol == 3 || symbol == 2) { symbol = lexical_analysis(input, &value); // 判断是否为分号 if (symbol == 18) { symbol = lexical_analysis(input, &value); } else { printf("Error: ';' is expected.\n"); exit(-1); } } else { printf("Error: Expression is expected.\n"); exit(-1); } } else { printf("Error: ':=' is expected.\n"); exit(-1); } } } printf("Syntax analysis finished.\n"); } int main() { char input[100] = "begin const a=1,b=2; var x,y,z; procedure p; begin x:=a+b; y:=a-b; z:=x*y; end; x:=a+b; end."; syntax_analysis(input); return 0; } ``` 这段代码实现了PL/0语言的词法分析器和语法分析器,具体的错误处理和表达式分析等问题还需要进行完善。可以通过修改输入字符串来测试程序的正确性。

相关推荐

最新推荐

recommend-type

词法分析示例程序(C语言编写,针对PL/0语言)

词法分析阶段是编译过程的第一个阶段,是编译的基础。这个阶段的任务是从左到右一个字符一个字符地读入源程序,即对构成源程序的字符流进行扫描...PL/0语言是Pascal语言的子集,它具备一般高级程序设计语言的典型特点。
recommend-type

C/C++语言宏定义使用实例详解

主要介绍了 C/C++语言宏定义使用实例详解的相关资料,需要的朋友可以参考下
recommend-type

编译:语法分析程序报告(源程序) c/c++

编译原理 语法分析程序 c/c++编译原理 语法分析程序 c/c++编译原理 语法分析程序 c/c++
recommend-type

编译原理实验报告分析PL0词法分析程序

学习PL0程序的词法分析程序GetSym的实现过程 结合具体的程序了解词法分析过程  独立完程序的分析过程  自己跟踪程序的执行过程  记录程序的执行过程  记录程序的运行结果
recommend-type

表驱动LL(1)语法分析程序.docx

(1)根据LL(1)分析法编写一个语法分析程序,输入文法的FIRST(α)和FOLLOW(U)集,由程序自动生成文法的预测分析表。 (2)所开发的程序可适用于不同的文法和任意输入串,且能判断该文法是否为LL(1)文法。 (3)对输入的...
recommend-type

RTL8188FU-Linux-v5.7.4.2-36687.20200602.tar(20765).gz

REALTEK 8188FTV 8188eus 8188etv linux驱动程序稳定版本, 支持AP,STA 以及AP+STA 共存模式。 稳定支持linux4.0以上内核。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

:YOLOv1目标检测算法:实时目标检测的先驱,开启计算机视觉新篇章

![:YOLOv1目标检测算法:实时目标检测的先驱,开启计算机视觉新篇章](https://img-blog.csdnimg.cn/img_convert/69b98e1a619b1bb3c59cf98f4e397cd2.png) # 1. 目标检测算法概述 目标检测算法是一种计算机视觉技术,用于识别和定位图像或视频中的对象。它在各种应用中至关重要,例如自动驾驶、视频监控和医疗诊断。 目标检测算法通常分为两类:两阶段算法和单阶段算法。两阶段算法,如 R-CNN 和 Fast R-CNN,首先生成候选区域,然后对每个区域进行分类和边界框回归。单阶段算法,如 YOLO 和 SSD,一次性执行检
recommend-type

info-center source defatult

这是一个 Cisco IOS 命令,用于配置 Info Center 默认源。Info Center 是 Cisco 设备的日志记录和报告工具,可以用于收集和查看设备的事件、警报和错误信息。该命令用于配置 Info Center 默认源,即设备的默认日志记录和报告服务器。在命令行界面中输入该命令后,可以使用其他命令来配置默认源的 IP 地址、端口号和协议等参数。
recommend-type

c++校园超市商品信息管理系统课程设计说明书(含源代码) (2).pdf

校园超市商品信息管理系统课程设计旨在帮助学生深入理解程序设计的基础知识,同时锻炼他们的实际操作能力。通过设计和实现一个校园超市商品信息管理系统,学生掌握了如何利用计算机科学与技术知识解决实际问题的能力。在课程设计过程中,学生需要对超市商品和销售员的关系进行有效管理,使系统功能更全面、实用,从而提高用户体验和便利性。 学生在课程设计过程中展现了积极的学习态度和纪律,没有缺勤情况,演示过程流畅且作品具有很强的使用价值。设计报告完整详细,展现了对问题的深入思考和解决能力。在答辩环节中,学生能够自信地回答问题,展示出扎实的专业知识和逻辑思维能力。教师对学生的表现予以肯定,认为学生在课程设计中表现出色,值得称赞。 整个课程设计过程包括平时成绩、报告成绩和演示与答辩成绩三个部分,其中平时表现占比20%,报告成绩占比40%,演示与答辩成绩占比40%。通过这三个部分的综合评定,最终为学生总成绩提供参考。总评分以百分制计算,全面评估学生在课程设计中的各项表现,最终为学生提供综合评价和反馈意见。 通过校园超市商品信息管理系统课程设计,学生不仅提升了对程序设计基础知识的理解与应用能力,同时也增强了团队协作和沟通能力。这一过程旨在培养学生综合运用技术解决问题的能力,为其未来的专业发展打下坚实基础。学生在进行校园超市商品信息管理系统课程设计过程中,不仅获得了理论知识的提升,同时也锻炼了实践能力和创新思维,为其未来的职业发展奠定了坚实基础。 校园超市商品信息管理系统课程设计的目的在于促进学生对程序设计基础知识的深入理解与掌握,同时培养学生解决实际问题的能力。通过对系统功能和用户需求的全面考量,学生设计了一个实用、高效的校园超市商品信息管理系统,为用户提供了更便捷、更高效的管理和使用体验。 综上所述,校园超市商品信息管理系统课程设计是一项旨在提升学生综合能力和实践技能的重要教学活动。通过此次设计,学生不仅深化了对程序设计基础知识的理解,还培养了解决实际问题的能力和团队合作精神。这一过程将为学生未来的专业发展提供坚实基础,使其在实际工作中能够胜任更多挑战。