PL0扩展for to语句

修改头文件:

1、增加关键字个数( 第15行附近):增加2个

#define norw 16     /* 关键字个数 */

2、增加forsym,tosym符号(第24行附近)

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,	elsesym,	forsym,    tosym,
};

3、修改符号数量(第33行附近):增加2个

#define symnum 35

修改源文件:

1、增加for,to保留字(第130行附近)

	strcpy(&(word[0][0]), "begin");
	strcpy(&(word[1][0]), "call");
	strcpy(&(word[2][0]), "const");
	strcpy(&(word[3][0]), "do");
	strcpy(&(word[4][0]), "else");
	strcpy(&(word[5][0]), "end");
	strcpy(&(word[6][0]), "for");
	strcpy(&(word[7][0]), "if");
	strcpy(&(word[8][0]), "odd");
	strcpy(&(word[9][0]), "procedure");
	strcpy(&(word[10][0]), "read");
	strcpy(&(word[11][0]), "then");
	strcpy(&(word[12][0]), "to");
	strcpy(&(word[13][0]), "var");
	strcpy(&(word[14][0]), "while");
	strcpy(&(word[15][0]), "write");

2、增加for保留字符号(150行附近)

	wsym[0] = beginsym;
	wsym[1] = callsym;
	wsym[2] = constsym;
	wsym[3] = dosym;
	wsym[4] = elsesym;
	wsym[5] = endsym;
	wsym[6] = forsym;
	wsym[7] = ifsym;
	wsym[8] = oddsym;
	wsym[9] = procsym;
	wsym[10] = readsym;
	wsym[11] = thensym;
	wsym[12] = tosym;
	wsym[13] = varsym;
	wsym[14] = whilesym;
	wsym[15] = writesym;

 

4、增加for语义处理

在代码第780行附近能找到“  if (sym == ident)  /*准备按照赋值语句处理*/”,在下面找到与之相关的else,在它们之间增加一个else if语句

else if(sym==forsym)      //检测到for语句
    {
        getsymdo;
        if(sym==ident)
        {
            i=position(id,*ptx);
            if(i==0) error(11);
            else
            {
                if(table[i].kind!=variable) //赋值语句中,赋值号左部标识符属性应是变量
                {
                    error(12);i=0;
                }
                else
                {
                    getsymdo;
                    if(sym!=becomes) error(13);             //赋值语句左部标识符后应是赋值号:=
                    else getsymdo;
                    memcpy(nxtlev,fsys,sizeof(bool)*symnum); 
                    nxtlev[tosym]=true;                     //后跟符to和downto
                    expressiondo(nxtlev,ptx,lev);           //处理赋值语句右部的表达式E1
                    gendo(sto,lev-table[i].level,table[i].adr);     //保存初值
                 	if(sym==tosym){
					 
                        getsymdo;
                        cx1=cx;       //保存循环开始点
                        //将循环判断变量取出放到栈顶
                        gendo(lod,lev-table[i].level,table[i].adr);                                        
                        memcpy(nxtlev,fsys,sizeof(bool)*symnum);    //处理表达式E2
                        nxtlev[dosym]=true;                         //后跟符do
                        expressiondo(nxtlev,ptx,lev);
                        /*判断循环变量条件,比如for i:=E1 to E2 do S中,判断i是否小于E2,如小于等于,继续循环,大于的话,跳出循环*/     
                        gendo(opr,0,13);             //生成比较指令,i是否小于等于E2的值
                        cx2=cx;                      //保存循环结束点
                        //生成条件跳转指令,跳出循环,跳出的地址未知
                        gendo(jpc,0,0);                     
                        if(sym==dosym)               //处理循环体S
                        {
                            getsymdo;
                            statement(fsys,ptx,lev);  //循环体处理
                            //增加循环变量步长为
                            //将循环变量取出放在栈顶
                            gendo(lod,lev-table[i].level,table[i].adr);                                       
                            gendo(lit,0,1);                            //将步长取到栈顶
                            gendo(opr,0,2);                            //循环变量加步长
                            //将栈顶的值存入循环变量
                            gendo(sto,lev-table[i].level,table[i].adr); 
                            gendo(jmp,0,cx1);                 //无条件跳转到循环开始点
                            /*回填循环结束点的地址,cx为else后语句执行完的位置,它正是前面未定的跳转地址*/
                            code[cx2].a=cx;                     
                         }
                         else
                         {
                            error(29);    //for语句中少了do
                         }
                    }
                }
            }
        }
    }

 测试代码:

var i,a;
begin
  read(a); 
  for i:=1 to 10 do
  begin
     write(i);
     write(i*a);
   end;
end. 

运行截图

源代码:

头文件

/*
 * PL/0 complier program for win32 platform (implemented in C)
 *
 * The program has been test on Visual C++ 6.0,  Visual C++.NET and
 * Visual C++.NET 2003,  on Win98,  WinNT,  Win2000,  WinXP and Win2003
 *
 */

typedef enum {
    false,
    true
} bool;


#define norw 16     /* ¹Ø¼ü×Ö¸öÊý */
#define txmax 100   /* Ãû×Ö±íÈÝÁ¿ */
#define nmax 14     /* numberµÄ×î´óλÊý */
#define al 10       /* ·ûºÅµÄ×î´ó³¤¶È */
#define amax 2047   /* µØÖ·ÉϽç*/
#define levmax 3    /* ×î´óÔÊÐí¹ý³ÌǶÌ×ÉùÃ÷²ãÊý [0,  levmax]*/
#define cxmax 500   /* ×î¶àµÄÐéÄâ»ú´úÂëÊý */

/* ·ûºÅ */
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,	elsesym,	forsym, 	tosym,
};
#define symnum 35

/* Ãû×Ö±íÖеÄÀàÐÍ */
enum object {
    constant,
    variable,
    procedur,
    array       //add
};

/* ÐéÄâ»ú´úÂë */
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+1];      /* µ±Ç°ident, ¶à³öµÄÒ»¸ö×Ö½ÚÓÃÓÚ´æ·Å0 */
int num;            /* µ±Ç°number */
int cc, ll;          /* getchʹÓõļÆÊýÆ÷£¬cc±íʾµ±Ç°×Ö·û(ch)µÄλÖà */
int cx;             /* ÐéÄâ»ú´úÂëÖ¸Õë, È¡Öµ·¶Î§[0, cxmax-1]*/
char line[81];      /* ¶ÁÈ¡Ðлº³åÇø */
char a[al+1];       /* ÁÙʱ·ûºÅ, ¶à³öµÄÒ»¸ö×Ö½ÚÓÃÓÚ´æ·Å0 */
struct instruction code[cxmax]; /* ´æ·ÅÐéÄâ»ú´úÂëµÄÊý×é */
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, array or procedure */
    int val;            /* ÊýÖµ£¬½öconstʹÓà */
    int level;          /* Ëù´¦²ã£¬½öconst²»Ê¹Óà */
    int adr;            /* µØÖ·£¬½öconst²»Ê¹Óà */
    int size;           /* ÐèÒª·ÖÅäµÄÊý¾ÝÇø¿Õ¼ä, ½öprocedureʹÓà */
};

struct tablestruct table[txmax]; /* Ãû×Ö±í */

FILE* fin;
FILE* fout;
char fname[al];
int err; /* ´íÎó¼ÆÊýÆ÷ */

