1

I've been stuck with the dcl program from chapter 5.12 in K&R C. It is basically a program which accepts a C variable/function/table declaration and prints a description of it in English. It works for simple declarations such as int a but fails with more complicated ones. For example, when I enter int (*pf)() I get the output

error: expected name or (dcl)
Syntax error
:  int
error: expected name or (dcl)
:  function that returns pf

Below is the portion of the code related to the program. The getch() and ungetch() functions are in a separate file.

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

#define MAXTOKEN 100

enum { NAME, PARENS, BRACKETS };

void dcl(void);
void dirdcl(void);
int gettoken(void);

int tokentype;
char token[MAXTOKEN];
char name[MAXTOKEN];
char datatype[MAXTOKEN];
char out[1000];

int main(void)
{
    while (gettoken() != EOF) {
        strcpy(datatype, token);
        out[0] = '\0';
        dcl();
        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;

    if (tokentype == '(') {
        dcl();
        if (tokentype != ')')
            printf("error: missing )\n");
    } else if (tokentype == NAME)
        strcpy(name, token);
    else
        printf("error: expected name or (dcl)\n");
    while ((type=gettoken()) == PARENS || type == BRACKETS) {
        if (type == PARENS)
            strcat(out, " function that returns");
        else {
            strcat(out, " array");
            strcat(out, token);
            strcat(out, " of");
        }
    }
}

int gettoken(void)
{
    int c;
    char *p = token;

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

Could you please help me pinpoint the mistake?

3
  • 2
    You forgot to ask a question, but if you're wondering what's wrong with the program then the line return tokentype = ')'; in gettoken() looks wrong. It should probably be return tokentype = '(';, instead. There may be other issues. Commented Aug 5, 2021 at 18:00
  • Per request, mistake pinpointed: return tokentype = ')📍';. Commented Aug 5, 2021 at 18:07
  • @John Bollinger thank you. I added a question and from the beginning I found this part suspicious. The Greek print of the book has a ton of mistakes. Commented Aug 5, 2021 at 18:07

1 Answer 1

0

On p124 Brian and Dennis say "Since the programs are intended to be illustrative, not bullet-proof, there are significant restricts on dcl."

The final sentence in the paragraph has this version of the author's final cop-out: "These improvements are left as exercises."

This could be a good time to dust off yacc.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.