📄 chap9.lst
字号:
get_token(); // skip opening (
eval_exp(cond); // initialization expression
if(*token != ';') throw InterpExc(SEMI_EXPECTED);
prog++; // get past the ;
temp = prog;
for(;;) {
// Get the value of the conditional expression.
eval_exp(cond);
if(*token != ';') throw InterpExc(SEMI_EXPECTED);
prog++; // get past the ;
temp2 = prog;
// Find start of for block.
paren = 1;
while(paren) {
get_token();
if(*token == '(') paren++;
if(*token == ')') paren--;
}
// Confirm start of block.
get_token();
if(*token != '{')
throw InterpExc(BRACE_EXPECTED);
putback();
// If condition is true, interpret
if(cond)
interp();
else { // otherwise, skip to end of loop
find_eob();
return;
}
prog = temp2; // go to increment expression
// Check for break in loop.
if(breakfound) {
// Find start of loop block.
do {
get_token();
} while(*token != '{' && tok != END);
putback();
breakfound = false;
find_eob(); // now, find end of loop
return;
}
// Evaluate the increment expression.
eval_exp(cond);
prog = temp; // loop back to top
}
}
// Execute a cout statement.
void exec_cout()
{
int val;
get_token();
if(*token != LS) throw InterpExc(SYNTAX);
do {
get_token();
if(token_type==STRING) {
// Output a string.
cout << token;
}
else if(token_type == NUMBER ||
token_type == IDENTIFIER) {
// Output a number.
putback();
eval_exp(val);
cout << val;
}
else if(*token == '\'') {
// Output a character constant.
putback();
eval_exp(val);
cout << (char) val;
}
get_token();
} while(*token == LS);
if(*token != ';') throw InterpExc(SEMI_EXPECTED);
}
// Execute a cin statement.
void exec_cin()
{
int val;
char chval;
token_ireps vtype;
get_token();
if(*token != RS) throw InterpExc(SYNTAX);
do {
get_token();
if(token_type != IDENTIFIER)
throw InterpExc(NOT_VAR);
vtype = find_var_type(token);
if(vtype == CHAR) {
cin >> chval;
assign_var(token, chval);
}
else if(vtype == INT) {
cin >> val;
assign_var(token, val);
}
get_token();
} while(*token == RS);
if(*token != ';') throw InterpExc(SEMI_EXPECTED);
}
// Find the end of a block.
void find_eob()
{
int brace;
get_token();
if(*token != '{')
throw InterpExc(BRACE_EXPECTED);
brace = 1;
do {
get_token();
if(*token == '{') brace++;
else if(*token == '}') brace--;
} while(brace && tok != END);
if(tok==END) throw InterpExc(UNBAL_BRACES);
}
// Determine if an identifier is a variable. Return
// true if variable is found; false otherwise.
bool is_var(char *vname)
{
// See if vname a local variable.
if(!local_var_stack.empty())
for(int i=local_var_stack.size()-1;
i >= func_call_stack.top(); i--)
{
if(!strcmp(local_var_stack[i].var_name, vname))
return true;
}
// See if vname is a global variable.
for(unsigned i=0; i < global_vars.size(); i++)
if(!strcmp(global_vars[i].var_name, vname))
return true;
return false;
}
// Return the type of variable.
token_ireps find_var_type(char *vname)
{
// First, see if it's a local variable.
if(!local_var_stack.empty())
for(int i=local_var_stack.size()-1;
i >= func_call_stack.top(); i--)
{
if(!strcmp(local_var_stack[i].var_name, vname))
return local_var_stack[i].v_type;
}
// Otherwise, try global vars.
for(unsigned i=0; i < global_vars.size(); i++)
if(!strcmp(global_vars[i].var_name, vname))
return local_var_stack[i].v_type;
return UNDEFTOK;
}
listing 3
// ***** Internal Library Functions *****
// Add more of your own, here.
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include "mccommon.h"
using namespace std;
// Read a character from the console.
// If your compiler supplies an unbuffered
// character intput function, feel free to
// substitute it for the call to cin.get().
int call_getchar()
{
char ch;
ch = getchar();
// Advance past ()
get_token();
if(*token != '(')
throw InterpExc(PAREN_EXPECTED);
get_token();
if(*token != ')')
throw InterpExc(PAREN_EXPECTED);
return ch;
}
// Write a character to the display.
int call_putchar()
{
int value;
eval_exp(value);
putchar(value);
return value;
}
// Return absolute value.
int call_abs()
{
int val;
eval_exp(val);
val = abs(val);
return val;
}
// Return a randome integer.
int call_rand()
{
// Advance past ()
get_token();
if(*token != '(')
throw InterpExc(PAREN_EXPECTED);
get_token();
if(*token != ')')
throw InterpExc(PAREN_EXPECTED);
return rand();
}
listing 4
// Common declarations used by parser.cpp, minicpp.cpp,
// or libcpp.cpp, or by other files that you might add.
//
const int MAX_T_LEN = 128; // max token length
const int MAX_ID_LEN = 31; // max identifier length
const int PROG_SIZE = 10000; // max program size
const int NUM_PARAMS = 31; // max number of parameters
// Enumeration of token types.
enum tok_types { UNDEFTT, DELIMITER, IDENTIFIER,
NUMBER, KEYWORD, TEMP, STRING, BLOCK };
// Enumeration of internal representation of tokens.
enum token_ireps { UNDEFTOK, ARG, CHAR, INT, SWITCH,
CASE, IF, ELSE, FOR, DO, WHILE, BREAK,
RETURN, COUT, CIN, END };
// Enumeration of two-character operators, such as <=.
enum double_ops { LT=1, LE, GT, GE, EQ, NE, LS, RS, INC, DEC };
// These are the constants used when throwing a
// syntax error exception.
//
// NOTE: SYNTAX is a generic error message used when
// nothing else seems appropriate.
enum error_msg
{ SYNTAX, NO_EXP, NOT_VAR, DUP_VAR, DUP_FUNC,
SEMI_EXPECTED, UNBAL_BRACES, FUNC_UNDEF,
TYPE_EXPECTED, RET_NOCALL, PAREN_EXPECTED,
WHILE_EXPECTED, QUOTE_EXPECTED, DIV_BY_ZERO,
BRACE_EXPECTED, COLON_EXPECTED };
extern char *prog; // current location in source code
extern char *p_buf; // points to start of program buffer
extern char token[MAX_T_LEN+1]; // string version of token
extern tok_types token_type; // contains type of token
extern token_ireps tok; // internal representation of token
extern int ret_value; // function return value
extern bool breakfound; // true if break encountered
// Exception class for Mini C++.
class InterpExc {
error_msg err;
public:
InterpExc(error_msg e) { err = e; }
error_msg get_err() { return err; }
};
// Interpreter prototypes.
void prescan();
void decl_global();
void call();
void putback();
void decl_local();
void exec_if();
void find_eob();
void exec_for();
void exec_switch();
void get_params();
void get_args();
void exec_while();
void exec_do();
void exec_cout();
void exec_cin();
void assign_var(char *var_name, int value);
bool load_program(char *p, char *fname);
int find_var(char *s);
void interp();
void func_ret();
char *find_func(char *name);
bool is_var(char *s);
token_ireps find_var_type(char *s);
// Parser prototypes.
void eval_exp(int &value);
void eval_exp0(int &value);
void eval_exp1(int &value);
void eval_exp2(int &value);
void eval_exp3(int &value);
void eval_exp4(int &value);
void eval_exp5(int &value);
void atom(int &value);
void sntx_err(error_msg error);
void putback();
bool isdelim(char c);
token_ireps look_up(char *s);
int find_var(char *s);
tok_types get_token();
int internal_func(char *s);
bool is_var(char *s);
// "Standard library" prototypes.
int call_getchar();
int call_putchar();
int call_abs();
int call_rand();
listing 5
/* Mini C++ Demonstration Program #1.
This program demonstrates all features
of C++ that are recognized by Mini C++.
*/
int i, j; // global vars
char ch;
int main()
{
int i, j; // local vars
// Call a "standard library' function.
cout << "Mini C++ Demo Program.\n\n";
// Call a programmer-defined function.
print_alpha();
cout << "\n";
// Demonstrate do and for loops.
cout << "Use loops.\n";
do {
cout << "Enter a number (0 to quit): ";
cin >> i;
// Demonstrate the if
if(i < 0 ) {
cout << "Numbers must be positive, try again.\n";
}
else {
for(j = 0; j <= i; ++j) {
cout << j << " summed is ";
cout << sum(j) << "\n";
}
}
} while(i != 0);
cout << "\n";
// Demonstrate the break in a loop.
cout << "Break from a loop.\n";
for(i=0; i < 100; i++) {
cout << i << "\n";
if(i == 5) {
cout << "Breaking out of loop.\n";
break;
}
}
cout << "\n";
// Demonstrate the switch
cout << "Use a switch.\n";
for(i=0; i < 6; i++) {
switch(i) {
case 1: // can stack cases
case 0:
cout << "1 or 0\n";
break;
case 2:
cout << "two\n";
break;
case 3:
cout << "three\n";
break;
case 4:
cout << "four\n";
cout << "4 * 4 is "<< 4*4 << "\n";
// break; // this break is optional
// no case for 5
}
}
cout << "\n";
cout << "Use a library function to generate "
<< "10 random integers.\n";
for(i=0; i < 10; i++) {
cout << rand() << " ";
}
cout << "\n";
cout << "Done!\n";
return 0;
}
// Sum the values between 0 and num.
// This function takes a parameter.
int sum(int num)
{
int running_sum;
running_sum = 0;
while(num) {
running_sum = running_sum + num;
num--;
}
return running_sum;
}
// Print the alphabet.
int print_alpha()
{
cout << "This is the alphabet:\n";
for(ch = 'A'; ch<='Z'; ch++) {
putchar(ch);
}
cout << "\n";
return 0;
}
listing 6
// Nested loop example.
int main()
{
int i, j, k;
for(i = 0; i < 5; i = i + 1) {
for(j = 0; j < 3; j = j + 1) {
for(k = 3; k ; k = k - 1) {
cout << i <<", ";
cout << j << ", ";
cout << k << "\n";
}
}
}
cout << "done";
return 0;
}
listing 7
// Assigments as operations.
int main()
{
int a, b;
a = b = 5;
cout << a << " " << b << "\n";
while(a=a-1) {
cout << a << " ";
do {
cout << b << " ";
} while((b=b-1) > -5);
cout << "\n";
}
return 0;
}
listing 8
// This program demonstrates a recursive function.
// A recursive function that returns the
// factorial of i.
int factr(int i)
{
if(i<2) {
return 1;
}
else {
return i * factr(i-1);
}
}
int main()
{
cout << "Factorial of 4 is: ";
cout << factr(4) << "\n";
cout << "Factorial of 6 is: ";
cout << factr(6) << "\n";
return 0;
}
listing 9
// A more rigorous example of function arguments.
int f1(int a, int b)
{
int count;
cout << "Args for f1 are ";
cout << a << " " << b << "\n";
count = a;
do {
cout << count << " ";
} while(count=count-1);
cout << a << " " << b
<< " " << a*b << "\n";
return a*b;
}
int f2(int a, int x, int y)
{
cout << "Args for f2 are ";
cout << a << " " << x << " "
<< y << "\n";
cout << x / a << " ";
cout << y*x << "\n";
return 0;
}
int main()
{
f2(10, f1(10, 20), 99);
return 0;
}
listing 10
// Exercise the loop statements.
int main()
{
int a;
char ch;
// The while.
cout << "Enter a number: ";
cin >> a;
while(a) {
cout << a*a << " ";
--a;
}
cout << "\n";
// The do-while.
cout << "\nEnter characters, 'q' to quit.\n";
do {
// Use two "standard library" functions.
ch = getchar();
putchar(ch);
} while(ch != 'q');
cout << "\n\n";
// the for.
for(a=0; a<10; ++a) {
cout << a << " ";
}
cout << "\n\nDone!\n";
return 0;
}
listing 11
// Demonstrate nested scopes.
int x; // global x
int main()
{
int i;
i = 4;
x = 99; // global x is 99
if(i == 4) {
int x; // local x
int num; // local to if statement
x = i * 2;
cout << "Outer local x before loop: "
<< x << "\n";
while(x--) {
int x; // another local x
x = 18;
cout << "Inner local x: " << x << "\n";
}
cout << "Outer local x after loop: "
<< x << "\n";
}
// Can't refer to num here because it is local
// to the preceding if block.
// num = 10;
cout << "Global x: " << x << "\n";
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -