Unix program

Hello,

I have this program taken straight from the K&R textbook, which to converts a declaration into words. For example, char ** argv would evaluate to
argv: pointer to pointer to char. However this crashes on every attempt to turn declaration into words.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129

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


#define MAXTOKEN 100

enum { NAME, PARENS, BRACKETS };

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];            /* output string */


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


/* dcl: parse a declarator */

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


/* dirdcl: parse a direct declarator */

void dirdcl(void)
{
	int type;
	
	if (tokentype == '(') {
		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 gettoken(void)   /* return next token */

{
	
	int c, getch(void);
	void ungetch(int);
	char *p = token;  /* character string pointed by p */
	
	while ((c = getch()) == ' '  || c == '\t') /* skip blanks or tabs */
		;
	if (c == '(') {
		if ((c = getch()) == ')') { 
			strcpy(token, "()");         
			return tokentype = PARENS;  
		}  else {
			ungetch(c);   /* put character back on input before prosessing new input */           
			return tokentype = '(';
			
		 }
	 } else if (c == '[')  {
		 for (*p++ = c; (*p++ = getch()) != ']'; )  /* do nothing as long as character is not terminating bracket */ 
			 ;
		 *p = '\0';
		 return tokentype = BRACKETS;  /* if it is, we found it, so tokentype is brackets */
	 }   else if (isalpha(c))  {      
			for (*p++ = c; isalnum(c == getch()); ) /* read characters as long as is alphanumeric */
				*p++ = c;     
			*p = '\0';
			ungetch(c);          /* if not, push back into the buffer */
			return tokentype = NAME; 
		} else
			return tokentype = c;
  }
  
  
#define BUFSIZE 100

char buf[BUFSIZE];
int bufp = 0;

int getch(void) 
{
	return (bufp > 0) ? buf[--bufp] : getchar();
}

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

What input did you give it, what happened, what did you expect to happen?
Hi,

For example:

char**argv

syntax error
c: c
syntax error
c: c
syntax error
c: c

Expected: argv: pointer to pointer to char
This program can also be found here:
https://hassanolity.files.wordpress.com/2013/11/the_c_programming_language_2.pdf
Last edited on
Maybe I should just skip this chapter...
It could be me, but I think you're missing the code that actually parses the datatype. You never check for keywords (e.g. char). That's probably why your parser rejects the input. It doesn't understand the keyword char.

Edit: while inspecting more thoroughly, I noticed a small error in your code. In the function gettoken,, you wrote:

1
2
for (*p++ = c; isalnum(c == getch()); ) /* read characters as long as is alphanumeric */
    *p++ = c;


You use the == operator and pass this to isalnum. This operator returns true or false, converted to 1 or 0. Both character 1 and 0 are not alphanumeric, so you will always read only 1 character. Use operator= to solve your problem.
Last edited on
However this crashes on every attempt


As an aside, this is very much not a crash. A crash involves the program aborting unexpectedly. This program doesn't crash. It keeps running. Big, big difference in nomenclature; if you say "crash" when you mean "doesn't do what I expected", people will have trouble helping you because they will be looking for reasons why the code would crash.
Last edited on
Thank you shadowwolf, now it's working just a simple problem as that was hanging my code :/
Topic archived. No new replies allowed.