ch5-undeclare (Encode declarations)

Chapter_5     Exercise_5-17     declare Exercise_5-18







CONTENTS:     undcl.txt     undcl.c     dcl.txt     dcl(copy).txt




undcl.txt     K&R, p. 122-123, 126         download


pf () * int
pf * () int
apf [] * () char
argv * * char
daytab * [13] int
daytab [13] * int
comp () * void
comp * () void
x () * [] * () char
x [3] * () * [5] char





undcl.c     K&R, p. 122-126         download


#include <stdio.h> // for printf(), sprintf(), getchar(), EOF
#include <string.h> // for strcat(), strcpy()
#include <ctype.h> // for isalpha(), isalnum()

/*
dcl: optional *s direct-dcl
direct-dcl: name
(dcl)
direct-dcl()
direct-dcl[optional size]
*/
// char (*(*x())[])()
// x () * [] * () char
#define MAXTOKEN 100 // max token length
#define MAXOUTPUT 1000 // max length of output string

enum {NAME, PARENS, BRACKETS};

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

int main() // convert word description to declaration
{
int type;
char temp[MAXOUTPUT+MAXTOKEN]; // to avoid warnings (temp not big enough)
// sprintf(), string printf(), writes into string temp
while(gettoken() != EOF) // process a file
{ // first token is variable or function name
strcpy(out, token); // reset at the beginning of each line

while ((type = gettoken()) != '\n') // process one line
{
if (type == PARENS || type == BRACKETS)
{strcat(out, token);}
else if (type == '*')
{
sprintf(temp, "(*%s)", out); // string printf()
strcpy(out, temp);
}
else if (type == NAME)
{ // data type
sprintf(temp, "%s %s", token, out);
strcpy(out, temp);
}
else {printf("Invalid token at %s\n", token);}
}

printf("%s\n", out);
}

return 0;
}

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

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

while((c = getch()) == ' ' || c == '\t')
{} // skip beginning whitespace

if (c == '(')
{
if ((c = getch()) == ')')
{
strcpy(token, "()");
return tokentype = PARENS;
}
else
{
ungetch(c);
return tokentype = '(';
}
}
else if (c == '[')
{
for (*p++ = c; (*p++ = getch()) != ']'; )
{} // token holds [...]
*p = '\0'; // end string
return tokentype = BRACKETS;
}
else if (isalpha(c))
{
for (*p++ = c; isalnum(c = getch()); )
{*p++ = c;}
*p = '\0'; // end string
ungetch(c);
return tokentype = NAME;
}
else {return tokentype = c;} // could be ')' or '\n' or EOF
}

// buffer for ungetch():
int buf = EOF-1; // not a real character, not even EOF

int getch(void) // get a (possibly pushed-back) character
{
if (buf < EOF)
{
return getchar();
}

int temp = buf; // buf >= EOF
buf = EOF-1; // reset buf

return temp;
}
// push character back on input (make it available for the next getch()):
void ungetch(int c)
{
buf = c;
}
/*
gcc undcl.c -o undcl
./undcl // Enter (input from keyboard)
apf [] * () char // Enter
char (*apf[])()
argv * * char // Enter
char (*(*argv))
comp () * void // Enter
void (*comp())
comp * () void // Enter
void (*comp)()
x () * [] * () char // Enter
char (*(*x())[])()
// Ctrl^D in Linux, Ctrl^Z+Enter in Windows (EOF)

./undcl < undcl.txt > "dcl(copy).txt"
meld dcl.txt "dcl(copy).txt"
// redundant parentheses
*/





Notes:  File name "dcl(copy).txt" is within quotes because the shell interprets parentheses (subshell). Notice the redundant parentheses in dcl(copy).txt compared to dcl.txt.











dcl.txt     K&R, p. 122-123         download


int *pf()
int (*pf)()
char (*apf[])()
char **argv
int (*daytab)[13]
int *daytab[13]
void *comp()
void (*comp)()
char (*(*x())[])()
char (*(*x[3])())[5]





dcl(copy).txt         download


int (*pf())
int (*pf)()
char (*apf[])()
char (*(*argv))
int (*daytab)[13]
int (*daytab[13])
void (*comp())
void (*comp)()
char (*(*x())[])()
char (*(*x[3])())[5]









Chapter_5     Exercise_5-17     declare BACK_TO_TOP Exercise_5-18



Comments

Popular posts from this blog

Contents

Blogger Page Margins in Contempo