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
Post a Comment