/* µ±º¯ÊýÖлᷢÉú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

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 position(char* idt, int tx);
void enter(enum object k, int* ptx, int lev, int* pdx);
int base(int l, int* s, int b);

源文件 

/*
 * PL/0 complier program for win32 platform (implemented in C)
 *
 * The program has been test on Visual C++ 6.0, Visual C++.NET and
 * Visual C++.NET 2003, on Win98, WinNT, Win2000, WinXP and Win2003
 *
 * ʹÓ÷½·¨£º
 * ÔËÐкóÊäÈëPL/0Ô´³ÌÐòÎļþ?
 * »Ø´ðÊÇ·ñÊä³öÐéÄâ»ú´úÂë
 * »Ø´ðÊÇ·ñÊä³öÃû×Ö±í
 * fa.tmpÊä³öÐéÄâ»ú´úÂë
 * fa1.tmpÊä³öÔ´Îļþ¼°Æä¸÷ÐжÔÓ¦µÄÊ×µØÖ·
 * fa2.tmpÊä³ö½á?
 * fas.tmpÊä³öÃû×Ö±í
 */

#include <stdio.h>

#include "pl0.h"
#include "string.h"

/* ½âÊÍÖ´ÐÐʱʹÓõÄÕ» */
#define stacksize 500


int main()
{
	bool nxtlev[symnum];

	printf("Input pl/0 file?   ");
	scanf("%s", fname);     /* ÊäÈëÎļþÃû */

	fin = fopen(fname, "r");

	if (fin)
	{
		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');

		fa1 = fopen("fa1.tmp", "w");
		fprintf(fa1,"Input pl/0 file?   ");
		fprintf(fa1,"%s\n",fname);

		init();     /* ³õʼ»¯ */

		err = 0;
		cc = cx = ll = 0;
		ch = ' ';

		if(-1 != getsym())
		{
			fa = fopen("fa.tmp", "w");
			fas = fopen("fas.tmp", "w");
			addset(nxtlev, declbegsys, statbegsys, symnum);
			nxtlev[period] = true;

			if(-1 == block(0, 0, nxtlev))   /* µ÷ÓñàÒë³ÌÐò */
			{
				fclose(fa);
				fclose(fa1);
				fclose(fas);
				fclose(fin);
				printf("\n");
				return 0;
			}
			fclose(fa);
			fclose(fa1);
			fclose(fas);

			if (sym != period)
			{
				error(9);
			}

			if (err == 0)
			{
				fa2 = fopen("fa2.tmp", "w");
				interpret();    /* µ÷ÓýâÊÍÖ´ÐгÌÐò */
				fclose(fa2);
			}
			else
			{
				printf("Errors in pl/0 program");
			}
		}

		fclose(fin);
	}
	else
	{
		printf("Can't open file!\n");
	}

	printf("\n");
	return 0;
}

/*
* ³õʼ»¯
*/
void init()
{
	int i;

	/* ÉèÖõ¥×Ö·û·ûºÅ */
	for (i=0; i<=255; i++)
	{
		ssym[i] = nul;
	}
	ssym['+'] = plus;
	ssym['-'] = minus;
	ssym['*'] = times;
	ssym['/'] = slash;
	ssym['('] = lparen;
	ssym[')'] = rparen;
	ssym['='] = eql;
	ssym[','] = comma;
	ssym['.'] = period;
	ssym['#'] = neq;
	ssym[';'] = semicolon;

	/* ÉèÖñ£Áô×ÖÃû×Ö,°´ÕÕ×Öĸ˳Ðò£¬±ãÓÚÕÛ°ë²éÕÒ */
	strcpy(&(word[0][0]), "begin");
	strcpy(&(word[1][0]), "call");
	strcpy(&(word[2][0]), "const");
	strcpy(&(word[3][0]), "do");
	strcpy(&(word[4][0]), "else");
	strcpy(&(word[5][0]), "end");
	strcpy(&(word[6][0]), "for");
	strcpy(&(word[7][0]), "if");
	strcpy(&(word[8][0]), "odd");
	strcpy(&(word[9][0]), "procedure");
	strcpy(&(word[10][0]), "read");
	strcpy(&(word[11][0]), "then");
	strcpy(&(word[12][0]), "to");
	strcpy(&(word[13][0]), "var");
	strcpy(&(word[14][0]), "while");
	strcpy(&(word[15][0]), "write");
	

	/* ÉèÖñ£Áô×Ö·ûºÅ */
	wsym[0] = beginsym;
	wsym[1] = callsym;
	wsym[2] = constsym;
	wsym[3] = dosym;
	wsym[4] = elsesym;
	wsym[5] = endsym;
	wsym[6] = forsym;
	wsym[7] = ifsym;
	wsym[8] = oddsym;
	wsym[9] = procsym;
	wsym[10] = readsym;
	wsym[11] = thensym;
	wsym[12] = tosym;
	wsym[13] = varsym;
	wsym[14] = whilesym;
	wsym[15] = writesym;

	/* ÉèÖÃÖ¸ÁîÃû³Æ */
	strcpy(&(mnemonic[lit][0]), "lit");
	strcpy(&(mnemonic[opr][0]), "opr");
	strcpy(&(mnemonic[lod][0]), "lod");
	strcpy(&(mnemonic[sto][0]), "sto");
	strcpy(&(mnemonic[cal][0]), "cal");
	strcpy(&(mnemonic[inte][0]), "int");
	strcpy(&(mnemonic[jmp][0]), "jmp");
	strcpy(&(mnemonic[jpc][0]), "jpc");

	/* ÉèÖ÷ûºÅ¼¯ */
	for (i=0; i<symnum; i++)
	{
		declbegsys[i] = false;
		statbegsys[i] = false;
		facbegsys[i] = false;
	}

	/* ÉèÖÃÉùÃ÷¿ªÊ¼·ûºÅ¼¯ */
	declbegsys[constsym] = true;
	declbegsys[varsym] = true;
	declbegsys[procsym] = true;

	/* ÉèÖÃÓï¾ä¿ªÊ¼·ûºÅ¼¯ */
	statbegsys[beginsym] = true;
	statbegsys[callsym] = true;
	statbegsys[ifsym] = true;
	statbegsys[whilesym] = true;

	/* ÉèÖÃÒò×Ó¿ªÊ¼·ûºÅ¼¯ */
	facbegsys[ident] = true;
	facbegsys[number] = true;
	facbegsys[lparen] = true;
}

/*
* ÓÃÊý×éʵÏÖ¼¯ºÏµÄ¼¯ºÏÔËËã
*/
int inset(int e, bool* s)
{
	return s[e];
}

int addset(bool* sr, bool* s1, bool* s2, int n)
{
	int i;
	for (i=0; i<n; i++)
	{
		sr[i] = s1[i]||s2[i];
	}
	return 0;
}

int subset(bool* sr, bool* s1, bool* s2, int n)
{
	int i;
	for (i=0; i<n; i++)
	{
		sr[i] = s1[i]&&(!s2[i]);
	}
	return 0;
}

int mulset(bool* sr, bool* s1, bool* s2, int n)
{
	int i;
	for (i=0; i<n; i++)
	{
		sr[i] = s1[i]&&s2[i];
	}
	return 0;
}

