#!/bin/sh # This is a shar archive. # The rest of this file is a shell script which will extract: # # 3_12.c 3_12.cmp 3_12.in 3_12a.c 3_12b1.c 3_12tst.c makefile # # To extract the files from this shell archive file simply # create a directory for this file, move the archive file # to it and enter the command # # sh filename # # The files will be extracted automatically. # Note: Do not use csh. # # Archive created: Mon Jul 30 22:58:02 EDT 1990 # echo x - 3_12.c sed 's/^X//' > 3_12.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ // Read a token into the buffer. // Read a line at a time. #include #include token_value get_token() { static char linebuf[512] = ""; static int lineindex = 0; // if line is empty, fill it if (linebuf[lineindex] == '\0') { if (!cin.get(linebuf, sizeof linebuf - 1)) return (curr_tok = END); // discard newline from input char c; cin.get(c); // install newline within line int end = strlen(linebuf); linebuf[end++] = '\n'; linebuf[end] = '\0'; lineindex = 0; } // delete leading whitespace on the line while (isspace(linebuf[lineindex]) && (linebuf[lineindex] != '\n')) lineindex++; // match a token char ch; switch (ch = linebuf[lineindex++]) { case ';': case '\n': return (curr_tok = PRINT); case '*': case '+': case '(': case '/': case '-': case ')': case ':': return (curr_tok = ch); // match a number case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '.': int saveindex = lineindex - 1; while (isdigit(ch = linebuf[lineindex]) || (ch == '.')) lineindex++; linebuf[lineindex] = '\0'; number_value = atof(&linebuf[saveindex]); linebuf[lineindex] = ch; return (curr_tok = NUMBER); default: if (isalpha(ch)) { char *p = name_string; for (*p++ = ch; isalnum(ch = linebuf[lineindex]); *p++ = ch, lineindex++) ; *p = '\0'; return (curr_tok = NAME); } error("unknown token received"); return (curr_tok = PRINT); } } !EOF! ls -l 3_12.c echo x - 3_12.cmp sed 's/^X//' > 3_12.cmp << '!EOF!' curr_tok=# numb='32' curr_tok=+ curr_tok=# numb='495' curr_tok=- curr_tok=# numb='27' curr_tok=P curr_tok=N name='foo' curr_tok=+ curr_tok=# numb='99' curr_tok=P !EOF! ls -l 3_12.cmp echo x - 3_12.in sed 's/^X//' > 3_12.in << '!EOF!' 32+495-27 foo+99 !EOF! ls -l 3_12.in echo x - 3_12a.c sed 's/^X//' > 3_12a.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ ch = linebuf[lineindex++] !EOF! ls -l 3_12a.c echo x - 3_12b1.c sed 's/^X//' > 3_12b1.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ lineindex - 1 !EOF! ls -l 3_12b1.c echo x - 3_12tst.c sed 's/^X//' > 3_12tst.c << '!EOF!' /* Copyright (c) 1990 by AT&T Bell Telephone Laboratories, Incorporated. */ /* The C++ Answer Book */ /* Tony Hansen */ /* All rights reserved. */ #include #include #include enum token_value { END = 'E', PRINT='P', NUMBER='#', NAME='N', L1='*', L2='+', L3='(', L4=')', L5='/', L6='-', L7=':' } curr_tok; double number_value; char name_string[512]; #include "3_12.c" main() { while (get_token() != END) { cout << "curr_tok=" << chr(curr_tok) << "\n"; switch (curr_tok) { case NAME: cout << "name='" << name_string << "'\n"; break; case NUMBER:cout << "numb='" << number_value<< "'\n"; break; } } return 0; } !EOF! ls -l 3_12tst.c echo x - makefile sed 's/^X//' > makefile << '!EOF!' CC= CC -I. -I../../CC ERROR= ../../error.o all: 3_12tst 3_12tst: 3_12.c 3_12tst.c $(CC) 3_12tst.c -o 3_12tst $(ERROR) test: all 3_12.cmp 3_12tst < 3_12.in > 3_12.out cmp 3_12.out 3_12.cmp echo tests done !EOF! ls -l makefile # The following exit is to ensure that extra garbage # after the end of the shar file will be ignored. exit 0