📄 sxb2.c
字号:
{ // if statement getsym(); set1 = createset(SYM_THEN, SYM_DO, SYM_NULL); set = uniteset(set1, fsys); condition(set); destroyset(set1); destroyset(set); if (sym == SYM_THEN) { getsym(); } else { error(16); // 'then' expected. } cx1 = cx; gen(JPC, 0, 0); statement(fsys); code[cx1].a = cx; } else if (sym == SYM_BEGIN) { // block getsym(); set1 = createset(SYM_SEMICOLON, SYM_END, SYM_NULL); set = uniteset(set1, fsys); statement(set); while (sym == SYM_SEMICOLON || inset(sym, statbegsys)) { if (sym == SYM_SEMICOLON) { getsym(); } else { error(10); } statement(set); } // while destroyset(set1); destroyset(set); if (sym == SYM_END) { getsym(); } else { error(17); // ';' or 'end' expected. } } else if (sym == SYM_WHILE) { // while statement cx1 = cx; getsym(); set1 = createset(SYM_DO, SYM_NULL); set = uniteset(set1, fsys); condition(set); destroyset(set1); destroyset(set); cx2 = cx; gen(JPC, 0, 0); if (sym == SYM_DO) { getsym(); } else { error(18); // 'do' expected. } statement(fsys); gen(JMP, 0, cx1); code[cx2].a = cx; } else //added by yzhang 02-02-28 test(fsys, phi, 19);} // statement //////////////////////////////////////////////////////////////////////void block(symset fsys){ int cx0; // initial code index mask* mk; int block_dx; int savedTx; symset set1, set; dx = 3; block_dx = dx; mk = (mask*) &table[tx]; mk->address = cx; gen(JMP, 0, 0); if (level > MAXLEVEL) { error(32); // There are too many levels. } do { if (sym == SYM_CONST) { // constant declarations getsym(); do { constdeclaration(); while (sym == SYM_COMMA) { getsym(); constdeclaration(); } if (sym == SYM_SEMICOLON) { getsym(); } else { error(5); // Missing ',' or ';'. } } while (sym == SYM_IDENTIFIER); } // if if (sym == SYM_VAR) { // variable declarations getsym(); do { vardeclaration(); while (sym == SYM_COMMA) { getsym(); vardeclaration(); } if (sym == SYM_SEMICOLON) { getsym(); } else { error(5); // Missing ',' or ';'. } } while (sym == SYM_IDENTIFIER); block_dx = dx; // modified by yzhang 02-03-15 } // if while (sym == SYM_PROCEDURE) { // procedure declarations getsym(); if (sym == SYM_IDENTIFIER) { enter(ID_PROCEDURE); getsym(); } else { error(4); // There must be an identifier to follow 'const', 'var', or 'procedure'. } if (sym == SYM_SEMICOLON) { getsym(); } else { error(5); // Missing ',' or ';'. } level++; savedTx = tx; set1 = createset(SYM_SEMICOLON, SYM_NULL); set = uniteset(set1, fsys); block(set); destroyset(set1); destroyset(set); tx = savedTx; level--; if (sym == SYM_SEMICOLON) { getsym(); set1 = createset(SYM_IDENTIFIER, SYM_PROCEDURE, SYM_NULL); set = uniteset(statbegsys, set1); test(set, fsys, 6); destroyset(set1); destroyset(set); } else { error(5); // Missing ',' or ';'. } } // while set1 = createset(SYM_IDENTIFIER, SYM_NULL); set = uniteset(statbegsys, set1); test(set, declbegsys, 7); destroyset(set1); destroyset(set); } while (inset(sym, declbegsys)); code[mk->address].a = cx; mk->address = cx; cx0 = cx; gen(INT, 0, block_dx); set1 = createset(SYM_SEMICOLON, SYM_END, SYM_NULL); set = uniteset(set1, fsys); statement(set); destroyset(set1); destroyset(set); gen(OPR, 0, OPR_RET); // return test(fsys, phi, 8); // test for error: Follow the statement is an incorrect symbol. listcode(cx0, cx);} // block//////////////////////////////////////////////////////////////////////int base(int stack[], int currentLevel, int levelDiff){ int b = currentLevel; while (levelDiff--) b = stack[b]; return b;} // base//////////////////////////////////////////////////////////////////////// interprets and executes codes.void interpret(){ int pc; // program counter int stack[STACKSIZE]; int top; // top of stack int b; // program, base, and top-stack register instruction i; // instruction register printf("Begin executing PL/0 program.\n"); fprintf(outfile, "Begin executing PL/0 program.\n"); pc = 0; b = 1; top = 3; stack[1] = stack[2] = stack[3] = 0; do { i = code[pc++]; switch (i.f) { case LIT: stack[++top] = i.a; break; case OPR: switch (i.a) // operator { case OPR_RET: top = b - 1; pc = stack[top + 3]; b = stack[top + 2]; break; case OPR_NEG: stack[top] = -stack[top]; break; case OPR_ADD: top--; stack[top] += stack[top + 1]; break; case OPR_MIN: top--; stack[top] -= stack[top + 1]; break; case OPR_MUL: top--; stack[top] *= stack[top + 1]; break; case OPR_DIV: top--; if (stack[top + 1] == 0) { fprintf(stderr, "Runtime Error: Divided by zero.\n"); fprintf(stderr, "Program terminated.\n"); continue; } stack[top] /= stack[top + 1]; break; case OPR_ODD: stack[top] %= 2; break; case OPR_EQU: top--; stack[top] = stack[top] == stack[top + 1]; break; case OPR_NEQ: top--; stack[top] = stack[top] != stack[top + 1]; case OPR_LES: top--; stack[top] = stack[top] < stack[top + 1]; break; case OPR_GEQ: top--; stack[top] = stack[top] >= stack[top + 1]; case OPR_GTR: top--; stack[top] = stack[top] > stack[top + 1]; break; case OPR_LEQ: top--; stack[top] = stack[top] <= stack[top + 1]; } // switch break; case LOD: stack[++top] = stack[base(stack, b, i.l) + i.a]; break; case STO: stack[base(stack, b, i.l) + i.a] = stack[top]; //printf("%d\n", stack[top]); fprintf(outfile, "%d\n", stack[top]); top--; break; case CAL: stack[top + 1] = base(stack, b, i.l); // generate new block mark stack[top + 2] = b; stack[top + 3] = pc; b = top + 1; pc = i.a; break; case INT: top += i.a; break; case JMP: pc = i.a; break; case JPC: if (stack[top] == 0) pc = i.a; top--; break; } // switch } while (pc); //printf("End executing PL/0 program.\n"); fprintf(outfile, "End executing PL/0 program.\n");} // interpret
symset uniteset(symset s1, symset s2)
{
symset s;
snode* p;
s = p = (snode*) malloc(sizeof(snode));
// added by yzhang 02-02-28
s1 = s1->next; s2 = s2->next;
// end add
while (s1 && s2)
{
p->next = (snode*) malloc(sizeof(snode));
p = p->next;
if (s1->elem < s2->elem)
{
p->elem = s1->elem;
s1 = s1->next;
}
else
{
p->elem = s2->elem;
s2 = s2->next;
}
}
if ( s2 ) s1 = s2; //added by yzhang 02-02-28
while (s1)
{
p->next = (snode*) malloc(sizeof(snode));
p = p->next;
p->elem = s1->elem;
s1 = s1->next;
}
/* deleted by yzhang 02-02-28
while (s2)
{
p->next = (snode*) malloc(sizeof(snode));
p = p->next;
p->elem = s2->elem;
s2 = s2->next;
}
*/
p->next = NULL;
return s;
} // uniteset
void setinsert(symset s, int elem)
{
snode* p = s;
snode* q;
while (p->next && p->next->elem < elem)
{
p = p->next;
}
q = (snode*) malloc(sizeof(snode));
q->elem = elem;
q->next = p->next;
p->next = q;
} // setinsert
symset createset(int elem, .../* SYM_NULL */)
{
// va_list list;
symset s;
s = (snode*) malloc(sizeof(snode));
s->next = NULL;
// va_start(list, elem);
// while (elem)
// {
// setinsert(s, elem);
// elem = va_arg(list, int);
// }
// va_end(list);
return s;
} // createset
void destroyset(symset s)
{
snode* p;
while (s)
{
p = s;
s = s->next;
free(p);
}
} // destroyset
int inset(int elem, symset s)
{
s ->next;
while (s && s->elem < elem)
s = s->next;
if (s && s->elem == elem)
return 1;
else
return 0;
} // inset
//added by yzhang 02-02-28
void showset(symset s)
{
s = s->next;
while (s ){
printf("%d,", s->elem);
s = s->next;
}
printf("\n");
} // showset//////////////////////////////////////////////////////////////////////void main (){ FILE* hbin; char s[80],*finddot; int i; symset set, set1, set2; printf("Please input source file name: "); // get file name to be compiled scanf("%s", s); if ((infile = fopen(s, "r")) == NULL) { printf("File %s can't be opened.\n", s); exit(1); }#if 1 // added by yzhang 02-02-28 // open the output file finddot = strchr(s,'.'); if (finddot!=NULL){ strcpy(finddot, ".out"); }else{ strcat(s, ".out"); printf("%s\n", s); } printf("Output File is %s\n", s); if ((outfile = fopen(s, "w")) == NULL) { printf("File %s can't be opened.\n", s); exit(1); }#endif phi = createset(SYM_NULL); relset = createset(SYM_EQU, SYM_NEQ, SYM_LES, SYM_LEQ, SYM_GTR, SYM_GEQ, SYM_NULL); // create begin symbol sets declbegsys = createset(SYM_CONST, SYM_VAR, SYM_PROCEDURE, SYM_NULL); statbegsys = createset(SYM_BEGIN, SYM_CALL, SYM_IF, SYM_WHILE, SYM_NULL); facbegsys = createset(SYM_IDENTIFIER, SYM_NUMBER, SYM_LPAREN, SYM_NULL); err = cc = cx = ll = 0; // initialize global variables ch = ' '; kk = MAXIDLEN; getsym();
set1 = createset(SYM_PERIOD, SYM_NULL); set2 = uniteset(declbegsys, statbegsys); set = uniteset(set1, set2); block(set); destroyset(set1); destroyset(set2); destroyset(set); destroyset(phi); destroyset(relset); destroyset(declbegsys); destroyset(statbegsys); destroyset(facbegsys); if (sym != SYM_PERIOD) error(9); // '.' expected. if (err == 0) { hbin = fopen("hbin.txt", "w"); for (i = 0; i < cx; i++) fwrite(&code[i], sizeof(instruction), 1, hbin); fclose(hbin); } if (err == 0) interpret(); else printf("There are %d error(s) in PL/0 program.\n", err); listcode(0, cx); // close all files, added by yzhang, 02-02-28 fclose(infile); fclose(outfile);} // main//////////////////////////////////////////////////////////////////////// eof pl0.c
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -