⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 myparser.y

📁 扩展后的mini-pl0语法编译器
💻 Y
📖 第 1 页 / 共 2 页
字号:
%{
/****************************************************************************
myparser.y
ParserWizard generated YACC file.

Date: 2005年11月21日
****************************************************************************/

#include "mylexer.h"
#include "interpret.h"
#include <fstream>
#include <string.h>
#include <stdlib.h>
#include <conio.h>

int currentlever = 0;			//当前层数

const int MAXENDCODE = 1024;	//目标代码数组的最大值
int EndCode[MAXENDCODE];		//目标代码数组
int codeindex = 0;				//写目标代码是的下标变量

char NameStack[30][30];			//变量名暂存数组
int stackindex=0;				//已存变量名的最大下标

int varlength;					//变量的长度
int vardispl;					//偏移

int errorcount=0;				//错误的个数
int warningcount=0;				//警告的个数

%}

/////////////////////////////////////////////////////////////////////////////
// declarations section

%start ProgDef

%include {
#include "symbol.h"
enum IdType;
class symbol;
class symboltable;
}

// attribute type
%union 
{
	char str[20];
	int Iv;
	bool Bv;
	int CH;	
	char OP;
	struct	{ int sta,en;}					Sta_end;
	struct	{ int outwhile,conti;}			_WBD; 
	struct	{ int varlen,displ;}			_SubProg;
	struct	{ int value;	IdType type;}	_CIB;
	struct	{ int len,value;IdType type;}	_Expr;
	struct	{ int sta,en;	IdType type;	symbol* compsym;} _ArrD;
	struct	{ int len;		IdType type;	symbol* sym;}_Var;

}

%token <str>	ID
%token <Iv>		NUMBER
%token <Bv>		TRUE	FALSE
%token	PROGRAM
%token	<CH>	PROCEDURE 
%token	<CH>	BEG	
%token	<CH>	END	
%token	<CH>	VAR	
%token	<CH>	CONST
%token	<CH>	TYPE
%token	<CH>	ARRAY
%token	<CH>	DD
%token	<CH>	OF		
%token	<CH>	RECORD	
%token	<CH>	BOOLEAN	
%token	<CH>	INTEGER	
%token	WHILE	
%token	DO		
%token	IF		
%token	THEN
%token	ELSE	
%token	READ	
%token	WRITE
%token	ASSIGN
%token	LE		
%token	GE	
%token	NE	
%token	OR	AND	NOT	DIV	MOD
//优先级及结合性定义
%left ASSIGN
%left OR
%left AND
%right NOT
%nonassoc '<' '>' '=' LE GE NE
%left '+' '-'
%left '*' DIV MOD
%right UMINUS
//%nonassoc hiheest

%type <_SubProg>	SubProg
%type <CH>	ConstDef	ConstDefList	ConstDefState
%type <CH>	TypeDef		TypeDefList		TypeDefState
%type <CH>	TypeOfRecord	DomainList	RecordSection	DomainNameList
%type <CH>	VarDef	VarDefList	VarDefState	VarList
%type <CH>	ProceDefList ProceDef FormParaList ParaDef
%type <CH>	Statement	StateList	AsignState
%type <CH>	ISE	IBT	Wh
%type <_WBD>	WBD
%type <CH> CompState ProQ	CompQ
%type <_CIB>	ConstNum
%type <_ArrD>	TypeOfArray	TypeName
%type <Sta_end> IndexDomain
%type <OP>	RelationOp
%type <_Expr> Expr	BoolExpr	
%type <_Var> Variable
%type <CH>	ProceState
%type <CH>	RealParaList
%type <CH>	RealPara
%type <CH> ProgDef



// parser name
%name myparser

// class definition
{
public:
	symboltable * symtable;			//符号表的根节点
	symboltable * currentsymtable;	//当前符号表的节点指针
	
	symbol* symlist[30];			//用于存储一组变量的节点指针
	int symlistindex;				//已存变量的节点指针的下标(当前未存)
	
	bool checkvar;					//是否是函数的参数列表
	bool checkparam;				//函数参数是否是值参(true为var型,不复制,否则复制)

	symbol** ParamArray;			//过程调用时参数的节点数组指针
	int IsParamIndex;				//当前访问的参数下标
	
public:
	void clearPsym()
	{
		for(int i=0;i<30;i++)
		{
			symlist[i]=NULL;
		}
		symlistindex = 0;
	}
	//查找过程名为name的符号表,前提是每个过程名都不相同
	symboltable* searchProce(char* name,symboltable* child)
	{
		symboltable* temp=child;
		while(temp)
		{
			if(strcmp((temp->m_procesymbol)->m_name,name)==NULL)
				return temp;
			else
			{
				//查找孩子
				symboltable* tempchild = searchProce(name,temp->m_childtable);
				//查找兄弟
				if(tempchild)
					return tempchild;
				else
					temp=temp->m_siblingtable;
			}
		}
		return NULL;		
	}
}

// constructor
{
	clearPsym();
}

// destructor
{
	// place any extra cleanup code here
	symtable->deletechild(symtable);
}

// attribute type
%include {
#ifndef YYSTYPE
#define YYSTYPE int
#endif

}

%%

/////////////////////////////////////////////////////////////////////////////
// rules section

/*<程序>->Program<程序名>;<块体>*/
ProgDef:		PROGRAM ID 
				{
					symtable = new symboltable(currentlever,NULL,NULL);
					currentsymtable = symtable;
					symtable->install($2, symtable->symbolList,CProce);
					
					EndCode[codeindex]=24;
					EndCode[codeindex+4]=yylexerptr->yylineno;
					codeindex=codeindex+5;				
				}
				';' SubProg progQ
				{
					EndCode[1]=$5.varlen;		//过程中变量的长度
					EndCode[2]=3*EndCode[1];
					EndCode[3]=$5.displ;		//过程语句开始时的偏移
					
					EndCode[codeindex] = 7;		//程序结束
					
					cout<<"succeed"<<endl;
				}
			;
progQ:			'.'
			| 
				{
					warningcount++;
					cout<<"warning"<<warningcount<<":缺少结尾\".\"。"<<endl;
				}
			;

/*<块体>->[<常数定义部分>][<类型定义部分>][<变量定义部分>]{<过程定义部分>}<复合语句>*/
SubProg:		ConstDef TypeDef VarDef ProceDefList CompState
				{
					$$.varlen=$3;
					$$.displ=$5;
				}
			|	TypeDef VarDef ProceDefList CompState
				{
					$$.varlen=$2;
					$$.displ=$4;
				}
			|	ConstDef VarDef ProceDefList CompState
				{
					$$.varlen=$2;
					$$.displ=$4;
				}
			|	VarDef ProceDefList CompState
				{
					$$.varlen=$1;
					$$.displ=$3;
				}
			|	ConstDef TypeDef ProceDefList CompState
				{
					$$.varlen=0;
					$$.displ=$4;
				}
			|	TypeDef ProceDefList CompState
				{
					$$.varlen=0;
					$$.displ=$3;
				}
			|	ConstDef ProceDefList CompState
				{
					$$.varlen=0;
					$$.displ=$3;
				}
			|	ProceDefList CompState
				{
					$$.varlen=0;
					$$.displ=$2;
				}
			;

/*<常数定义部分>->const <常数定义>{<常数定义>}
  <常数定义>-><常数名>=<常数>;*/
ConstDef:		CONST ConstDefList ';'
			;
ConstDefList:	ConstDefList ';' ConstDefState
			|	ConstDefState
			;
ConstDefState:	ID '=' ConstNum
				{
					symbol* temp;
					temp = currentsymtable->install($1,$3.type);
					if(temp==NULL)
					{
						errorcount++;
						cout<<"error"<<errorcount<<"h("<<yylexerptr->yylineno<<"):该常量已存在。"<<endl;	
					}
					else
						temp->SetSimpleValue($3.value);
				}
			|	ID ASSIGN ConstNum
				{
					warningcount++;
					cout<<"warning"<<warningcount<<"h("<<yylexerptr->yylineno<<"):常量不能赋值"<<endl;
					symbol* temp;
					temp = currentsymtable->install($1,$3.type);
					if(temp==NULL)
					{
						errorcount++;
						cout<<"error"<<errorcount<<"h("<<yylexerptr->yylineno<<"):该常量已存在。"<<endl;	
					}
					else
						temp->SetSimpleValue($3.value);
				}
/*			|	ConstNum '=' ConstNum
				{
					warningcount++;
					cout<<"warning"<<warningcount<<"h("<<yylexerptr->yylineno<<"):不能给常数赋值"<<endl;
				}
			|	ConstNum ASSIGN ConstNum
				{
					warningcount++;
					cout<<"warning"<<warningcount<<"h("<<yylexerptr->yylineno<<"):不能给常数赋值"<<endl;
				}
*/			;

