编译原理课设(词法分析,语法分析,语义分析)

语法分析,有LL1语法分析,以及自顶向上   2种。

predict是程序自动生成和手动添加两种

语义分析:全局表

#include<iostream>
#include<stdio.h>
#include<stack>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<string>
using namespace std;
const int maxn = 10000;
/*
* 类型声明
*/
enum Terminal {
	/* 簿记单词符号 */
	ENDFILE, ERROR,
	/* 保留字 */
	PROGRAM, PROCEDURE, TYPE, VAR, IF,
	THEN, ELSE, FI, WHILE, DO,
	ENDWH, BEGIN, END, READ, WRITE,
	ARRAY, OF, RECORD, RETURN,
	/*类型*/
	INTEGER, CHAR,
	/* 多字符单词符号 */
	ID, INTC, CHARC,
	/*特殊符号 */
	ASSIGN, EQ, LT, PLUS, MINUS,
	TIMES, OVER, LPAREN, RPAREN, DOT,
	COLON, SEMI, COMMA, LMIDPAREN, RMIDPAREN,
	UNDERANGE
};
enum NonTerminal {
	//总程序
	Program = 50,
	//程序头
	ProgramHead, ProgramName,
	//程序声明
	DeclarePart,
	//类型声明
	TypeDecpart, TypeDec, TypeDecList, TypeDecMore, TypeId,
	//类型
	TypeDef, BaseType, StructureType, ArrayType,
	Low, Top, RecType, FieldDecList, FieldDecMore, IdList, IdMore,
	//变量声明
	VarDecpart, VarDec, VarDecList, VarDecMore, VarIdList, VarIdMore,
	//过程声明
	ProcDecpart, ProcDec, ProcDecMore, ProcName,
	//参数声明
	ParamList, ParamDecList, ParamMore, Param, FormList, FidMore,
	//过程中的声明部分
	ProcDecPart,
	//过程体
	ProcBody,
	//主程序体
	ProgramBody,
	//语句序列
	StmList, StmMore,
	//语句
	Stm, AssCall,
	//赋值语句
	AssignmentRest,
	//条件语句
	ConditionalStm,
	//循环语句
	LoopStm,
	//输入语句
	InputStm, Invar,
	//输出语句
	OutputStm,
	//返回语句
	ReturnStm,
	//过程调用语句
	CallStmRest, ActParamList, ActParamMore,
	//条件表达式
	RelExp, OtherRelE,
	//算术表达式
	Exp, OtherTerm,
	//项
	Term, OtherFactor,
	//因子
	Factor, Variable, VariMore, FieldVar, FieldVarMore, CmpOp, AddOp, MultOp
};
map<int, string>Map;
void initmap() {
	//终极符
	Map.insert(make_pair(0, "ENDFILE"));
	Map.insert(make_pair(1, "ERROR"));
	Map.insert(make_pair(2, "PROGRAM"));
	Map.insert(make_pair(3, "PROCEDURE"));
	Map.insert(make_pair(4, "TYPE"));
	Map.insert(make_pair(5, "VAR"));
	Map.insert(make_pair(6, "IF"));
	Map.insert(make_pair(7, "THEN"));
	Map.insert(make_pair(8, "ELSE"));
	Map.insert(make_pair(9, "FI"));
	Map.insert(make_pair(10, "WHILE"));
	Map.insert(make_pair(11, "DO"));
	Map.insert(make_pair(12, "ENDWH"));
	Map.insert(make_pair(13, "BEGIN"));
	Map.insert(make_pair(14, "END"));
	Map.insert(make_pair(15, "READ"));
	Map.insert(make_pair(16, "WRITE"));
	Map.insert(make_pair(17, "ARRAY"));
	Map.insert(make_pair(18, "OF"));
	Map.insert(make_pair(19, "RECORD"));
	Map.insert(make_pair(20, "RETURN"));
	Map.insert(make_pair(21, "INTEGER"));
	Map.insert(make_pair(22, "CHAR"));
	Map.insert(make_pair(23, "ID"));
	Map.insert(make_pair(24, "INTC"));
	Map.insert(make_pair(25, "CHARC"));
	Map.insert(make_pair(26, "ASSIGN"));
	Map.insert(make_pair(27, "EQ"));
	Map.insert(make_pair(28, "LT"));
	Map.insert(make_pair(29, "PLUS"));
	Map.insert(make_pair(30, "MINUS"));
	Map.insert(make_pair(31, "TIMES"));
	Map.insert(make_pair(32, "OVER"));
	Map.insert(make_pair(33, "LPAREN"));
	Map.insert(make_pair(34, "RPAREN"));
	Map.insert(make_pair(35, "DOT"));
	Map.insert(make_pair(36, "COLON"));
	Map.insert(make_pair(37, "SEMI"));
	Map.insert(make_pair(38, "COMMA"));
	Map.insert(make_pair(39, "LMIDPAREN"));
	Map.insert(make_pair(40, "RMIDPAREN"));
	Map.insert(make_pair(41, "UNDERANGE"));
	//非终极符
	Map.insert(make_pair(50, "Program"));
	Map.insert(make_pair(51, "ProgramHead"));
	Map.insert(make_pair(52, "ProgramName"));
	Map.insert(make_pair(53, "DeclarePart"));
	Map.insert(make_pair(54, "TypeDecpart"));
	Map.insert(make_pair(55, "TypeDec"));
	Map.insert(make_pair(56, "TypeDecList"));
	Map.insert(make_pair(57, "TypeDecMore"));
	Map.insert(make_pair(58, "TypeId"));
	Map.insert(make_pair(59, "TypeDef"));
	Map.insert(make_pair(60, "BaseType"));
	Map.insert(make_pair(61, "StructureType"));
	Map.insert(make_pair(62, "ArrayType"));
	Map.insert(make_pair(63, "Low"));
	Map.insert(make_pair(64, "Top"));
	Map.insert(make_pair(65, "RecType"));
	Map.insert(make_pair(66, "FieldDecList"));
	Map.insert(make_pair(67, "FieldDecMore"));
	Map.insert(make_pair(68, "IdList"));
	Map.insert(make_pair(69, "IdMore"));
	Map.insert(make_pair(70, "VarDecpart"));
	Map.insert(make_pair(71, "VarDec"));
	Map.insert(make_pair(72, "VarDecList"));
	Map.insert(make_pair(73, "VarDecMore"));
	Map.insert(make_pair(74, "VarIdList"));
	Map.insert(make_pair(75, "VarIdMore"));
	Map.insert(make_pair(76, "ProcDecpart"));
	Map.insert(make_pair(77, "ProcDec"));
	Map.insert(make_pair(78, "ProcDecMore"));
	Map.insert(make_pair(79, "ProcName"));
	Map.insert(make_pair(80, "ParamList"));
	Map.insert(make_pair(81, "ParamDecList"));
	Map.insert(make_pair(82, "ParamMore"));
	Map.insert(make_pair(83, "Param"));
	Map.insert(make_pair(84, "FormList"));
	Map.insert(make_pair(85, "FidMore"));
	Map.insert(make_pair(86, "ProcDecPart"));
	Map.insert(make_pair(87, "ProcBody"));
	Map.insert(make_pair(88, "ProgramBody"));
	Map.insert(make_pair(89, "StmList"));
	Map.insert(make_pair(90, "StmMore"));
	Map.insert(make_pair(91, "Stm"));
	Map.insert(make_pair(92, "AssCall"));
	Map.insert(make_pair(93, "AssignmentRest"));
	Map.insert(make_pair(94, "ConditionalStm"));
	Map.insert(make_pair(95, "LoopStm"));
	Map.insert(make_pair(96, "InputStm"));
	Map.insert(make_pair(97, "Invar"));
	Map.insert(make_pair(98, "OutputStm"));
	Map.insert(make_pair(99, "ReturnStm"));
	Map.insert(make_pair(100, "CallStmRest"));
	Map.insert(make_pair(101, "ActParamList"));
	Map.insert(make_pair(102, "ActParamMore"));
	Map.insert(make_pair(103, "RelExp"));
	Map.insert(make_pair(104, "OtherRelE"));
	Map.insert(make_pair(105, "Exp"));
	Map.insert(make_pair(106, "OtherTerm"));
	Map.insert(make_pair(107, "Term"));
	Map.insert(make_pair(108, "OtherFactor"));
	Map.insert(make_pair(109, "Factor"));
	Map.insert(make_pair(110, "Variable"));
	Map.insert(make_pair(111, "VariMore"));
	Map.insert(make_pair(112, "FieldVar"));
	Map.insert(make_pair(113, "FieldVarMore"));
	Map.insert(make_pair(114, "CmpOp"));
	Map.insert(make_pair(115, "AddOp"));
	Map.insert(make_pair(116, "MultOp"));
}
struct Token {
	int hang;
	Terminal Tname;
	int flag;//0是终极符,1非终极符
	NonTerminal  nonTname;
	int name;
	string tokenname;  //token的名字 比如有个char型变量叫sss,那么存的就是"sss"
};
/*
* 结构体构建区
*/
struct Tree {
	int sonnum;
	int hang;
	int height = 0;
	Terminal Tname;
	int flag;//0是终极符,1非终极符
	NonTerminal  nonTname;
	Tree() {
		sonnum = 0;
	}
	Tree* son[100];
	Tree* father;
	~Tree() {
		for (int i = 0; i < sonnum; i++) {
			delete(son[i]);
		}
	}
};
struct Product {
	NonTerminal  nonTname;
	int flag;
	Terminal Tname;
	Terminal getTerminalname() { return Tname; }
	NonTerminal getNonTerminalname() { return nonTname; }
	void setTerminalname(Terminal name) { Tname = name; }
	void setNonTerminalname(NonTerminal name) { nonTname = name; }
};
struct Production {
	Product product[100];
	NonTerminal Headname;
	void setHead(NonTerminal name) { Headname = name; }
	int num;
	Production() { num = 0; }
	void setProduction(Terminal ter) {
		product[num].setTerminalname(ter); product[num++].flag = 0;

	}
	void setProduction(NonTerminal nonter) { product[num].setNonTerminalname(nonter); product[num++].flag = 1; }
	NonTerminal getHeadname() { return Headname; }
	Product get(int i) { return product[i]; }

};
struct Predict {
	Terminal name[100];
	Terminal ter[100];
	int num = 0;
	void setPredict(Terminal nonter) { name[num++] = nonter; }
	Terminal get(int i) { return name[i]; }
};
struct RecBody {
	string name;
	union {
		struct {
			int Size;
			Terminal kind;
		} CommonVar;
		struct {
			int Size;//Size=(up-low+1)*sizeof(ElemType)
			Terminal kind;
			int low;
			int up;
			Terminal ElemType;
		} ArrayVar;
		struct {
			int Size;
			Terminal kind;
			RecBody* recbody;
		} RecVar;
	} type;
	RecBody* link;
};
struct ParameTable {
	string name;
	Terminal kind;
	int level;
	ParameTable* next;
};
struct SymTable {
	string name;
	Terminal kind;
	int level;
	union {
		struct {
			int Size;
			Terminal kind;
		} CommonVar;
		struct {
			int Size;//Size=(up-low+1)*sizeof(ElemType)
			Terminal kind;
			int low;
			int up;
			Terminal ElemType;
		} ArrayVar;
		struct {
			int Size;
			Terminal kind;
			RecBody* recbody;
		} RecVar;
	} type;
	ParameTable* Parame = NULL;
	SymTable* next;
};
/*
* 全局变量区
*/
Token tokenlist[maxn];
int tokenlen;
Production product[141];
Predict predict[141];
int error = 0;
Tree* root = new Tree();
int hangshu = 1;  //此时所扫描token所在行数
Tree* tree[1000];
int Level = 0;//分别表示当前层数和符号表最大下标
vector<SymTable*> symArr;
vector<SymTable*> scope;
/*
*  词法分析阶段
*/
int IsOther(char ch)
{
	if (ch >= 'A' && ch <= 'Z')
		return 0;
	if (ch >= 'a' && ch <= 'z')
		return 0;
	if (ch >= '0' && ch <= '9')
		return 0;
	return 1;
}
//判断是否为关键字
int IsKeyWord(string str, Token* pToken)
{
	if (str == "endfile")
	{
		pToken->flag = 0;
		pToken->Tname = ENDFILE;
		pToken->tokenname = str;
		return 1;
	}
	else if (str == "error")
	{
		pToken->flag = 0;
		pToken->Tname = ERROR;
		pToken->tokenname = str;
		return 1;
	}
	else if (str == "integer")
	{
		pToken->flag = 0;
		pToken->Tname = INTEGER;
		pToken->tokenname = str;
		return 1;
	}
	else if (str == "char")
	{
		pToken->flag = 0;
		pToken->Tname = CHAR;
		pToken->tokenname = str;
		return 1;
	}
	else if (str == "program")
	{
		pToken->flag = 0;
		pToken->Tname = PROGRAM;
		pToken->tokenname = str;
		return 1;
	}
	else if (str == "array")
	{
		pToken->flag = 0;
		pToken->Tname = ARRAY;
		pToken->tokenname = str;
		return 1;
	}
	else if (str == "of")
	{
		pToken->flag = 0;
		pToken->Tname = OF;
		pToken->tokenname = str;
		return 1;
	}
	else if (str == "record")
	{
		pToken->flag = 0;
		pToken->Tname = RECORD;
		pToken->tokenname = str;
		return 1;
	}
	else if (str == "end")
	{
		pToken->flag = 0;
		pToken->Tname = END;
		pToken->tokenname = str;
		return 1;
	}
	else if (str == "var")
	{
		pToken->flag = 0;
		pToken->Tname = VAR;
		pToken->tokenname = str;
		return 1;
	}
	else if (str == "procedure")
	{
		pToken->flag = 0;
		pToken->Tname = PROCEDURE;
		pToken->tokenname = str;
		return 1;
	}
	else if (str == "begin")
	{
		pToken->flag = 0;
		pToken->Tname = BEGIN;
		pToken->tokenname = str;
		return 1;
	}
	else if (str == "if")
	{
		pToken->flag = 0;
		pToken->Tname = IF;
		pToken->tokenname = str;
		return 1;
	}
	else if (str == "then")
	{
		pToken->flag = 0;
		pToken->Tname = THEN;
		pToken->tokenname = str;
		return 1;
	}
	else if (str == "else")
	{
		pToken->flag = 0;
		pToken->Tname = ELSE;
		pToken->tokenname = str;
		return 1;
	}
	else if (str == "fi")
	{
		pToken->flag = 0;
		pToken->Tname = FI;
		pToken->tokenname = str;
		return 1;
	}
	else if (str == "while")
	{
		pToken->flag = 0;
		pToken->Tname = WHILE;
		pToken->tokenname = str;
		return 1;
	}
	else if (str == "do")
	{
		pToken->flag = 0;
		pToken->Tname = DO;
		pToken->tokenname = str;
		return 1;
	}
	else if (str == "endwh")
	{
		pToken->flag = 0;
		pToken->Tname = ENDWH;
		pToken->tokenname = str;
		return 1;
	}
	else if (str == "read")
	{
		pToken->flag = 0;
		pToken->Tname = READ;
		pToken->tokenname = str;
		return 1;
	}
	else if (str == "write")
	{
		pToken->flag = 0;
		pToken->Tname = WRITE;
		pToken->tokenname = str;
		return 1;
	}
	else if (str == "return")
	{
		pToken->flag = 0;
		pToken->Tname = RETURN;
		pToken->tokenname = str;
		return 1;
	}
	else if (str == "type")
	{
		pToken->flag = 0;
		pToken->Tname = TYPE;
		pToken->tokenname = str;
		return 1;
	}
	else return 0;
}
Token* Scanner(FILE* pf)
{
	char ch;
	string tmpStr = "";
	Token* pToken = new Token();
	/*用于检测标识符是否合法*/
	char biaozhi[50] = { '\0' };
	int pb = 0;
LS0://根据第一个字符确定程序走向
	{
		ch = fgetc(pf);
		if (ch != EOF)      //没有读到文件末尾
		{
			if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'))
				goto LS1;
			if (ch >= '0' && ch <= '9')
				goto LS2;
			if (ch == '+')
				goto LS3;
			if (ch == '-')
				goto LS4;
			if (ch == '*')
				goto LS5;
			if (ch == '/')
				goto LS6;
			if (ch == '<')
				goto LS7;
			if (ch == ';')
				goto LS8;
			if (ch == ':')
				goto LS9;
			if (ch == ',')
				goto LS10;
			if (ch == '.')
				goto LS11;
			if (ch == '=')
				goto LS12;
			if (ch == '[')
				goto LS13;
			if (ch == ']')
				goto LS14;
			if (ch == '(')
				goto LS15;
			if (ch == ')')
				goto LS16;
			if (ch == '\'')
				goto LS17;
			if (ch == ' ')
				goto LS18;
			if (ch == '\n' || ch == '\r' || ch == '\t')
				goto LS19;
			goto LS20;
		}
		else
		{
			return NULL;
		}
	}
LS1://若字母开头,可能为标示符或关键字
	{
		tmpStr += ch;
		biaozhi[pb] = ch;
		pb++;
		int flag;
		ch = fgetc(pf);                                    //读取下一个字符
		if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9'))
			goto LS1;
		if ((flag = IsOther(ch)) == 1)                     //如果读到了除字母数字以外的
		{
			ungetc(ch, pf);                                //把读到的字符放回到文件流中
			if ((flag = IsKeyWord(tmpStr, pToken)) == 1)   //如果判断字符串是关键字
			{
				//char数组清零
				for (int s = 0; s < 50; s++)
					biaozhi[s] = '\0';
				pb = 0;
				//放入token序列
				pToken->hang = hangshu;
				return pToken;
			}
			else
			{
				
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
附录c 编译程序实验 实验目的:用c语言对一个简单语言的子集编制一个一遍扫描的编译程序,以加深对编译原理的理解,掌握编译程序的实现方法和技术。 语法分析 C2.1 实验目的 编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析. C2.2 实验要求 利用C语言编制递归下降分析程序,并对简单语言进行语法分析. C2.2.1待分析的简单语言的语法 实验目的 通过上机实习,加深对语法制导翻译原理的理解,掌握将语法分析所识别的语法成分变换为中间代码的语义翻译方法. 实验要求 采用递归下降语法制导翻译法,对算术表达式、赋值语句进行语义分析并生成四元式序列。 实验的输入和输出 输入是语法分析提供的正确的单词串,输出为三地址指令形式的四元式序列。 例如:对于语句串 begin a:=2+3*4;x:=(a+b)/c end# 输出的三地址指令如下: (1) t1=3*4 (2) t2=2+t1 (3) a=t2 (4) t3=a+b (5) t4=t3/c (6) x=t4 算法思想 1设置语义过程 (1) emit(char *result,char *arg1,char *op,char *ag2) 该函数功能是生成一个三地址语句送到四元式表中。 四元式表的结构如下: struct {char result[8]; char ag1[8]; char op[8]; char ag2[8]; }quad[20]; (2)char *newtemp() 该函数回送一个新的临时变量名,临时变量名产生的顺序为T1,T2,…. Char *newtemp(void) { char *p; char m[8]; p=(char *)malloc(8); k++; itoa(k,m,10); strcpy(p+1,m); p[0]=’t’; return(p); } (2)主程序示意图如图c.10所示。 (2) 函数lrparser在原来语法分析的基础上插入相应的语义动作:将输入串翻译成四元式序列。在实验中我们只对表达式、赋值语句进行翻译。 语义分析程序的C语言程序框架 int lrparser() { int schain=0; kk=0; if(syn=1) { 读下一个单词符号; schain=yucu; /调用语句串分析函数进行分析/ if(syn=6) { 读下一个单词符号; if(syn=0 && (kk==0)) 输出(“success”); } else { if(kk!=1 ) 输出 ‘缺end’ 错误;kk=1;} else{输出’begin’错误;kk=1;} } return(schain); int yucu() { int schain=0; schain=statement();/调用语句分析函数进行分析/ while(syn=26) {读下一个单词符号; schain=statement(); /调用语句分析函数进行分析/ } return(schain); } int statement() { char tt[8],eplace[8]; int schain=0; {switch(syn) {case 10: strcpy(tt,token); scanner(); if(syn=18) {读下一个单词符号; strcpy(eplace,expression()); emit(tt,eplace,””,””); schain=0; } else {输出’缺少赋值号’的错误;kk=1; } return(schain); break; } } char *expression(void) {char *tp,*ep2,*eplace,*tt; tp=(char *)malloc(12);/分配空间/ ep2=(char *)malloc(12); eplace=(char *)malloc(12); tt =(char )malloc(12); strcpy(eplace,term ());/调用term分析产生表达式计算的第一项eplace/ while(syn=13 or 14) { 操作符 tt= ‘+’或者‘—’; 读下一个单词符号; strcpy(ep2,term());/调用term分析产生表达式计算的第二项ep2/ strcpy(tp,newtemp());/调用newtemp产生临时变量tp存储计算结果/ emit(tp,eplace,tt,ep2);/生成四元式送入四元式表/ strcpy(eplace,tp); } return(eplace); } char *term(void)/仿照函数expression编写/ char *factor(void) {char *fplace; fplace=(char *)malloc(12); strcpy(fplace, “ ”); if(syn=10) {strcpy(fplace,,token);/将标识符token的值赋给fplace/ 读下一个单词符号; } else if(syn=11) {itoa(sum,fplace,10); 读下一个单词符号; } else if (syn=27) {读下一个单词符号; fplace=expression();/调用expression分析返回表达式的值/ if(syn=28) 读下一个单词符号; else{输出‘}’错误;kk=1; } } else{输出‘(’错误;kk=1; } return(fplace); }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

初,梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值