回 帖 发 新 帖 刷新版面

主题:[求助]PL/0改写,添加REPEAT语句。谢谢各位了急

改写PL/0程序,功能是增加一个Repeat语句,各位帮忙啊,急,,,,

回复列表 (共2个回复)

沙发

给出源代码
    源代码
pl0c.h
/* 关键字个数 */
#define norw 13
/* 名字表容量 */
#define txmax 100
/* 所有的add1用于定义数组 */
#define txmaxadd1 101
/* number的最大位数 */
#define nmax 14
/* 符号的最大长度 */
#define al 10
/* 地址上界 */
#define amax 2047
/* 最大允许过程嵌套声明层数 */
#define levmax 3
/* 最多的虚拟机代码数 */
#define cxmax 200
#define cxmaxadd1 201

/* 当函数中会发生fatal error时,返回-1告知调用它的函数,最终退出程序 */
#define getsymdo if(-1==getsym())return -1
#define getchdo if(-1==getch())return -1
#define testdo(a,b,c) if(-1==test(a,b,c))return -1
#define gendo(a,b,c) if(-1==gen(a,b,c))return -1
#define expressiondo(a,b,c) if(-1==expression(a,b,c))return -1
#define factordo(a,b,c) if(-1==factor(a,b,c))return -1
#define termdo(a,b,c) if(-1==term(a,b,c))return -1
#define conditiondo(a,b,c) if(-1==condition(a,b,c))return -1
#define statementdo(a,b,c) if(-1==statement(a,b,c))return -1
#define constdeclarationdo(a,b,c) if(-1==constdeclaration(a,b,c))return -1
#define vardeclarationdo(a,b,c) if(-1==vardeclaration(a,b,c))return -1

typedef enum {false,true} bool;

/* 符号 */
enum symbol {nul,ident,number,plus,minus,times,slash,oddsym,eql,neq,lss,leq,gtr,geq,lparen,rparen,comma,semicolon,period,becomes,beginsym,endsym,ifsym,thensym,whilesym,writesym,readsym,dosym,callsym,constsym,varsym,procsym};
#define symnum 32

/* 名字表中的类型 */
enum object {constant,variable,procedur};

/* 虚拟机代码 */
enum fct {lit,opr,lod,sto,cal,inte,jmp,jpc};
#define fctnum 8

/* 虚拟机代码结构 */
struct instruction
{
    enum fct f; /* 虚拟机代码指令 */
    int l; /* 引用层与声明层的层次差 */
    int a; /* 根据f的不同而不同 */
};

FILE* fas;    /* 输出名字表 */
FILE* fa; /* 输出虚拟机代码 */
FILE* fa1; /* 输出源文件及其各行对应的首地址 */
FILE* fa2; /* 输出结果 */
bool listswitch; /* 显示虚拟机代码与否 */
bool tableswitch; /* 显示名字表与否 */
char ch; /* 获取字符的缓冲区,getch 使用 */
enum symbol sym; /* 当前的符号 */
char id[al]; /* 当前ident */
int num; /* 当前number */
int cc,ll,kk; /* getch使用的计数器,cc表示当前字符(ch)的位置 */
int cx; /* 虚拟机代码指针 */
char line[81]; /* 读取行缓冲区 */
char a[al]; /* 临时符号 */
struct instruction code[cxmaxadd1]; /* 存放虚拟机代码的数组 */
char word[norw][al]; /* 保留字 */
enum symbol wsym[norw]; /* 保留字对应的符号值 */
enum symbol ssym[256]; /* 单字符的符号值 */
char mnemonic[fctnum][5]; /* 虚拟机代码指令名称 */
bool declbegsys[symnum]; /* 表示声明开始的符号集合 */
bool statbegsys[symnum]; /* 表示语句开始的符号集合 */
bool facbegsys[symnum]; /* 表示因子开始的符号集合 */