/*
*   ³ö´í´¦Àí£¬´òÓ¡³ö´íλÖúʹíÎó±àÂë
*/
void error(int n)
{
	char space[81];
	memset(space,32,81);

	space[cc-1]=0; //³ö´íʱµ±Ç°·ûºÅÒѾ­¶ÁÍ꣬ËùÒÔcc-1

	printf("****%s!%d\n", space, n);
	fprintf(fa1,"****%s!%d\n", space, n);

	err++;
}

/*
* ©µô¿Õ¸ñ£¬¶ÁÈ¡Ò»¸ö×Ö·û¡£
*
* ÿ´Î¶ÁÒ»ÐУ¬´æÈëline»º³åÇø£¬line±»getsymÈ¡¿ÕºóÔÙ¶ÁÒ»ÐÐ
*
* ±»º¯Êýgetsymµ÷Óá£
*/
int getch()
{
	if (cc == ll)
	{
		if (feof(fin))
		{
			printf("program incomplete");
			return -1;
		}
		ll=0;
		cc=0;
		printf("%d ", cx);
		fprintf(fa1,"%d ", cx);
		ch = ' ';
		while (ch != 10)
		{
			//fscanf_s(fin,"%c", &ch)
			//richard
			if (EOF == fscanf(fin,"%c", &ch))
			{
				line[ll] = 0;
				break;
			}
			//end richard
			printf("%c", ch);
			fprintf(fa1, "%c", ch);
			line[ll] = ch;
			ll++;
		}
		printf("\n");
		fprintf(fa1, "\n");
	}
	ch = line[cc];
	cc++;
	return 0;
}

/*
* ´Ê·¨·ÖÎö£¬»ñÈ¡Ò»¸ö·ûºÅ
*/
int getsym()
{
	int i,j,k;

	/* the original version lacks "\r", thanks to foolevery */
	while (ch==' ' || ch==10 || ch==13 || ch==9)  /* ºöÂÔ¿Õ¸ñ¡¢»»ÐС¢»Ø³µºÍTAB */
	{
		getchdo;
	}
	if (ch>='a' && ch<='z')
	{           /* Ãû×Ö»ò±£Áô×ÖÒÔa..z¿ªÍ· */
		k = 0;
		do {
			if(k<al)
			{
				a[k] = ch;
				k++;
			}
			getchdo;
		} while (ch>='a' && ch<='z' || ch>='0' && ch<='9');
		a[k] = 0;
		strcpy(id, a);
		i = 0;
		j = norw-1;
		do {    /* ËÑË÷µ±Ç°·ûºÅÊÇ·ñΪ±£Áô×Ö */
			k = (i+j)/2;
			if (strcmp(id,word[k]) <= 0)
			{
				j = k - 1;
			}
			if (strcmp(id,word[k]) >= 0)
			{
				i = k + 1;
			}
		} while (i <= j);
		if (i-1 > j)
		{
			sym = wsym[k];
		}
		else
		{
			sym = ident; /* ËÑË÷ʧ°ÜÔò£¬ÊÇÃû×Ö»òÊý×Ö */
		}
	}
	else
	{
		if (ch>='0' && ch<='9')
		{           /* ¼ì²âÊÇ·ñΪÊý×Ö£ºÒÔ0..9¿ªÍ· */
			k = 0;
			num = 0;
			sym = number;
			do {
				num = 10*num + ch - '0';
				k++;
				getchdo;
			} while (ch>='0' && ch<='9'); /* »ñÈ¡Êý×ÖµÄÖµ */
			k--;
			if (k > nmax)
			{
				error(30);
			}
		}
		else
		{
			if (ch == ':')      /* ¼ì²â¸³Öµ·ûºÅ */
			{
				getchdo;
				if (ch == '=')
				{
					sym = becomes;
					getchdo;
				}
				else
				{
					sym = nul;  /* ²»ÄÜʶ±ðµÄ·ûºÅ */
				}
			}
			else
			{
				if (ch == '<')      /* ¼ì²âСÓÚ»òСÓÚµÈÓÚ·ûºÅ */
				{
					getchdo;
					if (ch == '=')
					{
						sym = leq;
						getchdo;
					}
					else
					{
						sym = lss;
					}
				}
				else
				{
					if (ch=='>')        /* ¼ì²â´óÓÚ»ò´óÓÚµÈÓÚ·ûºÅ */
					{
						getchdo;
						if (ch == '=')
						{
							sym = geq;
							getchdo;
						}
						else
						{
							sym = gtr;
						}
					}
					else
					{
						sym = ssym[ch];     /* µ±·ûºÅ²»Âú×ãÉÏÊöÌõ¼þʱ£¬È«²¿°´ÕÕµ¥×Ö·û·ûºÅ´¦Àí */
						//getchdo;
						//richard
						if (sym != period)
						{
							getchdo;
						}
						//end richard
					}
				}
			}
		}
	}
	return 0;
}

/*
* Éú³ÉÐéÄâ»ú´úÂë
*
* x: instruction.f;
* y: instruction.l;
* z: instruction.a;
*/
int gen(enum fct x, int y, int z )
{
	if (cx >= cxmax)
	{
		printf("Program too long"); /* ³ÌÐò¹ý³¤ */
		return -1;
	}
	code[cx].f = x;
	code[cx].l = y;
	code[cx].a = z;
	cx++;
	return 0;
}


/*
* ²âÊÔµ±Ç°·ûºÅÊÇ·ñºÏ·¨
*
* ÔÚijһ²¿·Ö£¨ÈçÒ»ÌõÓï¾ä£¬Ò»¸ö±í´ïʽ£©½«Òª½áÊøʱʱÎÒÃÇÏ£ÍûÏÂÒ»¸ö·ûºÅÊôÓÚij¼¯?
* £¨¸Ã²¿·ÖµÄºó¸ú·ûºÅ£©£¬test¸ºÔðÕâÏî¼ì²â£¬²¢ÇÒ¸ºÔðµ±¼ì²â²»Í¨¹ýʱµÄ²¹¾È´ëÊ©£¬
* ³ÌÐòÔÚÐèÒª¼ì²âʱָ¶¨µ±Ç°ÐèÒªµÄ·ûºÅ¼¯ºÏºÍ²¹¾ÈÓõļ¯ºÏ£¨Èç֮ǰδÍê³É²¿·ÖµÄºó¸ú
* ·ûºÅ£©£¬ÒÔ¼°¼ì²â²»Í¨¹ýʱµÄ´íÎóºÅ¡£
*
* s1:   ÎÒÃÇÐèÒªµÄ·ûºÅ
* s2:   Èç¹û²»ÊÇÎÒÃÇÐèÒªµÄ£¬ÔòÐèÒªÒ»¸ö²¹¾ÈÓõļ¯?
* n:    ´íÎóºÅ
*/
int test(bool* s1, bool* s2, int n)
{
	if (!inset(sym, s1))
	{
		error(n);
		/* µ±¼ì²â²»Í¨¹ýʱ£¬²»Í£»ñÈ¡·ûºÅ£¬Ö±µ½ËüÊôÓÚÐèÒªµÄ¼¯ºÏ»ò²¹¾ÈµÄ¼¯ºÏ */
		while ((!inset(sym,s1)) && (!inset(sym,s2)))
		{
			getsymdo;
		}
	}
	return 0;
}