/*<类型定义部分>->type<类型定义>{<类型定义>}
  <类型定义>-><类型名>=<新类型>;
  <新类型>-><数组类型>|<记录类型>*/
TypeDef:		TYPE TypeDefList ';'
			;
TypeDefList:	TypeDefList ';' TypeDefState
			|	TypeDefState
			;
TypeDefState:	ID '=' TypeOfArray
				{
					currentsymtable->install($1,$3.sta,$3.en,$3.type,$3.compsym);
				}
			|	ID '=' TypeOfRecord 
				{
					currentsymtable->install($1,symlist,DRecord);					
				}
			;
/*<数组类型>->array[<下标域>]of<类型名>
  <下标域>-><常数>..<常数>*/
TypeOfArray:	ARRAY '[' IndexDomain ']' OF TypeName
				{
					$$.type = $6.type;
					$$.compsym = $6.compsym;
					$$.sta = $3.sta;
					$$.en = $3.en;
				}
			;
IndexDomain:	ConstNum DD ConstNum
				{
					if($1.type==CInt && $3.type==CInt)
					{
						$$.sta = $1.value;
						$$.en = $3.value;
					}
					else
					{
						errorcount++;
						cout<<"error"<<errorcount<<"h("<<yylexerptr->yylineno<<"): 数组定义的下标不是常量"<<endl;
					}
				}
			;
TypeName:		INTEGER
				{
					$$.type = VInt;
					$$.compsym = NULL;
				}
			|	BOOLEAN
				{
					$$.type = VBool;
					$$.compsym = NULL;
				}
			|	ID	//新类型名
				{
					symboltable* temp;
					temp = currentsymtable->search($1);
					if(temp)
					{
						if(temp->m_tempsymbol->m_type==DArray||temp->m_tempsymbol->m_type==DRecord)
						{
							$$.compsym = temp->m_tempsymbol;
							$$.type = temp->m_tempsymbol->m_type;
						}
						else
						{
							errorcount++;
							cout<<"error"<<errorcount<<"h("<<yylexerptr->yylineno<<"):"<<$1<<"不是新类型名"<<endl;					
						}
					}
					else
					{
						errorcount++;
						cout<<"error"<<errorcount<<"h("<<yylexerptr->yylineno<<"):新类型"<<$1<<"不存在"<<endl;
					}
				}
			;
			
/*<记录类型>->record <域表> end
  <域表>-><记录节>{;<记录节>}
  <记录节>-><域名>{,<域名>}:<类型名>*/
TypeOfRecord:	RECORD 
				{
					clearPsym();
				}
				DomainList END
			;
DomainList:		DomainList ';' RecordSection
			|	RecordSection
			;			
RecordSection:	{stackindex=-1;} DomainNameList ':' TypeName
				{
					for(int i = 0; i <= stackindex; i++)
					{
						if(!$4.compsym &&($4.type==VInt||$4.type==VBool))//普通类型
						{
							symlist[symlistindex] = new symbol();
							symlist[symlistindex]->create(NameStack[i],$4.type);
							symlist[symlistindex]->m_length=1;
							symlistindex++;
						}
						else
						if($4.compsym &&($4.type == DArray||$4.type == DRecord))//新类型
						{
							symlist[symlistindex] = new symbol();
							if($4.type == DArray)
								symlist[symlistindex]->create(NameStack[i], VArray,$4.compsym);
							if($4.type == DRecord)
								symlist[symlistindex]->create(NameStack[i], VRecord,$4.compsym);
							symlist[symlistindex]->m_length = $4.compsym->m_length;
							symlistindex++;
						}
						else
						{
							errorcount++;
							cout<<"error"<<errorcount<<"h("<<yylexerptr->yylineno<<"):"<<" 域定义错误"<<endl;
						}
					}
				}
			;
DomainNameList:	DomainNameList ',' ID
				{
					stackindex++;
					if(stackindex>=30)
						cout<<"stackindex is small."<<endl;
					else
					{
						for(int i=0;i<stackindex;i++)
							if(strcmp(NameStack[stackindex],$3)==NULL)
							{
								break;
							}
						if(i==stackindex)
							strcpy(NameStack[stackindex],$3);
						else
						{
							stackindex--;
							warningcount++;
							cout<<"warning"<<warningcount<<"h("<<yylexerptr->yylineno<<"):"<<$3<<"重复"<<endl;
						}			
					}
				}
			|	ID
				{
					stackindex++;
					if(stackindex>=30)
						cout<<"stackindex is small."<<endl;
					else
						strcpy(NameStack[stackindex],$1);				
				}
			;

