getsym(); } else {
error(4); // There must be an identifier to follow 'const', 'var', or 'procedure'. }
} // vardeclaration
////////////////////////////////////////////////////////////////////// void listcode(int from, int to) {
int i;
printf(\
for (i = from; i < to; i++) {
printf(\%s\\t%d\\t%d\\n\i, mnemonic[code[i].f], code[i].l, code[i].a); }
printf(\} // listcode
////////////////////////////////////////////////////////////////////// void factor(symset fsys) {
void expression(); int i;
symset set;
test(facbegsys, fsys, 24); // The symbol can not be as the beginning of an expression.
while (inset(sym, facbegsys)) {
if (sym == SYM_IDENTIFIER) {
if ((i = position(id)) == 0) {
error(11); // Undeclared identifier. } else {
switch (table[i].kind) {
35
mask* mk; case ID_CONSTANT:
gen(LIT, 0, table[i].value); break;
case ID_VARIABLE:
mk = (mask*) &table[i];
gen(LOD, level - mk->level, mk->address); break;
case ID_PROCEDURE: error(21); // Procedure identifier can not be in an expression. break; } // switch }
getsym(); }
else if (sym == SYM_NUMBER) {
if (num > MAXADDRESS) {
error(25); // The number is too great. num = 0; }
gen(LIT, 0, num); getsym(); }
else if (sym == SYM_LPAREN) {
getsym();
set = uniteset(createset(SYM_RPAREN, SYM_NULL), fsys); expression(set); destroyset(set);
if (sym == SYM_RPAREN) {
getsym(); } else {
error(22); // Missing ')'. } }
test(fsys, createset(SYM_LPAREN, SYM_NULL), 23); } // while } // factor
36
////////////////////////////////////////////////////////////////////// void term(symset fsys) {
int mulop; symset set;
set = uniteset(fsys, createset(SYM_TIMES, SYM_SLASH, SYM_NULL)); factor(set);
while (sym == SYM_TIMES || sym == SYM_SLASH) {
mulop = sym; getsym(); factor(set);
if (mulop == SYM_TIMES) {
gen(OPR, 0, OPR_MUL); } else {
gen(OPR, 0, OPR_DIV); }
} // while
destroyset(set); } // term
////////////////////////////////////////////////////////////////////// void expression(symset fsys) {
int addop; symset set;
set = uniteset(fsys, createset(SYM_PLUS, SYM_MINUS, SYM_NULL)); if (sym == SYM_PLUS || sym == SYM_MINUS) {
addop = sym; getsym(); term(set);
if (addop == SYM_MINUS) {
gen(OPR, 0, OPR_NEG); } } else {
37
term(set); }
while (sym == SYM_PLUS || sym == SYM_MINUS) {
addop = sym; getsym(); term(set);
if (addop == SYM_PLUS) {
gen(OPR, 0, OPR_ADD); } else {
gen(OPR, 0, OPR_MIN); }
} // while
destroyset(set); } // expression
////////////////////////////////////////////////////////////////////// void condition(symset fsys) {
int relop; symset set;
if (sym == SYM_ODD) {
getsym();
expression(fsys); gen(OPR, 0, 6); } else {
set = uniteset(relset, fsys); expression(set); destroyset(set);
if (! inset(sym, relset)) {
error(20); } else {
38
relop = sym; getsym();
expression(fsys); switch (relop) {
case SYM_EQU:
gen(OPR, 0, OPR_EQU); break; case SYM_NEQ:
gen(OPR, 0, OPR_NEQ); break; case SYM_LES:
gen(OPR, 0, OPR_LES); break; case SYM_GEQ:
gen(OPR, 0, OPR_GEQ); break; case SYM_GTR:
gen(OPR, 0, OPR_GTR); break; case SYM_LEQ:
gen(OPR, 0, OPR_LEQ); break; } // switch } // else } // else } // condition
////////////////////////////////////////////////////////////////////// void statement(symset fsys) {
int i, cx1, cx2; symset set1, set;
if (sym == SYM_IDENTIFIER) { // variable assignment mask* mk;
if (! (i = position(id))) {
error(11); // Undeclared identifier. }
else if (table[i].kind != ID_VARIABLE) {
error(12); // Illegal assignment.
39