/*
* ±àÒë³ÌÐòÖ÷?
*
* lev:    µ±Ç°·Ö³ÌÐòËùÔÚ²ã
* tx:     Ãû×Ö±íµ±Ç°Î²Ö¸Õë
* fsys:   µ±Ç°Ä£¿éºó¸ú·ûºÅ¼¯?
*/
int block(int lev, int tx, bool* fsys)
{
	int i;

	int dx;                 /* Ãû×Ö·ÖÅäµ½µÄÏà¶ÔµØÖ· */
	int tx0;                /* ±£Áô³õʼtx */
	int cx0;                /* ±£Áô³õʼcx */
	bool nxtlev[symnum];    /* ÔÚϼ¶º¯ÊýµÄ²ÎÊýÖУ¬·ûºÅ¼¯ºÏ¾ùΪֵ²Î£¬µ«ÓÉÓÚʹÓÃÊý×éʵÏÖ£¬
							´«µÝ½øÀ´µÄÊÇÖ¸Õ룬Ϊ·Àֹϼ¶º¯Êý¸Ä±äÉϼ¶º¯ÊýµÄ¼¯ºÏ£¬¿ª±ÙеĿÕ?
							´«µÝ¸øϼ¶º¯Êý*/

	dx = 3;
	tx0 = tx;               /* ¼Ç¼±¾²ãÃû×ֵijõʼλÖà */
	table[tx].adr = cx;

	gendo(jmp, 0, 0);

	if (lev > levmax)
	{
		error(32);
	}

	do {

		if (sym == constsym)    /* ÊÕµ½³£Á¿ÉùÃ÷·ûºÅ£¬¿ªÊ¼´¦Àí³£Á¿ÉùÃ÷ */
		{
			getsymdo;

			/* the original do...while(sym == ident) is problematic, thanks to calculous */
			/* do { */
			constdeclarationdo(&tx, lev, &dx);  /* dxµÄÖµ»á±»constdeclaration¸Ä±ä£¬Ê¹ÓÃÖ¸Õë */
			while (sym == comma)
			{
				getsymdo;
				constdeclarationdo(&tx, lev, &dx);
			}
			if (sym == semicolon)
			{
				getsymdo;
			}
			else
			{
				error(5);   /*©µôÁ˶ººÅ»òÕß·ÖºÅ*/
			}
			/* } while (sym == ident); */
		}

		if (sym == varsym)      /* ÊÕµ½±äÁ¿ÉùÃ÷·ûºÅ£¬¿ªÊ¼´¦Àí±äÁ¿ÉùÃ÷ */
		{
			getsymdo;

			/* the original do...while(sym == ident) is problematic, thanks to calculous */
			/* do {  */
			vardeclarationdo(&tx, lev, &dx);
			while (sym == comma)
			{
				getsymdo;
				vardeclarationdo(&tx, lev, &dx);
			}
			if (sym == semicolon)
			{
				getsymdo;
			}
			else
			{
				error(5);
			}
			/* } while (sym == ident);  */
		}

		while (sym == procsym) /* ÊÕµ½¹ý³ÌÉùÃ÷·ûºÅ£¬¿ªÊ¼´¦Àí¹ý³ÌÉùÃ÷ */
		{
			getsymdo;

			if (sym == ident)
			{
				enter(procedur, &tx, lev, &dx); /* ¼Ç¼¹ý³ÌÃû×Ö */
				getsymdo;
			}
			else
			{
				error(4);   /* procedureºóӦΪ±êʶ·û */
			}

			if (sym == semicolon)
			{
				getsymdo;
			}
			else
			{
				error(5);   /* ©µôÁ˷ֺŠ*/
			}

			memcpy(nxtlev, fsys, sizeof(bool)*symnum);
			nxtlev[semicolon] = true;
			if (-1 == block(lev+1, tx, nxtlev))
			{
				return -1;  /* µÝ¹éµ÷Óà */
			}

			if(sym == semicolon)
			{
				getsymdo;
				memcpy(nxtlev, statbegsys, sizeof(bool)*symnum);
				nxtlev[ident] = true;
				nxtlev[procsym] = true;
				testdo(nxtlev, fsys, 6);
			}
			else
			{
				error(5);   /* ©µôÁ˷ֺŠ*/
			}
		}
		memcpy(nxtlev, statbegsys, sizeof(bool)*symnum);
		nxtlev[ident] = true;
		testdo(nxtlev, declbegsys, 7);
	} while (inset(sym, declbegsys));   /* Ö±µ½Ã»ÓÐÉùÃ÷·ûºÅ */

	code[table[tx0].adr].a = cx;    /* ¿ªÊ¼Éú³Éµ±Ç°¹ý³Ì´úÂë */
	table[tx0].adr = cx;            /* µ±Ç°¹ý³Ì´úÂëµØÖ· */
	table[tx0].size = dx;           /* ÉùÃ÷²¿·ÖÖÐÿÔö¼ÓÒ»ÌõÉùÃ÷¶¼»á¸ødxÔö¼Ó1£¬ÉùÃ÷²¿·ÖÒѾ­½áÊø£¬dx¾ÍÊǵ±Ç°¹ý³ÌÊý¾ÝµÄsize */
	cx0 = cx;
	gendo(inte, 0, dx);             /* Éú³É·ÖÅäÄÚ´æ´úÂë */

	if (tableswitch)        /* Êä³öÃû×Ö±í */
	{
		printf("TABLE:\n");
		if (tx0+1 > tx)
		{
			printf("    NULL\n");
		}
		for (i=tx0+1; i<=tx; i++)
		{
			switch (table[i].kind)
			{
			case constant:
				printf("    %d const %s ", i, table[i].name);
				printf("val=%d\n", table[i].val);
				fprintf(fas, "    %d const %s ", i, table[i].name);
				fprintf(fas, "val=%d\n", table[i].val);
				break;
			case variable:
				printf("    %d var   %s ", i, table[i].name);
				printf("lev=%d addr=%d\n", table[i].level, table[i].adr);
				fprintf(fas, "    %d var   %s ", i, table[i].name);
				fprintf(fas, "lev=%d addr=%d\n", table[i].level, table[i].adr);
				break;
			case procedur:
				printf("    %d proc  %s ", i, table[i].name);
				printf("lev=%d addr=%d size=%d\n", table[i].level, table[i].adr, table[i].size);
				fprintf(fas,"    %d proc  %s ", i, table[i].name);
				fprintf(fas,"lev=%d addr=%d size=%d\n", table[i].level, table[i].adr, table[i].size);
				break;
			}
		}
		printf("\n");
	}

	/* Óï¾äºó¸ú·ûºÅΪ·ÖºÅ»òend */
	memcpy(nxtlev, fsys, sizeof(bool)*symnum);  /* ÿ¸öºó¸ú·ûºÅ¼¯ºÍ¶¼°üº¬Éϲãºó¸ú·ûºÅ¼¯ºÍ£¬ÒԱ㲹¾È */
	nxtlev[semicolon] = true;
	nxtlev[endsym] = true;
	statementdo(nxtlev, &tx, lev);
	gendo(opr, 0, 0);                       /* ÿ¸ö¹ý³Ì³ö¿Ú¶¼ÒªÊ¹ÓõÄÊÍ·ÅÊý¾Ý¶ÎÖ¸Áî */
	memset(nxtlev, 0, sizeof(bool)*symnum); /*·Ö³ÌÐòûÓв¹¾È¼¯ºÏ */
	testdo(fsys, nxtlev, 8);                /* ¼ì²âºó¸ú·ûºÅÕýÈ·ÐÔ */
	listcode(cx0);                          /* Êä³ö´úÂë */
	return 0;
}

