Simplified About Basic Program Interpretation and Compilation Principle (1) - Classical Analysis and Algebra Value

zhaozj2021-02-08  246

On the Internet, see still some program enthusiasts hope to make your own compiler. Of course, this is really a difficult thing, many people say what compilation principle and proficient language, the result, let these lovers are looking forward to However, when we will do it personally, we have found a simple program interpreter (just like Java and Basic), it is very easy. You don't have to look at those things, as long as you understand C language, watch After this article, you can do that interpreter.

Online, there are many large C language, the compiler of Perl language. But when you download, you have found that you don't understand. In fact, those things still don't look good. After reading this article, I believe in you. I would rather I don't want to have a huge source code.

I have leaving the time, we start explaining.

This Basic interpreter code. Very classic. And it is very simple.

GET_TOKEN () is a vocabulary extraction, such as Print A B, by calling GET_TOKEN (), in the string token, put it on the string to TOKEN (), to pick up with GET_TOKEN (), token, install A and then call GET_TOKEN (), token Install and then call GET_TOKEN (), to install B is very simple in Token! Putback () is moving the PROG pointer back.

It contains the word analysis and the very critical algebraic value get_exp (int * result) about its algebraic evaluation GET_EXP (INT * Result), uses the recursive function void get_exp (), level2 (), level3 (), Level4 (), Level5 (); Void Level6 (), Primitive (), Arith (), unary (); indeed ugly understand, but you will use it although it is used.

Not much to say, you see the source code. Finally, I will give you a complete source code in C .

/ * Recursive Descent Parser for Integer Expression Which May Include Variables * /

#include #include #include #include #include

#define delimiter 1 # Define Variable 2 # Define Number 3 # Define Command 4 # Define String 5 # Define Quote 6

#define eol 9 # Define finished 10

Extern char * prog; / * Holds Expression to be analyzed * /

EXTERN JMP_BUF E_BUF; / * Hold Enviroment * / Extern Int Variables [26]; / * variables * / exten struct commands {char command [20]; char tok;} table [];

Extern char token [80]; / * Holds string representation of token * / exten char token_type; / * contains type of token * / extern char tok; / * Holds the inloadation of token * /

Void get_exp (), Level2 (), Level3 (), Level4 (), Level5 (); Void Level6 (), Primitive (), Arith (), unary (); void serror (), Putback ();

/ * Entry point @ g {get_token () {get_token (); if (! * token) {serror (2); return;};}; putback (); / * Return Last Token Read To input stream * /} / * add or subtract two terms * / void level2 (int * result) {register char op; int hold; level3 (result); while ((OP = * token) == ' ' || OP == '-') {get_token (); level3 (& Hold); Arith (OP, Result, & Hold);}}

/ * MULTIPLY or Divide Two factors * / void level3 (int * result) {register char op; int hold;

Level4; WHILE ((OP = * token) == '*' || op == '/' || op == '%') {GET_TOKEN (); Level3 (& Hold); Arith (OP, Result & Hold;}}

/ * process integer exponent * / void level4 (int * result) {register char op; int hold;

Level5 (result); if (* token == '^') {get_token (); Level4 (& Hold); Arith (OP, Result, & Hold);}

/ * is a unary or - * / void level5 (int * result) {register char OP; op = 0; if ((token_type == delimiter) && * token == ' ' || * token == '- ') {OP = * token; get_token ();} Level6 (OP) UNARY (OP, RESULT);

/ * Process Parenthesized Expression * / Void Level6 (INT * Result) {IF ((* token == '(') && (Token_Type == Delimiter) {get_token (); level2; if (* token! = ')') SERROR (1); GET_TOKEN ();} else primitive (result);

/ * Find Value of Number or Variable * / Void Primitive (INT * Result) {copy variable: * result = find_var (token); get_token (); return; case number: * result = atoi (token) Get_token (); return; default: serror (0);}} / * Perform the specified arithmetic * / void Arith (CHAR O, INT * R, INT * H) {Register INT T, EX; Switch (O) { Case '-': * r = * r- * h; Break; Case ' ': * r = * R * H; Break; Case '*': * r = * r ** h; Break; Case '/ ': * R = (* r) / (* h); Break; Case'% ': * r = (* r)% (* h); Break; Case' ^ ': EX = * r; if (* h == 0) {* r = 1; Break;} for (t = * h-1; t> 0; - t) * r = (* r) * EX; Break;}}

/ * REVERSE THE SIGN * / VOID UNARY (CHAR O, INT * R) {IF (o == '-') * r = - (* r);}

/ * Find the value of a variable * / int find_var (char * s) {if (! isalpha (* s)) {serror (4); / * not a variable * / return 0;} returnavles [TouPper " Token - 'a'];

/ * DISPLAY An Error Message * / Void SERROR (INT Error) {char * e [] = {"Syntax Error", "NO Expression Present", "Equal Sign Expected", "Not a Variable", "Label Table Full", "Duplicate Label", "Undefined Label", "Ten Expected", "TOO MANY NESTED for Loops", "Next WITHOUT for", "Too Many Nested Gosub", "Return WITHOUT Gosub "}; Printf ("% s / n ", e [error]); longjmp (e_buf, 1); / * return to save point * /}

/ * Get a token * / get_token () {register char * TEMP;

Token_Type = 0; tok = 0; Temp = token; if (* prog == '/ 0') {/ * end of file * / * token = 0; tok = finished; return (token_type = delimiter);} While Iswhite (* prog)) prog; / * SKIP over White Space * /

IF (* prog == '/ r') {/ * CR LF * / Prog; Prog; tok = eol; * token = '/ r'; token [1] = '/ n'; token [ 2] = 0; return (token_type = delimiter;} if (strchr (" - * ^ /% =; (),> <", * prog)) {/ * delimiter * / * temp = * prog; prog ; / * Advance to next position * / temp ; * temp = 0; return (token_type = Delimiter);} if (* prog == '") {/ * quote string * / prog ; while (* prog! =' "'&& * prog! =' / r ') * TEMP = * prog ; if (* prog ==' / r ') SERROR (1); prOG ; * Temp = 0; Return (token_type = quote);} (Isdigit (* number) {/ * number * / while (! isdelim (* prog)) * TEMP = * prog ; * Temp = '/ 0'; return (token_type = number);} if (isalpha (* prog) )) {/ * Var or command * / while (isdelim (* prog)) * TEMP = * prog ; token_type = string;}

* temp = '/ 0';

/ * see if a string is a command or a variable * / if (token_type == String) {tok = Look_up (token); / * Convert to INTERNAL REP * / IF (! tok) token_type = variable; else token_type = Command ; / * Is a command * /} return token_type;}

/ * RETURN A token to input stream * / void putback () {char * t; t = token; for (; * t; t ) prog--;}

Look_up (char * s) {Register INT I, J; Char * P;

/ * Convert to LowerCase * / P = S; While (* p) {* p = tolower (* p); p ;} / * see if token is in table * / for (i = 0; * Table [i] .command; i ) IF (! Strcmp (Table [i] .command, s)) Return Table [i] .tok; return 0; / * unknown command * /}

/ * RETURN TRUE IF C IS A DELIMITER * / ISDELIM (CHAR C) {IF (Strchr (";, - <> / *% ^ = ()", c) || ​​c == 9 || c == '/ r' || c == 0) Return 1; Return 0;}

Iswhite (CHAR C) {if (c == '|| c ==' / t ') Return 1; else return 0;}

转载请注明原文地址:https://www.9cbs.com/read-3189.html

New Post(0)