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

📄 sal.cpp

📁 编译程序的编译原理
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// SAL.cpp : Defines the entry point for the console application.
//
# include "stdafx.h"
# include <stdio.h>   //定义I / O库所用的某些宏和变量
# include <string>  //定义字符串库函数
# include <iostream>
using namespace std; 

char prog[100];  //数据存储变量
char ch;
char token[8];
int p=0;
int m=0,n=0;
int syn=-1; //种别编码
int sum;
int row=1;  //记录行
int pos=0;  //记录行位置
int WordRow; //记录每一特码的所在行
int WordPos; //记录每一物码的所在列
char LastEffectiveCode[8];  //记录最后有效字符
int FourGroupIndex=1000;  //四元组索引
int RecursionIndex=0; //递归索引
int RecursionError=-1; //递归错误位置

char *codeTable[15]={"." , "const" , "var" , "read" , "write" , "+" , "-" ,
					 "*" , "/" , "=" , ":=" , "," , ";" , "(" , ")"};  //种别编码表
FILE *f_Input=fopen("InputFile.txt","r"); //输入文件指针
FILE *f_DualGroup=fopen("OutPutDualGroup.txt","w"); //输入文件指针
FILE *f_FourGroup=fopen("OutPutFourGroup.txt","w"); //输出四元组

struct node 
{ 
    int codeID;
    char value[8];
	int row;
	int pos;
};

struct FourGroup{
	char oper[3];
	char var_01[10];
	char var_02[10];
	char Add[12];
};
int DA_index=0;
node *DataArray[200];
int FGA_index=0;
FourGroup *FourGroupArray[200];

char *e();

//***************************************/
//函数名:isNum                          */
//作 用:判断一个字符是否为0~9的数字字符 */
//参 数:ch 要判断的字符                 */
//反回值:是   1                         */
//       不是 0                         */
//***************************************/
int isNum(char ch){
	return (int(ch) >=48 && int(ch)<=57);
}

//***************************************/
//函数名:isChar                         */
//作 用:判断是否为a~z || A~Z的数字字符  */
//参 数:ch 要判断的字符                 */
//反回值:是   1                         */
//       不是 0                         */
//***************************************/
int isChar(char ch){
	return (int(ch) >=65 && int(ch)<=90) || (int(ch) >=97 && int(ch)<=122);
}

//***************************************/
//函数名:CodeEdit                       */
//作 用:打印错误位置                    */
//参 数:无                              */
//反回值:无                             */
//***************************************/
void CodeEdit(){
	printf("error:row(%i),pos(%i) the sign '%c' occur behind '%s'!\n",row,pos,ch,LastEffectiveCode);
	system("notepad InputFile.txt");
}


//***************************************/
//函数名:getOneChar                     */
//作 用:从文本读取一个字符              */
//参 数:f  文件操作指针                 */
//反回值:一个字符                       */
//***************************************/
char getOneChar(FILE *f)
{
	char ch=fgetc(f);
	if(ch != '\n'){
		pos++;
	}else{
		row++;
		pos=0;
	}
	return ch;
}


//***************************************/
//函数名:OutPutDualGroup                */
//作 用:输出二元组                      */
//参 数:无                              */
//反回值:无                             */
//***************************************/
void OutPutDualGroup(){
	for(int i=0; i<DA_index; i++){
		fprintf(f_DualGroup,"(%2i,%8s)\n",DataArray[i]->codeID,DataArray[i]->value);
	}
	printf("词法分析成功...\n");
}

//***************************************/
//函数名:createFourGroup                */
//作 用:创建四元组                      */
//参 数:oper 操作符                     */
//      var_01操作数01                  */ 
//      var_02操作数02                  */
//      Add 结果地址或变量              */
//反回值:无                             */
//***************************************/
void createFourGroup(char *oper, char *var_01, char *var_02, char *Add){
//	printf("(%2s,%10s,%10s,%10s)\n",oper,var_01,var_02,Add);
	FourGroup *newNode=(FourGroup*)malloc(sizeof(FourGroup));
	strcpy(newNode->oper,oper);
	strcpy(newNode->var_01,var_01);
	strcpy(newNode->var_02,var_02);
	strcpy(newNode->Add,Add);
	FourGroupArray[FGA_index++]=newNode;	
}

//***************************************/
//函数名:OutPutFourGroup                */
//作 用:输出四元组                      */
//参 数:oper 操作符                     */
//      var_01操作数01                  */ 
//      var_02操作数02                  */
//      Add 结果地址或变量]             */
//反回值:无                             */
//***************************************/
void OutPutFourGroup(){
	for(int i=0; i<FGA_index; i++){
		fprintf(f_FourGroup,"(%2s,%10s,%10s,%10s)\n",FourGroupArray[i]->oper,FourGroupArray[i]->var_01,FourGroupArray[i]->var_02,FourGroupArray[i]->Add);
	}
	printf("语法分析成功...\n");
}