/*
* ÔÚÃû×Ö±íÖмÓÈëÒ»Ïî
*
* k:      Ãû×ÖÖÖÀàconst,var or procedure
* ptx:    Ãû×Ö±íβָÕëµÄÖ¸Õ룬ΪÁË¿ÉÒԸıäÃû×Ö±íβָÕëµÄÖµ
* lev:    Ãû×ÖËùÔڵIJã´Î,£¬ÒÔºóËùÓеÄlev¶¼ÊÇÕâÑù
* pdx:    dxΪµ±Ç°Ó¦·ÖÅäµÄ±äÁ¿µÄÏà¶ÔµØÖ·£¬·ÖÅäºóÒªÔö¼Ó1
*/
void enter(enum object k, int* ptx, int lev, int* pdx)
{
	(*ptx)++;
	strcpy(table[(*ptx)].name, id); /* È«¾Ö±äÁ¿idÖÐÒÑ´æÓе±Ç°Ãû×ÖµÄÃû×Ö */
	table[(*ptx)].kind = k;
	switch (k)
	{
	case constant:  /* ³£Á¿Ãû×Ö */
		if (num > amax)
		{
			error(31);  /* ÊýÔ½½ç */
			num = 0;
		}
		table[(*ptx)].val = num;
		break;
	case variable:  /* ±äÁ¿Ãû×Ö */
		table[(*ptx)].level = lev;
		table[(*ptx)].adr = (*pdx);
		(*pdx)++;
		break;
	case procedur:  /*¡¡¹ý³ÌÃû×Ö¡¡*/
		table[(*ptx)].level = lev;
		break;
	}
}

/*
* ²éÕÒÃû×ÖµÄλÖÃ.
* ÕÒµ½Ôò·µ»ØÔÚÃû×Ö±íÖеÄλÖÃ,·ñÔò·µ»Ø0.
*
* idt:    Òª²éÕÒµÄÃû×Ö
* tx:     µ±Ç°Ãû×Ö±íβָÕë
*/
int position(char* idt, int tx)
{
	int i;
	strcpy(table[0].name, idt);
	i = tx;
	while (strcmp(table[i].name, idt) != 0)
	{
		i--;
	}
	return i;
}

/*
* ³£Á¿ÉùÃ÷´¦Àí
*/
int constdeclaration(int* ptx, int lev, int* pdx)
{
	if (sym == ident)
	{
		getsymdo;
		if (sym==eql || sym==becomes)
		{
			if (sym == becomes)
			{
				error(1);   /* °Ñ=д³ÉÁË:= */
			}
			getsymdo;
			if (sym == number)
			{
				enter(constant, ptx, lev, pdx);
				getsymdo;
			}
			else
			{
				error(2);   /* ³£Á¿ËµÃ÷=ºóÓ¦ÊÇÊý×Ö */
			}
		}
		else
		{
			error(3);   /* ³£Á¿ËµÃ÷±êʶºóÓ¦ÊÇ= */
		}
	}
	else
	{
		error(4);   /* constºóÓ¦ÊDZêʶ */
	}
	return 0;
}

/*
* ±äÁ¿ÉùÃ÷´¦Àí
*/
int vardeclaration(int* ptx,int lev,int* pdx)
{
	if (sym == ident)
	{
		enter(variable, ptx, lev, pdx); // ÌîдÃû×Ö±í
		getsymdo;
	}
	else
	{
		error(4);   /* varºóÓ¦ÊDZêʶ */
	}
	return 0;
}

/*
* Êä³öÄ¿±ê´úÂëÇåµ¥
*/
void listcode(int cx0)
{
	int i;
	if (listswitch)
	{
		for (i=cx0; i<cx; i++)
		{
			printf("%d %s %d %d\n", i, mnemonic[code[i].f], code[i].l, code[i].a);
			fprintf(fa,"%d %s %d %d\n", i, mnemonic[code[i].f], code[i].l, code[i].a);
		}
	}
}

