Exercise 6.6. Implement a simple version of the #define processor (i.e., no arguments) suitable for use with C programs, based on the routines of this section. You may also find getch and ungetch helpful.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#define MAXWORD 100
#define HASHSIZE 101
struct nlist{ //table entry
struct nlist *next; //next entry in chain
char *name; //define name
char *defn; //replacemrnt text
};
static struct nlist *hashtab[HASHSIZE]; //pointer table
void error(int, char *);
char *s_dup(char *);
int getch(void);
void ungetch(int);
int getword(char *, int);
void getdef(void);
void undef(char *);
void ungets(char *);
struct nlist *lookup(char *);
struct nlist *install(char *, char *);
void skipspace(void);
unsigned hash(char *);
/* a simple version of the #define processor */
int main()
{
char word[MAXWORD];
struct nlist *np;
while(getword(word, MAXWORD) != EOF)
if(strcmp(word, "#") == 0) //beginning def processor
getdef();
else if(!isalpha(word[0]))
printf("%s\n", word); //can't define
else if((np = lookup(word)) == NULL)
printf("%s\n", word); //not define
else
ungets(np->defn); //return definition
return 0;
}
void getdef(void)
{
int i;
char def[MAXWORD], dir[MAXWORD], name[MAXWORD];
skipspace();
if(!isalpha(getword(dir, MAXWORD)))
error(dir[0], "getdef: after # waiting directive");
else if(strcmp(dir, "define") == 0)
{
skipspace();
if(!isalpha(getword(name, MAXWORD)))
error(name[0], "getdef: not letter, waiting name");
else
{
skipspace();
for(i = 0; i < MAXWORD; i++)
if((def[i] = getch()) == EOF || def[i] == '\n')
break;
def[i] = '\0';
if(i <= 0) //not definition
error('\n', "getdef: incomplete definition");
else //put definition to table
install(name, def);
}
}
else if(strcmp(dir, "undef") == 0)
{
skipspace();
if(!isalpha(getword(name, MAXWORD)))
error(name[0], "getdef: not letter in directine undef");
else
undef(name);
}
else
error(dir[0], "getdef: aftewr # waiting directive");
}
/* error: print message about error and skip string */
void error(int c, char *s)
{
printf("Error: %s\n", s);
while(c != EOF && c != '\n')
c = getch();
}
/* skipspace: skip space and tabs */
void skipspace(void)
{
int c;
while((c = getch() == ' ' || c == '\t'))
;
ungetch(c);
}
/* ungets */
void ungets( char *s)
{
int len;
len = strlen(s);
while(len > 0)
ungetch(s[--len]);
}
Комментариев нет:
Отправить комментарий