Страницы

Translate

воскресенье, 29 сентября 2013 г.

Exercise 5.19. Modify undcl so that it does not add redundant parentheses to declarations.


Exercise 5.19. Modify undcl so that it does not add redundant parentheses to declarations.


#include <stdio.h>
#include <string.h>
#include <ctype.h>

#define MAXTOKEN 100

enum {NAME, PARENS, BRACKETS};
enum {NO, YES};

void dcl(void);
void dirdcl(void);

int gettoken(void);
int tokentype;                      //type of last token
char token[MAXTOKEN];       //last token string
char name[MAXTOKEN];        //identifier name
char datatype[MAXTOKEN];    //data type = char, int, etc.
char out[1000];
int posttoken(void);
int pretoken = NO;

/* undcl: convert word descriptions to declarations */
int main()
{
    int type;
    char temp[MAXTOKEN];
    
    while(gettoken() != EOF)        //1st token on line
    {
        strcpy(out, token);
        while((type = gettoken()) != '\n')
            if(type == PARENS || type == BRACKETS)
                strcat(out, token);
            else if(type == '*')
            {
                if((type = posttoken()) == PARENS || type == BRACKETS)
                    sprintf(temp, "(*%s)", out);
                else
                    sprintf(temp, "*%s", out);
                strcpy(out, temp);
            }
            else if(type == NAME)
            {
                sprintf(temp, "%s %s", token, out);
                strcpy(out, temp);
            }
            else
                printf("invalid input at %s\n", token);
        printf("%s\n", out);
    }
    return 0;
}

/* dcl: parse a declarator */
void dcl(void)
{
    int ns;
    
    for(ns = 0; gettoken() == '*';) //count stars
        ns++;
    dirdcl();
    while(ns-- > 0)
        strcat(out, " pointer to");
}

/* dirdcl: parse a direct declarator */
void dirdcl(void)
{
    int type;
    
    if(tokentype == '(') //(dcl)
    {
        dcl();
        if(tokentype != ')')
            printf("error: missing )\n");
    }
    else if(tokentype == NAME) //variable name
        strcpy(name, token);
    else
        printf("error: expected name or (dcl)\n");
    while((type = gettoken()) == PARENS || type == BRACKETS)
        if(type == PARENS)
            strcat(out, " function returning");
        else
        {
            strcat(out, " array");
            strcat(out, token);
            strcat(out, " of");
        }
}

int getch(void);
void ungetch(int c);


int gettoken(void)
{
    int c, getch(void);
    void ungetch(int);
    char *p = token;
    
    if(pretoken == YES)
    {
        pretoken = NO;
        return tokentype;
    }    
    while((c = getch()) == ' ' || c == '\t')
        ;
    if(c == '(')
    {
        if((c = getch()) == ')')
        {
            strcpy(token, "()");
            return tokentype = PARENS;
        }
        else
        {
            ungetch(c);
            return tokentype = '(';
        }
    }
    else if(c == '[')
    {
        for(*p++ = c; (*p++ = getch()) != ']';)
            ;
        *p = '\0';
        return tokentype = BRACKETS;
    }
    else if(isalpha(c))
    {
        for(*p++ = c; isalnum(c = getch());)
            *p++ = c;
        *p = '\0';
        ungetch(c);
        return tokentype = NAME;
    }
    else
        return tokentype = c;
}

#define BUFSIZE 100

char buf[BUFSIZE];  //buffer for ungetch;
int bufp = 0; //next free position in buf

int getch(void) // get a (possibly pushed-back) character  
{
   return (bufp > 0) ? buf[--bufp] : getchar();
}

void ungetch(int c) // push character back on input
{
    if(bufp >= BUFSIZE)
        printf("ungetch: too many characnters\n");
    else
        buf[bufp++] = c;
}

int posttoken(void)
{
    int nexttype;
    
    nexttype = gettoken();
    pretoken = YES;
    return nexttype;
}

Result:



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

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