/*
* Óï¾ä´¦Àí
*/
int statement(bool* fsys, int* ptx, int lev)
{
	int i, cx1, cx2, cx3, cx4, cx5;
	bool nxtlev[symnum];

	if (sym == ident)   /* ×¼±¸°´ÕÕ¸³ÖµÓï¾ä´¦Àí */
	{
		i = position(id, *ptx);
		if (i == 0)
		{
			error(11);  /* ±äÁ¿Î´ÕÒµ½ */
		}
		else
		{
			if(table[i].kind != variable)
			{
				error(12);  /* ¸³ÖµÓï¾ä¸ñʽ´íÎó */
				i = 0;
			}
			else
			{
				getsymdo;
				if(sym == becomes)
				{
					getsymdo;
				}
				else
				{
					error(13);  /* ûÓмì²âµ½¸³Öµ·ûºÅ */
				}
				memcpy(nxtlev, fsys, sizeof(bool)*symnum);
				expressiondo(nxtlev, ptx, lev); /* ´¦Àí¸³Öµ·ûºÅÓÒ²à±í´ïʽ */
				if(i != 0)
				{
					/* expression½«Ö´ÐÐһϵÁÐÖ¸Áµ«×îÖÕ½á¹û½«»á±£´æÔÚÕ»¶¥£¬Ö´ÐÐstoÃüÁîÍê³É¸³Öµ */
					gendo(sto, lev-table[i].level, table[i].adr);
				}
			}
		}//if (i == 0)
	}
	 else if(sym==forsym)      //¼ì²âµ½forÓï¾ä
    {
        getsymdo;
        if(sym==ident)
        {
            i=position(id,*ptx);
            if(i==0) error(11);
            else
            {
                if(table[i].kind!=variable) //¸³ÖµÓï¾äÖУ¬¸³ÖµºÅ×󲿱êʶ·ûÊôÐÔÓ¦ÊDZäÁ¿
                {
                    error(12);i=0;
                }
                else
                {
                    getsymdo;
                    if(sym!=becomes) error(13);             //¸³ÖµÓï¾ä×󲿱êʶ·ûºóÓ¦ÊǸ³ÖµºÅ:=
                    else getsymdo;
                    memcpy(nxtlev,fsys,sizeof(bool)*symnum); 
                    nxtlev[tosym]=true;                     //ºó¸ú·ûtoºÍdownto
                    expressiondo(nxtlev,ptx,lev);           //´¦Àí¸³ÖµÓï¾äÓÒ²¿µÄ±í´ïʽE1
                    gendo(sto,lev-table[i].level,table[i].adr);     //±£´æ³õÖµ
                 	if(sym==tosym){
					 
                        getsymdo;
                        cx1=cx;       //±£´æÑ­»·¿ªÊ¼µã
                        //½«Ñ­»·ÅжϱäÁ¿È¡³ö·Åµ½Õ»¶¥
                        gendo(lod,lev-table[i].level,table[i].adr);                                        
                        memcpy(nxtlev,fsys,sizeof(bool)*symnum);    //´¦Àí±í´ïʽE2
                        nxtlev[dosym]=true;                         //ºó¸ú·ûdo
                        expressiondo(nxtlev,ptx,lev);
                        /*ÅжÏÑ­»·±äÁ¿Ìõ¼þ£¬±ÈÈçfor i:=E1 to E2 do SÖУ¬ÅжÏiÊÇ·ñСÓÚE2£¬ÈçСÓÚµÈÓÚ£¬¼ÌÐøÑ­»·£¬´óÓڵĻ°£¬Ìø³öÑ­»·*/     
                        gendo(opr,0,13);             //Éú³É±È½ÏÖ¸ÁiÊÇ·ñСÓÚµÈÓÚE2µÄÖµ
                        cx2=cx;                      //±£´æÑ­»·½áÊøµã
                        //Éú³ÉÌõ¼þÌøתָÁÌø³öÑ­»·£¬Ìø³öµÄµØַδ֪
                        gendo(jpc,0,0);                     
                        if(sym==dosym)               //´¦ÀíÑ­»·ÌåS
                        {
                            getsymdo;
                            statement(fsys,ptx,lev);  //Ñ­»·Ìå´¦Àí
                            //Ôö¼ÓÑ­»·±äÁ¿²½³¤Îª
                            //½«Ñ­»·±äÁ¿È¡³ö·ÅÔÚÕ»¶¥
                            gendo(lod,lev-table[i].level,table[i].adr);                                       
                            gendo(lit,0,1);                            //½«²½³¤È¡µ½Õ»¶¥
                            gendo(opr,0,2);                            //Ñ­»·±äÁ¿¼Ó²½³¤
                            //½«Õ»¶¥µÄÖµ´æÈëÑ­»·±äÁ¿
                            gendo(sto,lev-table[i].level,table[i].adr); 
                            gendo(jmp,0,cx1);                 //ÎÞÌõ¼þÌøתµ½Ñ­»·¿ªÊ¼µã
                            /*»ØÌîÑ­»·½áÊøµãµÄµØÖ·£¬cxΪelseºóÓï¾äÖ´ÐÐÍêµÄλÖã¬ËüÕýÊÇÇ°Ãæ䶨µÄÌøתµØÖ·*/
                            code[cx2].a=cx;                     
                         }
                         else
                         {
                            error(29);    //forÓï¾äÖÐÉÙÁËdo
                         }
                    }
                }
            }
        }
    }
	else
	{
		if (sym == readsym) /* ×¼±¸°´ÕÕreadÓï¾ä´¦Àí */
		{
			getsymdo;
			if (sym != lparen)
			{
				error(34);  /* ¸ñʽ´íÎó£¬Ó¦ÊÇ×óÀ¨ºÅ */
			}
			else
			{
				do {
					getsymdo;
					if (sym == ident)
					{
						i = position(id, *ptx); /* ²éÕÒÒª¶ÁµÄ±äÁ¿ */
					}
					else
					{
						i=0;
					}

					if (i == 0)
					{
						error(35);  /* read()ÖÐÓ¦ÊÇÉùÃ÷¹ýµÄ±äÁ¿Ãû */
					}
					else if (table[i].kind != variable)
					{
						error(32);	/* read()²ÎÊý±íµÄ±êʶ·û²»ÊDZäÁ¿, thanks to amd */
					}
					else
					{
						gendo(opr, 0, 16);  /* Éú³ÉÊäÈëÖ¸Á¶ÁÈ¡Öµµ½Õ»¶¥ */
						gendo(sto, lev-table[i].level, table[i].adr);   /* ´¢´æµ½±äÁ¿ */
					}
					getsymdo;

				} while (sym == comma); /* Ò»ÌõreadÓï¾ä¿É¶Á¶à¸ö±äÁ¿ */
			}
			if(sym != rparen)
			{
				error(33);  /* ¸ñʽ´íÎó£¬Ó¦ÊÇÓÒÀ¨ºÅ */
				while (!inset(sym, fsys))   /* ³ö´í²¹¾È£¬Ö±µ½ÊÕµ½Éϲ㺯ÊýµÄºó¸ú·ûºÅ */
				{
					getsymdo;
				}
			}
			else
			{
				getsymdo;
			}
		}
		else
		{
			if (sym == writesym)    /* ×¼±¸°´ÕÕwriteÓï¾ä´¦Àí£¬ÓëreadÀàËÆ */
			{
				getsymdo;
				if (sym == lparen)
				{
					do {
						getsymdo;
						memcpy(nxtlev, fsys, sizeof(bool)*symnum);
						nxtlev[rparen] = true;
						nxtlev[comma] = true;       /* writeµÄºó¸ú·ûºÅΪ) or , */
						expressiondo(nxtlev, ptx, lev); /* µ÷Óñí´ïʽ´¦Àí£¬´Ë´¦Óëread²»Í¬£¬readΪ¸ø±äÁ¿¸³Öµ */
						gendo(opr, 0, 14);  /* Éú³ÉÊä³öÖ¸ÁÊä³öÕ»¶¥µÄÖµ */
					} while (sym == comma);
					if (sym != rparen)
					{
						error(33);  /* write()ÖÐӦΪÍêÕû±í´ïʽ */
					}
					else
					{
						getsymdo;
					}
				}
				gendo(opr, 0, 15);  /* Êä³ö»»ÐÐ */
			}
			else
			{
				if (sym == callsym) /* ×¼±¸°´ÕÕcallÓï¾ä´¦Àí */
				{
					getsymdo;
					if (sym != ident)
					{
						error(14);  /* callºóӦΪ±êʶ·û */
					}
					else
					{
						i = position(id, *ptx);
						if (i == 0)
						{
							error(11);  /* ¹ý³ÌδÕÒµ½ */
						}
						else
						{
							if (table[i].kind == procedur)
							{
								gendo(cal, lev-table[i].level, table[i].adr);   /* Éú³ÉcallÖ¸Áî */
							}
							else
							{
								error(15);  /* callºó±êʶ·ûӦΪ¹ý³Ì */
							}
						}
						getsymdo;
					}
				}
				else
				{
					if (sym == ifsym)   /* ×¼±¸°´ÕÕifÓï¾ä´¦Àí */
					{
						getsymdo;
						memcpy(nxtlev, fsys, sizeof(bool)*symnum);
						nxtlev[thensym] = true;
						nxtlev[dosym] = true;   /* ºó¸ú·ûºÅΪthen»òdo */
						conditiondo(nxtlev, ptx, lev); /* µ÷ÓÃÌõ¼þ´¦Àí£¨Âß¼­ÔËË㣩º¯Êý */
						if (sym == thensym)
						{
							getsymdo;
						}
						else
						{
							error(16);  /* ȱÉÙthen */
						}
						cx1 = cx;   /* ±£´æµ±Ç°Ö¸ÁîµØÖ· */
						gendo(jpc, 0, 0);   /* Éú³ÉÌõ¼þÌøתָÁÌøתµØַδ֪£¬ÔÝʱд0 */
						statementdo(fsys, ptx, lev);    /* ´¦ÀíthenºóµÄÓï¾ä */
						if (sym == elsesym) {
							getsymdo;
							cx2 = cx;
							gendo(jmp, 0, 0);
							code[cx1].a = cx;
							statementdo(fsys, ptx, lev);
							code[cx2].a = cx;
						}
					else {
						//ÒÔÉÏÊÇ´¦ÀíelseÓï¾ä
						code[cx1].a = cx;      /*¾­statement´¦Àíºó£¬cxΪthenºóÓï¾äÖ´ÐÐÍêµÄλÖã¬ËüÕýÊÇÇ°Ãæ䶨µÄÌøתµØÖ·*/
					}
				}
					else
					{
						if (sym == beginsym)    /* ×¼±¸°´ÕÕ¸´ºÏÓï¾ä´¦Àí */
						{
							getsymdo;
							memcpy(nxtlev, fsys, sizeof(bool)*symnum);
							nxtlev[semicolon] = true;
							nxtlev[endsym] = true;  /* ºó¸ú·ûºÅΪ·ÖºÅ»òend */
							/* Ñ­»·µ÷ÓÃÓï¾ä´¦Àíº¯Êý£¬Ö±µ½ÏÂÒ»¸ö·ûºÅ²»ÊÇÓï¾ä¿ªÊ¼·ûºÅ»òÊÕµ½end */
							statementdo(nxtlev, ptx, lev);

							while (inset(sym, statbegsys) || sym==semicolon)
							{
								if (sym == semicolon)
								{
									getsymdo;
								}
								else
								{
									error(10);  /* ȱÉٷֺŠ*/
								}
								statementdo(nxtlev, ptx, lev);
							}
							if(sym == endsym)
							{
								getsymdo;
							}
							else
							{
								error(17);  /* ȱÉÙend»ò·ÖºÅ */
							}
						}
						else
						{
							if (sym == whilesym)    /* ×¼±¸°´ÕÕwhileÓï¾ä´¦Àí */
							{
								cx1 = cx;   /* ±£´æÅжÏÌõ¼þ²Ù×÷µÄλÖà */
								getsymdo;
								memcpy(nxtlev, fsys, sizeof(bool)*symnum);
								nxtlev[dosym] = true;   /* ºó¸ú·ûºÅΪdo */
								conditiondo(nxtlev, ptx, lev);  /* µ÷ÓÃÌõ¼þ´¦Àí */
								cx2 = cx;   /* ±£´æÑ­»·ÌåµÄ½áÊøµÄÏÂÒ»¸öλÖà */
								gendo(jpc, 0, 0);   /* Éú³ÉÌõ¼þÌøת£¬µ«Ìø³öÑ­»·µÄµØַδ֪ */
								if (sym == dosym)
								{
									getsymdo;
								}
								else
								{
									error(18);  /* ȱÉÙdo */
								}
								statementdo(fsys, ptx, lev);    /* Ñ­»·Ìå */
								gendo(jmp, 0, cx1); /* »ØÍ·ÖØÐÂÅжÏÌõ¼þ */
								code[cx2].a = cx;   /* ·´ÌîÌø³öÑ­»·µÄµØÖ·£¬ÓëifÀàËÆ */
							}
							else
							{
								memset(nxtlev, 0, sizeof(bool)*symnum); /* Óï¾ä½áÊøÎÞ²¹¾È¼¯ºÏ */
								testdo(fsys, nxtlev, 19);   /* ¼ì²âÓï¾ä½áÊøµÄÕýÈ·ÐÔ */
							}
						}
					}
				}
			}
		}
	}
	return 0;
}

