Recursive subscripts are used for syntax analysis.Program, Basically the previous rule corresponds to an analysis function.
Statement ProcessingCode
/* Constant declaration handling process constdeclaration */void constdeclaration (const Int & lev, Int & Tx, Int & dx) {If (sym = ident) /* The first symbol encountered during the constant declaration process must be the identifier */{getsym ();/* Get the next token */If (in (sym, symset {eql, becomes})/* if it is an equal sign or a value */{If (sym = becomes)/* if it is a value (the constant should be an equal sign in the description) */error (1);/* Throw Error 1 * // * errors are automatically corrected so that compilation continues, process the value assignment number as an equal sign */getsym ();/* obtain the next token, and connect the equal sign or value assignment number */If (sym = number) /* if it is indeed a number */{enter (constant, lev, Tx, dx);/* log on to the symbol table */getsym (); /* Get the next token and prepare for the following. */} elseerror (2);/* If the equal sign is not followed by a number, a 2 error is thrown */} elseerror (3 ); /* If the constant identifier is not followed by an equal sign or a value, a 3 error is thrown */} elseerror (4 ); /* If the first symbol encountered in the constant declaration process is not an identifier, a 4-digit error is thrown */}/* constdeclaration */; /* variable declaration process vardeclaration */void vardeclaration (const Int & lev, Int & Tx, Int & dx) {If (sym = ident) /* The first symbol at the beginning of the variable declaration process must be the identifier */{enter (variable, lev, Tx, dx ); /* log on to the symbol table */getsym ();/* Get the next token and prepare for the next token */} elseerror (4 ); /* If the first symbol encountered in the variable declaration process is not an identifier, the 4th error is thrown */}/* vardeclaration */;
Processing of expressions
Void expression (const symset & fsys, const Int & lev, Int & Tx);/* factor during factor Processing * // * parameter description: fsys: if an error occurs, you can use it to restore the collection of symbols for syntax analysis */void factor (const symset & fsys, const Int & lev, Int & Tx) {int I; test (facbegsys, fsys, 24);/* Before starting factor processing, check whether the current token is in the facbegsys set. * // * If it is not a valid token, throw the 24 th error and resume the syntax processing through fsys set restoration */while (in (sym, facbegsys )) /* cyclic processing factor */{If (sym = ident)/* If the identifier */{I = position (ID, TX) is encountered;/* query the symbol table, locate the position of the current identifier in the symbol table */if (I = 0)/* If the query symbol table returns 0, the identifier */error (11) is not found ); /* Throw error 11 */elseswitch (Table [I]. kind) {Case constant: Gen (values, 0, table [I]. val);/* If the identifier corresponds to a constant and the value is Val, generate the marker command and place Val to the top of the stack */break; Case variable: Gen, lev-table [I]. level, table [I]. (ADR);/* If the identifier is a variable name, generate the level-of-failure (dump) command, * // * place the variable whose offset address is ADR from the current layer to the top of the stack */break; case procedure: Error (21 ); /* If the identifier encountered in factor processing is a process name and an error occurs, the 21st error is thrown */break;} getsym ();/* Get the next token, continue loop Processing */} else if (sym = Number)/* If the factor processing encounters a number */{If (Num> amax) /* If the number size exceeds the allowed maximum value amax */{error (31);/* Throw error No. 31 */num = 0; /* process the number by 0 */} gen (numeric, 0, num);/* generate the numeric command and place the literal constant of this value to the top of the stack */getsym (); /* Get the next token */} else if (sym = lpar En)/* If the left parenthesis */{getsym ();/* Get a token */expression (symset {rparen} + fsys, lev, Tx ); /* recursively call the expression subroutine to analyze a subexpression */If (sym = rparen)/* after the subexpression is analyzed, the right parenthesis */getsym () should be encountered (); /* if you encounter a right parenthesis, read the next token */elseerror (22);/* otherwise, the 22nd error is thrown */} test (fsys, facbegsys, 23 ); /* after processing a factor, the token encountered should be in the fsys Set * // * If not, throw error 23 and find the start of the next factor, enable syntax analysis to continue running */}/* factor */;/* Term */* parameter description: fsys: if an error occurs, it can be used to restore the collection of symbols for syntax analysis */void te Rm (const symset & fsys, const Int & lev, Int & Tx) {/* Term */Symbol mulop; factor (symset {times, slash} + fsys, lev, TX);/* each item should start with a factor. Therefore, call the factor subroutine to analyze the factor */while (in (sym, symset {times, slash })) /* after a factor, the multiplication or division */{mulop = sym;/* Save the current operator */getsym (); /* obtain the next token */factor (fsys + symset {times, slash}, lev, Tx);/* The operator must be a factor, therefore, adjust the factor subroutine to analyze the factor */If (mulop = times)/* if you encounter a multiplication Number */Gen (OPR, 0, 4) just now;/* raw Multiplication command */elsegen (OPR, 0, 5);/* The division command */}/* Term */is generated instead of a multiplication number */; void expression (const symset & fsys, const Int & lev, Int & Tx) {symbol addop;/* expression */If (in (sym, symset {plus, minus })) /* an expression may start with a plus or minus sign, indicating the plus or minus sign */{addop = sym;/* stores the current positive or minus sign, so that the following code is generated */getsym ();/* Get a token */term (fsys + symset {plus, minus}, lev, Tx ); /* The plus or minus sign should be followed by an item. Call the term subroutine for analysis */If (addop = minus)/* If the saved symbol is a minus sign */Ge N (OPR, 0, 1);/* generate an Operation Command No. 1: Calculate the inverse operation * // * if it is not a negative number, it is a positive number, you do not need to generate the corresponding command */} else/*. If it does not start with a positive or negative number, it should start with an item */term (fsys + symset {plus, minus}, lev, TX);/* call the term subroutine analysis item */while (in (sym, symset {plus, minus })) /* add or subtract operations */{addop = sym;/* Save the operator */getsym ();/* Get the next token, after the addition and subtraction operators, it should be followed by an item */term (fsys + symset {plus, minus}, lev, Tx ); /* tune the term subroutine analysis item */If (addop = plus)/* If the operator between the item and the item is the plus sign */Gen (OPR, 0, 2 ); /* generate operation no. 2 Order: Add */else/*; otherwise, subtract */Gen (OPR, 0, 3);/* to generate operation command no. 3: subtraction */}/* expression */;/* condition processing process * // * parameter description: fsys: if an error occurs, you can restore the collection of symbols for syntax analysis */void condition (const symset & fsys, const Int & lev, Int & Tx) {symbol relop; /* used to temporarily record the content of the token (Here it must be a binary logical operator) */If (sym = oddsym)/* if it is an odd operator (one dollar) */{getsym ();/* Get the next token */expression (fsys, lev, Tx);/* process and compute the odd expression */Gen (OPR, 0, 6);/* generate operation command no. 6: parity judgment operation */} else /* If it is not an odd operator (it must be a binary logical operator) */{expression (symset {eql, NEQ, LSS, Leq, gtr, geq} + fsys, Leq, TX ); /* process and compute the left part of the expression */If (! (IN (sym, symset {eql, NEQ, LSS, Leq, gtr, geq})/* If token is not one of the logical operators */error (20 ); /* Throw error No. 20 */else {relop = sym;/* record the current logical operator */getsym ();/* Get the next token */expression (fsys, *, TX);/* process and compute the right part of the expression */switch (relop)/* If the operator is the following */{Case eql: Gen (OPR, 0, 8);/* equal sign: Generate command */break; Case NEQ: Gen (OPR, 0, 9);/* equal sign: command */break; Case LSS: Gen (OPR, 0, 10);/* minor: Generate command */break; Case geq: gen (OPR, 0, 11);/* greater than equal sign: generate the no. 11 command not less than */break; Case gtr: Gen (OPR, 0, 12 ); /* greater than ID: Generate command no. 12 greater than command */break; Case Leq: Gen (OPR, 0, 13);/* less than or equal to number: generate command no greater than command */break; default: break; }}}/* condition */