/ * ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------- * /
/ * Recursive drop analysis algorithm: Little C interpreter is a recursive drop in expression analysis * /
/ * ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------- * /
EXP_X recursive description
--------------------
Because of the problem involving priority, the recursive subroutine starting from EXP_1 is the higher the priority of the task to be completed.
After the exp_1 starts execution, does not complete its own task, but recursively, only one subroutine below, then return, returned
In the process, the current task is completed according to the priority.
First start from EXP_0, it checks if it is empty expression, and processing variables. Regeneration in the process of processing variables, making the variable assignment.
The main task of EXP_1 is to calculate the Boolean expression, and the second value is required to obtain the second value during the calculation process.
Calculate.
The main completed task of EXP_2 is to calculate the process of processing the additive and subtraction. It is a multiplication or division of operations during its operation.
If you need to calculate first, you need to call exp_3 inside the While, if it is 4 28 * 2, then it will return when Exp_3 returns.
56, then the addition operation is carried out. This procedure also needs to handle 7 1 2 1 such addition or decrease.
The main task of EXP_3 is to calculate division and touch. Its function is similar to the decrease.
EXP_4 processing a dollar or minus.
EXP_5 maximum priority, is () operation,
ATOM is responsible for internal functions and user-defined function calls, and returns the value to the global variable value, and returns a constant value and the numeric value.
----------------------
/ * Entry point INTO PARSER. * /
/ * Analytical partial program begins to execute * /
/ * The entry of the program is an eval_exp () function * /
Void eval_exp (int * value)
{
/ * First get a symbol * /
GET_TOKEN ();
/ * Judgment is a symbol, if there is no return, no expression * /
IF (! * token) {
SNTX_ERR (no_exp);
Return;
}
/ * If "word" is ";", then it is an empty expression, the value of the empty expression is 0, indicating the fake * /
IF (* token == ';') {
* Value = 0; / * EMPTY Expression * /
Return;
}
/ * If it is not 2 cases, then the expression recursive analysis begins to execute * /
Eval_EXP0 (Value);
Putback (); / * RETURN LAST token Read to Input Stream * /
}
/ * Process An Assignment Expression * /
Void Eval_EXP0 (INT * VALUE)
{
CHAR TEMP [ID_LEN]; / * Holds Name of Var Receiving
The assocignment * /
Register int Temp_tok;
IF (Token_Type == Identifier) {
/ * View this "marker" via variable is_var is already in a global or local variable table * /
IF (is_var (token)) {/ * if a var, see if assignment * // * If you are, copy token to the TEMP variable * /
STRCPY (TEMP, TOKEN);
// If you don't talk, you will first put the value Copy to Temp in the Token, as it is determined to be assigned statement, then it may be an expression, because Token is a global variable, it is necessary to protect it here.
Save.
Temp_tok = token_type; // Buffer tag type Set to token_Type
GET_TOKEN (); // Get the next symbol, according to this variable name, it is not defined, then it means that he should have a assignment statement.
If (* token == '=') {/ * is an association If it is a = symbol, then explain him to assign a statement.
GET_TOKEN (); // get symbol
Eval_exp0 (value); // Recursively calculated expression
Assign_var (TEMP, * VALUE); / / assigning variables
Return;
}
Else {//////
Putback (); / / Otherwise restore the location of Token's previous pointer
STRCPY (TOKEN, TEMP); // Put the value of TEMP to Token
Token_Type = Temp_tok; // Type Temp_tok Type
}
}
}
Eval_exp1 (value); // Recursive into the next layer
}
/ * Process RELATIONAL OPERATORS. * /
Void Eval_exp1 (INT * VALUE)
{
INT Partial_Value; // Another value in the expression that needs to be calculated
Register char OP; // This variable is an operator variable
Char relops [7] = {// Operator Table
LT, Le, GT, GE, EQ, NE, 0
}
Eval_exp2 (value); // Enter the next layer
Op = * token; // operator
IF (StrChr (Relops, OP)) {// If it belongs to the operator
GET_TOKEN (); // get the next symbol
Eval_exp2 (& Partial_Value); // Get the value of Partial_Value
Switch (OP) {/ * Perform The Relational Operation * /
Case LT: // Handling the LT situation is less than the number
* Value = * value Break; // Launches Switch statement Case Le: // Handling Le's situation is less than or equal * Value = * value <= partial_value; Break; Case GT: // Handling the case of GT is greater than the number * value = * value> Partial_Value; Break; Case ge: // Handling GE is greater than or equal to * value = * value> = Partial_Value; Break; Case EQ: // Processing EQ Symbol Test Is Equivalent Symbol * Value = * value == partial_value; Break; Case ne: // Handle NE symbol test does not wait * value = * value! = Partial_Value; Break; } } } / * Add or subtract two terms. * / Void Eval_exp2 (INT * VALUE) { Register char OP; INT Partial_Value; Eval_exp3 (value); // Enter recursive while ((OP = * token) == ' ' || op == '-') {// Handling multiple plus sign or minus GET_TOKEN (); // get a symbol Eval_exp3 (& Partial_Value); // Get a number. This value may be a value from multiplication or division or expression. Switch (OP) {// Select a symbol Case '-': // Processing * value = * value - Partial_Value; Break; Case ' ': // Processing plus sign * Value = * Value Partial_Value; Break; } } } / * Multiply or Divide Two factors. * / Void evAl_exp3 (INT * VALUE) { Register char OP; INT Partial_Value, T; Eval_exp4 (value); // Enter the next layer recursive While ((OP = * token) == '*' || op == '/' || op == '%') {// Processing Multi-multiplay or Connection GET_TOKEN (); // get the next symbol Eval_exp4 (& Partial_Value); // Get a number Switch (OP) {/ * MUL, DIV, or MODULULUS * / CASE '*': // Handling Multiplication * Value = * Value * partial_Value; Break; Case '/': // Treatment of division IF (Partial_Value == 0) SNTX_ERR (Div_By_zero); * Value = (* value) / partial_value; Break; Case '%': // Handling a touch operation. The remainder is placed in Value T = (* value) / Partial_Value; * Value = * Value- (t * partial_value); Break; } } } // EVAL_EXP4 processing one yuan plus or decrease / * Is a unary or -. * / Void Eval_EXP4 (INT * VALUE) { Register char OP; Op = '/ 0'; IF (* token == ' ' || * token == '-') { Op = * token; GET_TOKEN (); } evAl_exp5 (value); IF (op) IF (OP == '-') * value = - (* Value); } / * Process parenthesized expression. * / Void Eval_exp5 (INT * VALUE) { IF (* token == '(')) {// processing (, () has the highest priority GET_TOKEN (); Eval_EXP0 (Value); / * get subspression * / if (* token! = ')') SNTX_ERR (PAREN_EXPECTED); // If not) Description Syntax Error GET_TOKEN (); } Else Atom (value); // get a value } Void Atom (INT * VALUE) { INT I; Switch (token_type) {/ * Select token Type * / Case Identifier: / * If it is a variable or function * / I = INTERNAL_FUNC (TOKEN); / * Find the function name from the internal structure * / IF (i! = -1) {/ * call "standard library" function * / / * If not -1, then it is an internal function * / * Value = (* Intern_FUNC .p) (); / * Call internal functions through the function pointer in the structure, returned to the value pointing address * /} else if (Find_Func (token)) {/ * call user-defined function * / / * Otherwise, if you find a user-defined function, if yes * / call (); / * Call the user-defined function * / * value = RET_VALUE; / * Function, the return value of the value is placed on the address pointing to the value pointing to the address.里 * /} else * value = find_var (token); / * get var's value * / / * Otherwise, he thinks he is the name of a variable, find the token in the TOKEN, then put it in the value of Value * / GET_TOKEN (); / * Returns * / Return; Case Number: / * Is Numeric Constant * / / * If it is a number, then transform the character through the ATOI in the standard library function (this function is defined in stdio.h) For the digital type, the convenient expression calculation * / * value = atoi (token); get_token (); / * Return * / return; case delimiter: / * see if character constant * / / * If it is a character constant * / If (* token == '/' ') {/ * If it is' character, let the current value * / * value = * prog; prog ; if (* prog! = '/') SNTX_ERR (quote_expected); / * If not ending with 'symbol, throw syntax error * / prog ; get_token (); return;} if (* token ==') ') Return; / * process EMPTY Expression * / Else SNTX_ERR (SYNTAX); / * syntax error * / default: SNTX_ERR (Syntax); / * Syntax Error * /}}