/*
* ±í´ïʽ´¦Àí
*/
int expression(bool* fsys, int* ptx, int lev)
{
	enum symbol addop;  /* ÓÃÓÚ±£´æÕý¸ººÅ */
	bool nxtlev[symnum];

	if(sym==plus || sym==minus) /* ¿ªÍ·µÄÕý¸ººÅ£¬´Ëʱµ±Ç°±í´ïʽ±»¿´×÷Ò»¸öÕýµÄ»ò¸ºµÄÏî */
	{
		addop = sym;    /* ±£´æ¿ªÍ·µÄÕý¸ººÅ */
		getsymdo;
		memcpy(nxtlev, fsys, sizeof(bool)*symnum);
		nxtlev[plus] = true;
		nxtlev[minus] = true;
		termdo(nxtlev, ptx, lev);   /* ´¦ÀíÏî */
		if (addop == minus)
		{
			gendo(opr,0,1); /* Èç¹û¿ªÍ·Îª¸ººÅÉú³ÉÈ¡¸ºÖ¸Áî */
		}
	}
	else    /* ´Ëʱ±í´ïʽ±»¿´×÷ÏîµÄ¼Ó¼õ */
	{
		memcpy(nxtlev, fsys, sizeof(bool)*symnum);
		nxtlev[plus] = true;
		nxtlev[minus] = true;
		termdo(nxtlev, ptx, lev);   /* ´¦ÀíÏî */
	}
	while (sym==plus || sym==minus)
	{
		addop = sym;
		getsymdo;
		memcpy(nxtlev, fsys, sizeof(bool)*symnum);
		nxtlev[plus] = true;
		nxtlev[minus] = true;
		termdo(nxtlev, ptx, lev);   /* ´¦ÀíÏî */
		if (addop == plus)
		{
			gendo(opr, 0, 2);   /* Éú³É¼Ó·¨Ö¸Áî */
		}
		else
		{
			gendo(opr, 0, 3);   /* Éú³É¼õ·¨Ö¸Áî */
		}
	}
	return 0;
}

/*
* Ïî´¦Àí
*/
int term(bool* fsys, int* ptx, int lev)
{
	enum symbol mulop;  /* ÓÃÓÚ±£´æ³Ë³ý·¨·ûºÅ */
	bool nxtlev[symnum];

	memcpy(nxtlev, fsys, sizeof(bool)*symnum);
	nxtlev[times] = true;
	nxtlev[slash] = true;
	factordo(nxtlev, ptx, lev); /* ´¦ÀíÒò×Ó */
	while(sym==times || sym==slash)
	{
		mulop = sym;
		getsymdo;
		factordo(nxtlev, ptx, lev);
		if(mulop == times)
		{
			gendo(opr, 0, 4);   /* Éú³É³Ë·¨Ö¸Áî */
		}
		else
		{
			gendo(opr, 0, 5);   /* Éú³É³ý·¨Ö¸Áî */
		}
	}
	return 0;
}

/*
* Òò×Ó´¦Àí
*/
int factor(bool* fsys, int* ptx, int lev)
{
	int i;
	bool nxtlev[symnum];
	testdo(facbegsys, fsys, 24);    /* ¼ì²âÒò×ӵĿªÊ¼·ûºÅ */
	/* while(inset(sym, facbegsys)) */  /* Ñ­»·Ö±µ½²»ÊÇÒò×Ó¿ªÊ¼·ûºÅ */
	if(inset(sym,facbegsys))    /* BUG: Ô­À´µÄ·½·¨var1(var2+var3)»á±»´íÎóʶ±ðΪÒò×Ó */
	{
		if(sym == ident)    /* Òò×ÓΪ³£Á¿»ò±äÁ¿ */
		{
			i = position(id, *ptx); /* ²éÕÒÃû×Ö */
			if (i == 0)
			{
				error(11);  /* ±êʶ·ûδÉùÃ÷ */
			}
			else
			{
				switch (table[i].kind)
				{
				case constant:  /* Ãû×ÖΪ³£Á¿ */
					gendo(lit, 0, table[i].val);    /* Ö±½Ó°Ñ³£Á¿µÄÖµÈëÕ» */
					break;
				case variable:  /* Ãû×ÖΪ±äÁ¿ */
					gendo(lod, lev-table[i].level, table[i].adr);   /* ÕÒµ½±äÁ¿µØÖ·²¢½«ÆäÖµÈëÕ» */
					break;
				case procedur:  /* Ãû×ÖΪ¹ý³Ì */
					error(21);  /* ²»ÄÜΪ¹ý³Ì */
					break;
				}
			}
			getsymdo;
		}
		else
		{
			if(sym == number)   /* Òò×ÓΪÊý */
			{
				if (num > amax)
				{
					error(31);
					num = 0;
				}
				gendo(lit, 0, num);
				getsymdo;
			}
			else
			{
				if (sym == lparen)  /* Òò×ÓΪ±í´ïʽ */
				{
					getsymdo;
					memcpy(nxtlev, fsys, sizeof(bool)*symnum);
					nxtlev[rparen] = true;
					expressiondo(nxtlev, ptx, lev);
					if (sym == rparen)
					{
						getsymdo;
					}
					else
					{
						error(22);  /* ȱÉÙÓÒÀ¨ºÅ */
					}
				}
				testdo(fsys, facbegsys, 23);    /* Òò×ÓºóÓзǷ¨·ûºÅ */
			}
		}
	}
	return 0;
}

/*
* Ìõ¼þ´¦Àí
*/
int condition(bool* fsys, int* ptx, int lev)
{
	enum symbol relop;
	bool nxtlev[symnum];

	if(sym == oddsym)   /* ×¼±¸°´ÕÕoddÔËËã´¦Àí */
	{
		getsymdo;
		expressiondo(fsys, ptx, lev);
		gendo(opr, 0, 6);   /* Éú³ÉoddÖ¸Áî */
	}
	else
	{
		/* Âß¼­±í´ïʽ´¦Àí */
		memcpy(nxtlev, fsys, sizeof(bool)*symnum);
		nxtlev[eql] = true;
		nxtlev[neq] = true;
		nxtlev[lss] = true;
		nxtlev[leq] = true;
		nxtlev[gtr] = true;
		nxtlev[geq] = true;
		expressiondo(nxtlev, ptx, lev);
		if (sym!=eql && sym!=neq && sym!=lss && sym!=leq && sym!=gtr && sym!=geq)
		{
			error(20);
		}
		else
		{
			relop = sym;
			getsymdo;
			expressiondo(fsys, ptx, lev);
			switch (relop)
			{
			case eql:
				gendo(opr, 0, 8);
				break;
			case neq:
				gendo(opr, 0, 9);
				break;
			case lss:
				gendo(opr, 0, 10);
				break;
			case geq:
				gendo(opr, 0, 11);
				break;
			case gtr:
				gendo(opr, 0, 12);
				break;
			case leq:
				gendo(opr, 0, 13);
				break;
			}
		}
	}
	return 0;
}

/*
* ½âÊͳÌÐò
*/
void interpret()
{
	int p, b, t;    /* Ö¸ÁîÖ¸Õ룬ָÁî»ùÖ·£¬Õ»¶¥Ö¸Õë */
	struct instruction i;   /* ´æ·Åµ±Ç°Ö¸Áî */
	int s[stacksize];   /* Õ» */

	printf("start pl0\n");
	t = 0;
	b = 0;
	p = 0;
	s[0] = s[1] = s[2] = 0;
	do {
		i = code[p];    /* ¶Áµ±Ç°Ö¸Áî */
		p++;
		switch (i.f)
		{
		case lit:   /* ½«aµÄֵȡµ½Õ»¶¥ */
			s[t] = i.a;
			t++;
			break;
		case opr:   /* Êýѧ¡¢Âß¼­ÔËËã */
			switch (i.a)
			{
			case 0:
				t = b;
				p = s[t+2];
				b = s[t+1];
				break;
			case 1:
				s[t-1] = -s[t-1];
				break;
			case 2:
				t--;
				s[t-1] = s[t-1]+s[t];
				break;
			case 3:
				t--;
				s[t-1] = s[t-1]-s[t];
				break;
			case 4:
				t--;
				s[t-1] = s[t-1]*s[t];
				break;
			case 5:
				t--;
				s[t-1] = s[t-1]/s[t];
				break;
			case 6:
				s[t-1] = s[t-1]%2;
				break;
			case 8:
				t--;
				s[t-1] = (s[t-1] == s[t]);
				break;
			case 9:
				t--;
				s[t-1] = (s[t-1] != s[t]);
				break;
			case 10:
				t--;
				s[t-1] = (s[t-1] < s[t]);
				break;
			case 11:
				t--;
				s[t-1] = (s[t-1] >= s[t]);
				break;
			case 12:
				t--;
				s[t-1] = (s[t-1] > s[t]);
				break;
			case 13:
				t--;
				s[t-1] = (s[t-1] <= s[t]);
				break;
			case 14:
				printf("%d", s[t-1]);
				fprintf(fa2, "%d", s[t-1]);
				t--;
				break;
			case 15:
				printf("\n");
				fprintf(fa2,"\n");
				break;
			case 16:
				printf("?");
				fprintf(fa2, "?");
				scanf("%d", &(s[t]));
				fprintf(fa2, "%d\n", s[t]);
				t++;
				break;
			}
			break;
		case lod:   /* È¡Ïà¶Ôµ±Ç°¹ý³ÌµÄÊý¾Ý»ùµØַΪaµÄÄÚ´æµÄÖµµ½Õ»¶¥ */
			s[t] = s[base(i.l,s,b)+i.a];
			t++;
			break;
		case sto:   /* Õ»¶¥µÄÖµ´æµ½Ïà¶Ôµ±Ç°¹ý³ÌµÄÊý¾Ý»ùµØַΪaµÄÄÚ´æ */
			t--;
			s[base(i.l, s, b) + i.a] = s[t];
			break;
		case cal:   /* µ÷ÓÃ×Ó¹ý³Ì */
			s[t] = base(i.l, s, b); /* ½«¸¸¹ý³Ì»ùµØÖ·ÈëÕ» */
			s[t+1] = b; /* ½«±¾¹ý³Ì»ùµØÖ·ÈëÕ»£¬´ËÁ½ÏîÓÃÓÚbaseº¯Êý */
			s[t+2] = p; /* ½«µ±Ç°Ö¸ÁîÖ¸ÕëÈëÕ» */
			b = t;  /* ¸Ä±ä»ùµØÖ·Ö¸ÕëֵΪйý³ÌµÄ»ùµØÖ· */
			p = i.a;    /* Ìøת */
			break;
		case inte:  /* ·ÖÅäÄÚ´æ */
			t += i.a;
			break;
		case jmp:   /* Ö±½ÓÌøת */
			p = i.a;
			break;
		case jpc:   /* Ìõ¼þÌøת */
			t--;
			if (s[t] == 0)
			{
				p = i.a;
			}
			break;
		}
	} while (p != 0);
}

/* ͨ¹ý¹ý³Ì»ùÖ·ÇóÉÏl²ã¹ý³ÌµÄ»ùÖ· */
int base(int l, int* s, int b)
{
	int b1;
	b1 = b;
	while (l > 0)
	{
		b1 = s[b1];
		l--;
	}
	return b1;
}

 

  • 8
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值