Страницы

Translate

среда, 6 ноября 2013 г.

Exercise 6.6. Implement a simple version of the #define processor (i.e., no arguments)



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;
}

/* getdef: get definition and put it in table */
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]);

}

Комментариев нет:

Отправить комментарий