/*<变量定义部分>->var <变量定义>{<变量定义>}
  <变量定义>-><变量组>;
  <变量组>-><变量名>{,<变量名>}:<类型名>*/
VarDef:			{vardispl=3;}
				VAR	
				{
					checkvar = false;	//不是参数定义
					varlength=0;		//变量的长度
				}
				VarDefList ';'
				{
					$$=varlength;
				}
			;		
VarDefList:		VarDefList ';' VarDefState
				{}
			|	VarDefState
				{}
			;
VarDefState:	{stackindex=-1;} VarList ':' TypeName
				{
					symbol* temp;
					if(checkvar==false)
					{
						for(int i = 0; i <= stackindex; i++)
						{
							if(!$4.compsym && ($4.type==VInt||$4.type==VBool))//普通类型
							{
								temp=currentsymtable->install(NameStack[i], $4.type);
								temp->m_value = vardispl;
								vardispl++;
							}
							else
							if($4.compsym && $4.type == DArray)
							{
								temp=currentsymtable->install(NameStack[i], VArray, $4.compsym);
								temp->m_value = vardispl;
								vardispl=vardispl + $4.compsym->m_length;
							}
							else
							if($4.compsym && $4.type == DRecord)
							{
								temp=currentsymtable->install(NameStack[i], VRecord, $4.compsym);
								temp->m_value = vardispl;
								vardispl=vardispl + $4.compsym->m_length;
							}
							else
							{
							//	errorcount++;
							}
						}
						if($4.compsym)
						{
							varlength = varlength +$4.compsym->m_length * $2;
						}
						else
						{
							varlength = varlength + $2;
						}
					}
					else//过程参数
					{						
						if(checkparam)
						{
							for(int i = 0; i <= stackindex; i++)
							{
								symlist[symlistindex++]=currentsymtable->install(NameStack[i],
													$4.type,1,$4.compsym,checkparam);
							}
							$$ = stackindex + 1;
						}
						else
						{	
							int mlen;
							for(int i = 0; i <= stackindex; i++)
							{
								
								if($4.compsym)
								{
									mlen=$4.compsym->m_length;
								}
								else
									mlen=1;
								symlist[symlistindex++]=currentsymtable->install(NameStack[i],
													$4.type,mlen,$4.compsym,checkparam);
							}
							$$ = (stackindex + 1) * mlen;
						}						
					}
				}			
			;	
VarList:		VarList ',' ID
				{
					stackindex++;
					if(stackindex>=30)
					cout<<"stackindex is small."<<endl;
					strcpy(NameStack[stackindex],$3);
					$$ = $1+1;
				}
			|	ID
				{
					stackindex++;
					if(stackindex>=30)
					cout<<"stackindex is small."<<endl;
					strcpy(NameStack[stackindex],$1);
					$$ = 1;				
				}
			;

/*<过程定义>->procedure <过程名><过程块>;
  <过程块>->[(<形参表>)];<块体>
  <形参表>-><参数定义>{;<参数定义>}
  <参数定义>->[var]<变量名>*/		
ProceDefList:	/*empty*/
			|	ProceDefList ProceDef ';'
			;		
ProceDef:		PROCEDURE ID
				{
					currentsymtable=currentsymtable->insertchild($2);
					currentlever++;	
					clearPsym();
					
					EndCode[codeindex]=23;
					EndCode[codeindex+4]=yylexerptr->yylineno;
					
					currentsymtable->codebegin=codeindex;
					
					codeindex=codeindex+5;
					
					varlength=0;
								
				}
				'('FormParaList')'
				{
					currentsymtable->install($2,symlist,CProce);
				}
				';' ProQ SubProg
				{
					EndCode[$9+1]=$10.varlen;
					EndCode[$9+2]=EndCode[$9+1]*3;
					EndCode[$9+3]=$10.displ-$9;
					
					EndCode[codeindex++]=6;
					EndCode[codeindex++]=$5;
					
					currentsymtable=currentsymtable->m_parenttable;
					currentlever--;
				}
			|	PROCEDURE ID ';'
				{
					currentsymtable=currentsymtable->insertchild($2);
					currentlever++;
					
					EndCode[codeindex]=23;
					EndCode[codeindex+4]=yylexerptr->yylineno;
					
					currentsymtable->codebegin=codeindex;
					
					codeindex=codeindex+5;
					
					currentsymtable->install($2,symlist,CProce);	
				}
				ProQ SubProg
				{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -