天津理工大学编译原理实验3:语义分析与中间代码生成
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
" <<"semStack: "
delete syn;
system("pause"); }
Lexical.h #pragma once #include <string> #include <vector> namespace ccyg {
class Lexical { public:
enum letter {
第 1页 共 15页
【实验过程记录(源程序、测试用例、测试结果及心得体会等)】 分析的四元式:
(+,E1.place,T.place,E.place) (-,E1.place,T.place,E.place)
(=,T.place,_,E.place) (*,T1.place,F.place,T.place) (/,T1.place,F.place,T.place)
2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 4, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 5, 2, 2, 2, 2, 2, 6, 7, 2, 2, 1, 1, 1, 1, 1, 1, 1, 8, 0 }; long long poow(int a,int b) { if (b == 1) { return a; } else { return poow(a,b-1) * a; } } Syntax::Syntax(std::string s) : Lexical(s) { isSuccess = false; isInitNext = false; } Syntax::~Syntax() { } void Syntax::movein() { symbolStack.push_back(source[0]); if (source[0] == ide) { semStack.push_back(identifier[0]); std::vector<int>::iterator iter = identifier.begin(); identifier.erase(iter); } else
if (number != NULL) {
source.push_back(ide); identifier.push_back(number); number = 0; } source.push_back(sha); return true;
第 5页 共 15页
} else if (sourceCode[i] >= '0'&& sourceCode[i] <= '9') {
std::vector<int> symbolStack;// 定义符号栈 std::vector<int> inputStack; // 定义输入栈 std::vector<double> semStack; //定义语义栈 bool isSuccess; bool isInitNext; static const int preArray[9][9];
return ')'; case sha:
return '#'; default:
break; } return 0; }
void Lexical::setSourceCode(std::string source) {
sourceCode = source; }
Syntax.h
第 7页 共 15页
number = number * 10 + sourceCode[i] - 48; } else {
if (number != NULL) {
source.push_back(ide); identifier.push_back(number); number = 0; } switch (sourceCode[i]) { case '+': source.push_back(add); break; case '-': source.push_back(sub); break; case '*': source.push_back(mul); break; case '/': source.push_back(div); break; case '^': source.push_back(pow); break; case '(': source.push_back(lef); break; case ')': source.push_back(rig); break; default: std::cout << "can not identify : " << sourceCode[i] << std::endl; return false; break; } } } source.push_back(sha); return true;
add = 0, sub = 1, mul = 2, div = 3, pow = 4, ide = 5, lef = 6, rig = 7, sha = 8 }; Lexical(); Lexical(std::string); ~Lexical(); bool analysis(); void printSource(); void setSourceCode(std::string); char toChar(int); std::vector<int> identifier;
第 4页 共 15页
std::vector<int> source; private:
std::string sourceCode; }; }
Lexical.cpp #include "Lexical.h" #include <iostream> #include <stdio.h> using namespace ccyg;
#pragma once #include "Lexical.h" namespace ccyg {
class Syntax : public ccyg::Lexical { public:
enum Relation //定义优先关系枚举 {
equal = 0, less = 1, greater = 2, //错误 i_i = 3, i_left = 4, left_sharp = 5, right_i = 6, right_left = 7, sharp_right = 8 }; enum Symbol { E = 9, T = 10, F = 11, P = 12 }; Syntax(std::string = 0); ~Syntax(); bool reduced();//定义归约方法 void movein();//定义移进方法 int findOperator();//查找最近运算符 char toChar(int); bool nextStep(); void initNext(); void printSymbol(); void printSemantic(); bool getSuccess();
E→E+T | E-T | T T→T*F | T/F | F F→P^F | P P→(E) | i 要求构造出符合语义分析要求的属性文法描述,并在完成实验二(语法分析)的基础上,进行语义分 析程序设计,最终输出与测试用例等价的四元式中间代码序列。
实验目的:
1.掌握语法制导翻译的基本功能。 2.巩固对语义分析的基本功能和原理的认识。 3.能够基于语法制导翻译的知识进行语义分析。 4.掌握类高级语言中基本语句所对应的语义动作。 5.理解并处理语义分析中的异常和错误。
第 8页 共 15页
}; }
Syntax.cpp #include "Syntax.h" #include <iostream> using namespace ccyg; const int Syntax::preArray[9][9] = { 2, 2, 1, 1, 1, 1, 1, 2, 2,
(=,F.place,_,T.place) (^,P.place,_,F.place) (=,P.place,_,F.place) (=,E.place,_,P.place) (=,lookup(i.name),_,P.place)
根据语法分析修改的程序流程图
第 2页 共 15页
程序运行结果:
部分源代码: Main.cpp #include <iostream> #include "Syntax.h" int main(int argc, char ** argv) {
switch (a) { case add:
return '+'; case sub:
return '-'; case mul:
return '*'; case div:
return '/'; case pow:
return '^'; case ide:
return 'i'; case lef:
return '('; case rig:
实验要求:
1.在实验二的基础上,实现语法制导翻译功能,输出翻译后所得四元式序列; 2.要求详细描述所选分析方法进行制导翻译的设计过程; 3.完成对所设计分析器的功能测试,并给出测试数据和实验结果; 4.为增加程序可读性,请在程序中进行适当注释说明; 5.整理上机步骤,总结经验和体会; 6.认真完成并按时提交实验报告。
std::string source;
wk.baidu.com
std::cout<<"please input an arithmetic expression "<<std::endl; std::cin >> source;
ccyg::Syntax * syn = new ccyg::Syntax(source);
syn->analysis();
第 3页 共 15页
std::cout<< "symbolStack: " << "inputStack: <<std::endl;
while (!syn->getSuccess()) {
syn->printSymbol(); syn->printSource(); syn->printSemantic(); syn->nextStep(); std::cout << std::endl; }
学院(系)名称:计算机与通信工程学院
姓名
*****
学号
实验报告
*****
专业
计算机科学与技术
班级
*****
实验项目
实验三:语义分析与中间代码生成
课程名称
编译原理
课程代码
0668056
实验时间
*******
实验地点 计算机软件实验室 7-219
批改意见
成绩
教师签字:
实验内容:
可选择 LL1 分析法、算符优先分析法、LR 分析法之一,实现如下表达式文法的语法制导翻译过程。文 法 G[E]如下所示:
Lexical::Lexical() { } Lexical::Lexical(std::string s) {
sourceCode = s; } Lexical::~Lexical() {
} bool Lexical::analysis() {
if (sourceCode.size() == 0) {
std::cout << "source is empty !" << std::endl; return false; } source.clear(); identifier.clear(); int number = NULL; for (int i = 0; i <= sourceCode.size(); i++) { if (i == sourceCode.size()) {
第 6页 共 15页
}
void Lexical::printSource() {
for (int i = 0; i < source.size(); i++) {
std::cout << toChar(source[i]); } std::cout << " "; }
char Lexical::toChar(int a) {