完整代码如下:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
#define BUFFSIZE 1000


char prog[BUFFSIZE];//存入词法分析
char token[8];//存放正在分析的代码
char ch,ch1;
int syn,p,q,m,n,sum,i=1,k=0,kk,flag=0;
char *keyword[32]={"main","break","case","char","define","continue","default",
                    "do","double","else","what","extern","float","for","goto","if",
                    "int","long","stack","return","short","fopen","sizeof",
                    "static","struct","switch","typedef","enum","unsigned","void","fclose","while"};

int main()  /*主函数*/
{
    void scaner();
    int IrPar();
    FILE *fp;
    if((fp=fopen("test.txt","r"))==NULL)
    {
        printf("无法打开文件!\n");
        exit(1);
    }
    p=0;
    while(!feof(fp))
    {
        prog[p++]=fgetc(fp);
        if(p>=5000)
        {
            cout << "缓冲区容量不够!" << endl;
            exit(1);
        }
    }/*把文件test中的内容存入数组prog中*/
    fclose(fp);
    cout << prog;
    p=0;
    cout << "输出词法分析结果: " << endl;
	do
	{
		scaner();
		switch(syn)
		{
		case 34:printf("(%d,%d),",syn,sum);break;
		case -1:printf("error,");break;
		default:printf("(%d,%s),",syn,token);
		}
		cout << endl;
	}while(syn!=0);
	p=0;
	cout << endl << "语法语义分析: " << endl << endl << "四元式生成: " << endl;
    scaner();
    IrPar();
    system("pause");
    getchar();
    return 0;
}