/* 名字表结构 */
struct tablestruct
{
    char name[al];    /* 名字 */
    enum object kind;    /* 类型:const,var or procedure */
    int val; /* 数值,仅const使用 */
    int level; /* 所处层,仅const不使用 */
    int adr; /* 地址,仅const不使用 */
    int size; /* 需要分配的数据区空间,仅procedure使用 */
};

struct tablestruct table[txmaxadd1]; /* 名字表 */

FILE* fin;
FILE* fout;
char fname[al];
int err; /* 错误计数器 */

void error(int n);
int getsym();
int getch();
void init();
int gen(enum fct x,int y,int z);
int test(bool* s1,bool* s2,int n);
int inset(int e,bool* s);
int addset(bool* sr,bool* s1,bool* s2,int n);
int subset(bool* sr,bool* s1,bool* s2,int n);
int mulset(bool* sr,bool* s1,bool* s2,int n);
int block(int lev,int tx,bool* fsys);
void interpret();
int factor(bool* fsys,int* ptx,int lev);
int term(bool* fsys,int* ptx,int lev);
int condition(bool* fsys,int* ptx,int lev);
int expression(bool* fsys,int* ptx,int lev);
int statement(bool* fsys,int* ptx,int lev);
void listcode(int cx0);
int vardeclaration(int* ptx,int lev,int* pdx);
int constdeclaration(int* ptx,int lev,int* pdx);
int postion(char* idt,int tx);
void enter(enum object k,int* ptx,int lev,int* pdx);
int base(int l,int* s,int b);

板凳

pl0c.c
/*
Windows 下c语言PL/0编译程序
在Visual C++ 6.0和Visual C.NET上运行通过
使用方法:
运行后输入PL/0源程序文件名
回答是否输出虚拟机代码
回答是否输出名字表
fa.tmp输出虚拟机代码
fa1.tmp输出源文件及其各行对应的首地址
fa2.tmp输出结果
fas.tmp输出名字表
*/

#include <stdio.h>
#include "pl0c.h"
#include "string.h"

/* 解释执行时使用的栈 */
#define stacksize 500






int main()
{
    bool nxtlev[symnum];
    init();        /* 初始化 */
    fas=fopen("fas.tmp","w");
    fa1=fopen("fa1.tmp","w");
    printf("Input file?   ");
    fprintf(fa1,"Input file?   ");
    scanf("%s",fname);        /* 输入文件名 */
    fin=fopen(fname,"r");
    if(fin)
    {
        fprintf(fa1,"%s\n",fname);
        printf("List object code?(Y/N)");    /* 是否输出虚拟机代码 */
        scanf("%s",fname);
        listswitch=(fname[0]=='y'||fname[0]=='Y');
        printf("List symbol table?(Y/N)");    /* 是否输出名字表 */
        scanf("%s",fname);
        tableswitch=(fname[0]=='y'||fname[0]=='Y');
        err=0;
        cc=cx=ll=0;
        ch=' ';
        kk=al-1;

        if(-1!=getsym())
        {
            fa=fopen("fa.tmp","w");
            fa2=fopen("fa2.tmp","w");
            addset(nxtlev,declbegsys,statbegsys,symnum);
            nxtlev[period]=true;
            if(-1==block(0,0,nxtlev))    /* 调用编译程序 */
            {
                fclose(fa);
                fclose(fa1);
                fclose(fin);
                printf("\n");
                return 0;
            }
            fclose(fa);
            fclose(fa1);
            if(sym!=period)error(9);
            if(err==0)interpret();    /* 调用解释执行程序 */
            else
            {
                printf("Errors in pl/0 program");
            }
        }
        fclose(fin);
    }
    else
    {
        printf("Can't open file!\n");
        fprintf(fa1,"Can't open file!\n");
        fclose(fa1);
    }
    fclose(fas);
    printf("\n");
    return 0;
}




我来回复

您尚未登录,请登录后再回复。点此登录或注册