//***************************************/
//函数名:scaner                         */
//作 用:词法分析,并存贮每个一词         */
//参 数:无                              */
//反回值:无                             */
//***************************************/
void scaner(){
	memset(token,'\0',8);
	ch=getOneChar(f_Input);
	while (ch==' ' || ch=='\n' || ch=='\t')  ch=getOneChar(f_Input) ; //设置下标P为第一位不为空的位置
	int m=0;
	//关键字字符,以字母开头
	if (isChar(ch)){ 
		 WordRow=row;
		 WordPos=pos;
		 while(isNum(ch) || isChar(ch)){
			token[m++]=ch;
			ch=getOneChar(f_Input);
         }
		 fseek(f_Input,-1,SEEK_CUR);  //向前移回一位
		 pos--;
		 syn=15;  //先设成标识符的种别编码
		 for (n=1; n<=4; n++ ){                   //与关键字数组中的值进行关键关匹配
			 if (strcmp(token, codeTable[n])==0) {
				syn=n;
                return;
            } 
		 }
    }

	//数字字符
	else if (isNum(ch)) {   //ch 是数字字符
			WordRow=row;
			WordPos=pos;
			sum=0;
			while (isNum(ch)) { ///ch 为数字字符
				token[m++]=ch;
				ch=getOneChar(f_Input); //读下一个字符;   
			}
			fseek(f_Input,-1,SEEK_CUR);  //向前移回一位
			pos--;
			syn=16;
			return;

	}else{  //运算比较符
		WordRow=row;
		WordPos=pos;
        switch(ch)
        {
			case ':':  //" := "
				token[m++]=ch ;
                ch=getOneChar(f_Input);  //读下一个字符; 
                if (ch=='='){ 
					syn=10; 
                    token[m++]=ch ;
                }else{ 
					syn=-1;
                }
                break;
            case '+':	syn=5; token[0]=ch; break;
            case '-':	syn=6; token[0]=ch; break;
            case '*':	syn=7; token[0]=ch; break;
            case '/':	syn=8; token[0]=ch; break;
            case '=':	syn=9;  token[0]=ch; break;
            case ',':	syn=11;  token[0]=ch; break;
            case ';':	syn=12;  token[0]=ch; break;
            case '(':	syn=13;  token[0]=ch; break;
            case ')':	syn=14;  token[0]=ch; break;
            case '.':	syn=0;  token[0]=ch; break;
            default: syn= -1;  
        }
	}	
}



//***************************************/
//函数名:f()                            */
//作  用:递归语法分析---处理括号        */
//参  数:无                             */
//反回值:可处理标识符 或 变量存放地址   */
//***************************************/
char *f ()
{  
    if (DataArray[RecursionIndex]->codeID == 15 || DataArray[RecursionIndex]->codeID == 16){  //标识符节||常数
		return DataArray[RecursionIndex++]->value;
	}else if (DataArray[RecursionIndex++]->codeID ==13) {  //=='('
	        char *place=new char[8];
			memset(place,'\0',8);
			strcpy(place,e());
	        if (DataArray[RecursionIndex++]->codeID == 14){ //==')'
		        return place;
            }else{
                RecursionError=RecursionIndex-1;
            }
	}
	else RecursionError=RecursionIndex;
	return "";
}



//***************************************/
//函数名:t()                            */
//作  用:递归语法分析---处理乘除        */
//参  数:无                             */
//反回值:可处理标识符 或 变量存放地址   */
//***************************************/
char* t (){
    char *t1_place=new char[8];
	memset(t1_place,'\0',8);
	strcpy(t1_place,f());
    while (DataArray[RecursionIndex]->codeID ==7 || DataArray[RecursionIndex]->codeID==8){ //=='*' || '/'
		char sign[2];
		memset(sign,'\0',2);
		strcpy(sign,DataArray[RecursionIndex++]->value);

		char t2_place[8];
		memset(t2_place,'\0',8);
		strcpy(t2_place,f());

		char buff[10];
		memset(buff,'\0',10);
		sprintf(buff,"#ADD_%d",FourGroupIndex++); 

        createFourGroup(sign,t1_place,t2_place,buff);  //产生四元组
		strcpy(t1_place,buff);	
    }
	return t1_place;
}

//***************************************/
//函数名:e()                            */
//作  用:递归语法分析---处理加减        */
//参  数:无                             */
//反回值:可处理标识符 或 变量存放地址   */
//***************************************/
char *e ()  //处理加减
{    

⌨️ 快捷键说明

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