Thread: K&R Exercise 5-20 : bsearch Error when compiled

Threaded View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Registered User
    Join Date
    Jun 2013
    Posts
    9

    K&R Exercise 5-20 : bsearch Error when compiled

    Problem
    Expand dcl to handle declarations with function argument types, qualifiers like const, and so on.
    Answer:
    main.c
    Code:
    #include "extern.h"
    #include <string.h>
    #include <ctype.h>
    
    
    
    
    enum { NAME, PARENS, BRACKETS};
    enum {NO, YES};
    
    
    void dcl (void);
    void dirdcl(void);
    void errmsg(char *);
    int gettoken(void);
    
    
    int tokentype;
    char token[MAXTOKEN];
    char name[MAXTOKEN];
    char datatype[MAXTOKEN];
    char out[1000];
    int prevtoken;
    
    
    int main()  /* convert declaration to words */
    {
        while (gettoken() != EOF) { /* 1st token on line */
             strcpy(datatype, token);   /* is the datatype */
             out[0] = '\0';
             dcl();         /* parse rest of line */
             if (tokentype != '\n')
                printf("syntax error\n");
             printf("%s:  %s %s\n", name, out, datatype);
        }
        return 0;
    }
    
    
    void dcl (void)
    {
        int ns;
        for(ns = 0; gettoken() == '*'; )
            ns++;
        dirdcl();
        while(ns-- > 0)
            strcat(out, " pointer to");
    }
    
    
    void dirdcl(void)
    {
        int type;
        void parmdcl(void);
        if(tokentype == '(') {
            dcl();
            if(tokentype != ')')
                errmsg("error: missing )\n");
        } else if (tokentype == NAME) {
            if(name[0] == '\0')
                strcpy(name, token);
        } else
            prevtoken = YES;
        while((type = gettoken()) == PARENS || type == BRACKETS || type == '(')
            if(type == PARENS)
                strcat(out, "function returning");
            else if (type == '(') {
                strcat(out, " function expecting");
                parmdcl();
                strcat(out, " and returning");
            } else {
                strcat(out, " array");
                strcat(out, token);
                strcat(out, " of");
            }
    }
    
    
    void errmsg(char *msg)
    {
        printf("%s",msg);
        prevtoken = YES;
    }
    parmdcl.c
    Code:
    #include "extern.h"
    #include <string.h>
    #include <stdlib.h>
    #include <ctype.h>
    
    
    enum { NAME, PARENS, BRACKETS};
    enum { NO, YES};
    
    
    void dcl(void);
    void errmsg(char *);
    void dclspec(void);
    int typespec(void);
    int typequal(void);
    int compare(char **, char **);
    int gettoken(void);
    
    
    int tokentype;
    char token[MAXTOKEN];
    char name[MAXTOKEN];
    char datatype[MAXTOKEN];
    char out[MAXTOKEN];
    int prevtoken;
    
    
    void parmdcl(void)
    {
            do {
                dclspec();
            } while(tokentype == ',');
            if(tokentype != ')')
                errmsg("missing ) in parameter declaration\n");
    }
    
    
    void dclspec (void)
    {
        char temp[MAXTOKEN];
        temp[0] = '\0';
        gettoken();
        do {
            if (tokentype != NAME) {
                prevtoken = YES;
                dcl();
            } else if (typespec() == YES) {
                    strcat(temp, " ");
                    strcat(temp, token);
                    gettoken();
            } else if(typequal() == YES) {
                    strcat(temp, " ");
                    strcat(temp, token);
                    gettoken();
            } else
                errmsg("unknown type in parameter list \n");
        } while (tokentype != ',' && tokentype != ')');
        strcat(out, temp);
        if(tokentype == ',')
            strcat(out, ",");
    }
    
    
    int typespec(void)
    {
        static char *types[] = {
            "char",
            "int",
            "void"
        };
        char *pt = token;
        
        if (bsearch(&pt, types, sizeof(types)/sizeof(char *), sizeof(char *), compare)==NULL)
            return NO;
        else
            return YES;
    }
    
    
    int typequal(void)
    {
        static char *typeq[] = {
                "const",
                "volatile"
        };
        char *pt = token;
        
        if(bsearch(&pt, typeq, sizeof(typeq)/sizeof(char *), sizeof(char *), compare) == NULL)
            return NO;
        else
            return YES;
        
    }
    
    
    int compare(char **s, char **t)
    {
        return strcmp(*s, *t);
    }
    gettoken.c
    Code:
    #include "extern.h"
    #include <ctype.h>
    #include <string.h>
    
    
    enum {NAME, PARENS, BRACKETS};
    enum {NO, YES};
    
    
    int tokentype;
    char token[MAXTOKEN];
    int prevtoken = NO;
    
    
    int gettoken(void)
    {
        int c, getch(void);
        void ungetch(int);
        char *p = token;
        
        if (prevtoken == YES) {
            prevtoken = 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) /* pretend to push character back on input */
    {
        if (bufp >= BUFSIZE) 
            printf("ungetch:  too many characters\n");
        else 
            buf[bufp++] = c;
    }
    extern.h
    Code:
    #include <stdio.h>
    extern int tokentype;
    extern char token[];
    extern char name[];
    extern char datatype[];
    extern char out[];
    extern int prevtoken;
    
    
    #define MAXTOKEN 100
    gcc main.c parmdcl.c gettoken.c -Wall -Werror -pedantic -g -o dcl.exe
    Error: passing argument 5 of 'bsearch' from incompatible pointer type [-Werror]

    So i think the 5th argument of bsearch doesn't seem to accept double pointers. The function compare()'s parameter have two double pointers because it will receive string arguments for the bsearch (from <stdlib.h>) to compare them if they are in the static char arrays, *typeq[] and *types[].

    The error lies in the functions typespec() and typequal() in the parmdcl.c sourcefile. Anyone know how to make this work?
    Last edited by BinaryProgamer; 06-25-2013 at 02:49 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Exercise reverse array . I can't to find error .
    By ToNy_ in forum C Programming
    Replies: 8
    Last Post: 12-15-2011, 04:02 PM
  2. Replies: 1
    Last Post: 03-12-2008, 12:10 AM
  3. Compiled without error but Result varies!!
    By RahulDhanpat in forum C Programming
    Replies: 10
    Last Post: 02-12-2008, 10:32 AM
  4. Compiled error?
    By name|ess` in forum C++ Programming
    Replies: 2
    Last Post: 06-14-2004, 08:48 AM
  5. VC 6.0 compiled error
    By alan4100 in forum Windows Programming
    Replies: 4
    Last Post: 09-17-2001, 03:10 PM