📄 sal.cpp
字号:
// 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 + -