void scaner()
{
    for(n=0;n<8;n++) token[n]=NULL;
    m=0;
    sum=0;
    ch=prog[p];
    while(ch==' '||ch=='\n')
    {
        p++;
        ch=prog[p];
    }/*读下一个字符*/
    if((ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z'))
    {
        while((ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z')||(ch>='0'&&ch<='9'))
        {
            token[m]=ch;
            m++;p++;
            ch=prog[p];
        }
        token[m++]='\0';
        syn=33;
        for(n=0;n<32;n++)
        if(strcmp(token,keyword[n])==0)
        {
            syn=n+1;
            break;
        }
    }/*判断输入字符是否为标识符或者关键字的情况*/
    else if(ch>='0'&&ch<='9')
    {
        while(ch>='0'&&ch<='9')
        {
            sum=sum*10+ch-'0';
            p++;
            ch=prog[p];
        }
        syn=34;
    }/*判断输入字符是否为整型常数的情况*/
    else
      switch(ch)
      {
       case '<':token[m]=ch;
                p++;
                ch=prog[p];
                if(ch=='>')
                {
                    syn=42;
                    m++;
                    token[m]=ch;
                    p++;
                }/*出现<>的情况*/
                else if(ch=='=')
                {
                    syn=43;
                    m++;
                    token[m]=ch;
                    p++;
                }/*出现<=的情况*/
                else
                {syn=41;}
                break;

       case '>':token[m]=ch;
                p++;
                ch=prog[p];
                if(ch=='=')
                {
                    syn=45;
                    m++;
                    token[m]=ch;
                    p++;
                }/*出现>=的情况*/
                else
                {syn=44;}
                break;

       case ':':token[m]=ch;
                p++;
                ch=prog[p];
                if(ch=='=')
                {
                    syn=40;
                    m++;
                    token[m]=ch;
                    p++;
                }/*出现:=的情况*/
                else
                {syn=39;}
                break;

       case '/':token[m]=ch;
                p++;
                ch=prog[p];
                if(ch=='*')
                {
                    syn=51;
                    q=0;
                    m++;
                    token[m]=ch;
                    p++;
                    q=p+1;
                    while(prog[p]!='*'||prog[q]!='/')
                    {p++;q++;}
                }/*出现注释'/*'的情况*/
                else
                {syn=38;}
                break;

       case '*':token[m]=ch;
                p++;
                ch=prog[p];
                if(ch=='/')
                {
                    syn=52;
                    m++;
                    token[m]=ch;
                    p++;
                }
                else
                {syn=37;}
                break;

       case '+':syn=35;token[0]=ch;p++;break;
       case '-':syn=36;token[0]=ch;p++;break;
       case '=':syn=46;token[0]=ch;p++;break;
       case ';':syn=47;token[0]=ch;p++;break;
       case '(':syn=48;token[0]=ch;p++;break;
       case ')':syn=49;token[0]=ch;p++;break;
       case '%':syn=50;token[0]=ch;p++;break;
       case '{':syn=53;token[0]=ch;p++;break;
       case '}':syn=54;token[0]=ch;p++;break;
       case ',':syn=55;token[0]=ch;p++;break;
       case '#':syn=0;token[0]=ch;p++;break;
       default:syn=-1;
    }

}

void emit(char *result,char *ag1,char *op,char *ag2)//四元式生成
{
    cout << "(" << i << ")";
    cout << "(" << op << "," << ag1 << "," << ag2 << "," << result << ")" << endl;
    i++;
    return;
}

char *newTemp(void)//返回新的临时数组,p数组第一个字母为t,后面的是m数组中的内容
{
    char *p;
    char m[8];
    p=(char *)malloc(8);
    k++;
    itoa(k,m,10);//把k变成十进制字符串放入m数组
    strcpy(p+1,m);//把m中的字符串复制进p数组
    p[0]='t';//p第一行为t
    return(p);
}

int IrPar()
{
    int yucu();
    int schain=0;
    kk=0;
    if(syn!=1)
	{
        cout << "缺main错误!!" << endl;
        flag++;
	}
    scaner();
    if(syn!=48)
	{
        cout << "main后缺(括号!!" << endl;
        flag++;
	}
    else scaner();
    if(syn!=49)
	{
        cout << "main后缺)括号!!" << endl;
        flag++;
	}
    else scaner();
    if(syn!=53)
	{
        cout << "main后缺{括号!!" << endl;
        flag++;
	}
    else scaner();
    schain=yucu();
    if(syn==54)
    {
        scaner();
        if(syn==0 && kk==0 && flag==0)/*kk是用来记录其他错误的标识*/
        cout << "语法与语义分析结束。分析结果为:success" << endl;
		else
        cout << "程序有错误" << flag << "个" << endl;
    }
    else
    {
        if(kk!=1)
        cout << "缺}错误!!" << endl;
        kk=1;
    }
    return(schain);
}

int yucu()
{
    int statement();
    int schain=0;
    schain=statement();
    while(syn==47)
    {
        scaner();
        schain=statement();
    }
    return(schain);
}

int statement()
{
    char *expression();
    char tt[8],eplace[8];
    int schain=0;
    switch(syn)
    {
        case 33:
            strcpy(tt,token);
            scaner();
            if(syn==46)
            {
                scaner();
                strcpy(eplace,expression());
                emit(tt,eplace," "," ");
                schain=0;
            }
            else
            {
                cout << "赋值号=错误!!" << endl;
                kk=1;
            }
        return(schain);
        break;
    }
}

char *expression(void)
{
    char *term();
    char *tp,*ep2,*eplace,*tt;//给四个变量分配内存空间
    tp=(char *)malloc(12);
    ep2=(char *)malloc(12);
    eplace=(char *)malloc(12);
    tt=(char *)malloc(12);
    strcpy(eplace,term());
    while((syn==35) || (syn==36))
    {
        strcpy(tt,token);
        scaner();
        strcpy(ep2,term());
        strcpy(tp,newTemp());
        emit(tp,eplace,tt,ep2);
        strcpy(eplace,tp);
    }
    return(eplace);
}

char *term(void)
{
    char *factor();
    char *tp,*ep2,*eplace,*tt;
    tp=(char *)malloc(12);
    ep2=(char *)malloc(12);
    eplace=(char *)malloc(12);
    tt=(char *)malloc(12);
    strcpy(eplace,factor());
    while(syn==37||(syn==38))
    {
        strcpy(tt,token);
        scaner();
        strcpy(ep2,factor());
        strcpy(tp,newTemp());
        emit(tp,eplace,tt,ep2);
        strcpy(eplace,tp);
    }
    return(eplace);
}

char *factor(void)//factor函数返回指针变量fplace,判断
{
    char *fplace;
    fplace=(char *)malloc(12);
    strcpy(fplace," ");
    if(syn==33)
    {
       strcpy(fplace,token);//词法分析后如果是变量则把变量复制给fplace
       scaner();
    }
    else if(syn==34)
    {
       itoa(sum,fplace,10);//整型常数,转换成十进制数赋值给fplace并判断左括号后面是否有右括号
       scaner();
    }
    else if(syn==48)//判断是否左括号(
    {
        scaner();
        fplace=expression();
        if(syn==49)
        scaner();
        else
        {
            cout << "缺‘)’错误!!" << endl;
            kk=1;
            flag++;
        }
    }
    else
    {
        cout << "表达式错误!!" << endl;
        kk=1;
        flag++;
    }
    return(fplace);
}

//syn=33 为变量名
//itoa函数把一个整数转化为字符串

程序运行结果检测
PL/0语法分析下制作一个简易编译器
PL/0语法分析下制作一个简易编译器

相关文章: