1

I am trying to compile one of Donald Knuth's programs http://www-cs-faculty.stanford.edu/~uno/programs/grayspan.w.

I am using Ubuntu, I installed Marc van Leeuwen's version of CWEB which uses ctanglex and cweavex, I also installed the Stanford Graphbase.
At the commandline I type; ctanglex grayspan.w

This produces a file; grayspan.c
However when I compile (gcc grayspan.c -o grayspan) I get this error

grayspan.c:1:23: error: expected ‘)’ before ‘>’ token  
#define verbose (argc>2)

The output of the command ctanglex grayspan.w is;

ctanglex grayspan.w
This is CTANGLE (Version x3.04)
*1
! `@f', `@d', `@h', and `@c' are ignored in section body. (l. 32)
@h
  *4*6*16*18
Writing the output file (grayspan.c):..
Done.
(Pardon me, but I think I spotted something wrong)

and the full output of gcc grayspan.c -o grayspan is;

grayspan.c:1:22: error: expected ‘)’ before ‘>’ token
 #define verbose (argc>2)
                      ^
grayspan.w: In function ‘print_arcs’:
grayspan.w:125:1: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long int’ [-Wformat=]
     printf(" %d (to %s)\n",a->len,a->tip->name);
 ^
grayspan.w: In function ‘print_a’:
grayspan.w:348:1: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘long int’ [-Wformat=]
        k,aa(k)->len, aa(k)->tip->name, mate(aa(k))->tip->name);
 ^
grayspan.w: In function ‘main’:
grayspan.w:55:1: warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘long int’ [-Wformat=]
     argv[1],panic_code);
 ^
grayspan.w:233:1: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘long int’ [-Wformat=]
     l,e->len,v->name,v->deg);
 ^
grayspan.w:233:1: warning: format ‘%d’ expects argument of type ‘int’, but argument 5 has type ‘long int’ [-Wformat=]
grayspan.w:205:1: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long int’ [-Wformat=]
     for (k=1;k<n;k++) printf(" %d",aa(k)->len);
 ^
grayspan.w:206:1: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long int’ [-Wformat=]
     if (extraverbose && change_e) printf(" (-%d+%d)\n",change_e->len,e->len);
 ^
grayspan.w:206:1: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘long int’ [-Wformat=]
grayspan.w:208:1: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘long int’ [-Wformat=]
   }@+else printf("%.15g: -%d+%d\n",count,change_e->len,e->len);
 ^
grayspan.w:208:1: warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘long int’ [-Wformat=]
grayspan.w:254:1: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘long int’ [-Wformat=]
     l,e->len,v->name,v->deg);
 ^
grayspan.w:254:1: warning: format ‘%d’ expects argument of type ‘int’, but argument 5 has type ‘long int’ [-Wformat=]
grayspan.w:272:1: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘long int’ [-Wformat=]
     l,e->len,u->name);
 ^
grayspan.w:277:1: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘long int’ [-Wformat=]
     l,e->len,e->link->len!=e->len? e->link->len: e->link->link->len);
 ^
grayspan.w:277:1: warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘long int’ [-Wformat=]
grayspan.w:288:1: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘long int’ [-Wformat=]
 if (extraverbose) printf("level %d: %d is a bridge\n",l,e->len);
 ^
grayspan.w:302:1: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘long int’ [-Wformat=]
 if (extraverbose) printf("level %d: deleting %d\n",l,e->len);
 ^
grayspan.w:310:1: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long int’ [-Wformat=]
   if (extraverbose) printf("undeleting %d\n",e->len);'

The file grayspan.c ; for all those who wont click on an external link;

#define verbose (argc>2)
#define extraverbose (argc>3)
#define o mems++
#define oo mems+=2
#define ooo mems+=3
#define oooo mems+=4
#define ooooo mems+=5
#define deg u.I
#define prev a.A
#define mate(e)(edge_trick&(siz_t)(e)?(e)-1:(e)+1)
#define aa(l)(g->vertices+l)->z.A
#define del(l)(g->vertices+l)->y.A
#define link b.A
#define delete(e)ee=e,oooo,ee->prev->next=ee->next,ee->next->prev=ee->prev
#define undelete(e)ee=e,oooo,ee->next->prev=ee,ee->prev->next=ee
#define bfs v.V
#define sentinel (g->vertices)
/*1:*/
#line 30 "grayspan.w"
#include "gb_graph.h"
#include "gb_save.h"

double mems;
double count;/*5:*/
#line 120 "grayspan.w"
void print_arcs(Vertex*v)
{
register Arc*a;
printf("Arcs leading from %s:\n",v->name);
for(a=v->arcs->next;a->tip;a=a->next)
printf(" %d (to %s)\n",a->len,a->tip->name);
}/*:5*//*17:*/
#line 343 "grayspan.w"
void print_a(register Graph*g)
{
register int k;
for(k=1;k<g->n;k++)
printf(" a%d=%d (%s -- %s)\n",
k,aa(k)->len,aa(k)->tip->name,mate(aa(k))->tip->name);
}/*:17*/
#line 35 "grayspan.w"

main(int argc,char*argv[])
{/*3:*/
#line 62 "grayspan.w"
register Graph*g;
register int n;
register int k;
register Vertex*u,*v,*w;
register Arc*e,*ee,*f,*ff;/*:3*//*8:*/
#line 197 "grayspan.w"
register int l;
Arc*change_e;/*:8*/
#line 38 "grayspan.w"
;/*2:*/
#line 47 "grayspan.w"
if(argc<2){
fprintf(stderr,"Usage: %s foo.gb [[gory] details]\n",argv[0]);
exit(1);
}
g=restore_graph(argv[1]);
if(!g){
fprintf(stderr,
"Sorry, can't create the graph from file %s! (error code %d)\n",
argv[1],panic_code);
exit(-1);
}
n=g->n;/*4:*/
#line 89 "grayspan.w"
if(verbose)printf("Graph %s has the following edges:\n",g->id);
for(v=g->vertices,k=0;v<g->vertices+n;v++){
f=gb_virgin_arc();f->next=v->arcs;
for(v->deg=0,e=v->arcs,v->arcs=f;e;v->deg++,f=e,e=e->next){
e->prev=f;
u=e->tip;
if(u==v){
fprintf(stderr,"Oops, there's a loop from %s to itself!\n",v->name);
exit(-3);
}
if(mate(e)->tip!=v){
fprintf(stderr,"Oops: There's an arc from %s to %s,\n",u->name,v->name);
fprintf(stderr," but the edge trick doesn't find the opposite arc!\n");
exit(-4);
}
if(u>v){
e->len=mate(e)->len= ++k;
if(verbose)printf(" %d: %s -- %s\n",k,v->name,u->name);
}
}
v->arcs->prev=f,f->next=v->arcs;
if(v->deg==0){
fprintf(stderr,"Graph %s has an isolated vertex %s!\n",
g->id,v->name);
exit(-5);
}
}/*:4*/
#line 59 "grayspan.w"
;/*:2*/
#line 39 "grayspan.w"
;/*16:*/
#line 322 "grayspan.w"
for(v=g->vertices+1;v<g->vertices+n;v++)v->bfs=NULL;
for(k=n-1,o,w=v=g->vertices,w->bfs=sentinel;;o,v=w,w=w->bfs){
for(oo,e=v->arcs->next;o,u=e->tip;o,e=e->next)
if(o,u->bfs==NULL){
o,aa(k)=e,k--;
if(k==0)goto connected;
o,u->bfs=w,w=u;
}
if(w==sentinel)break;
}
printf("Oops, the graph isn't connected!\n");exit(0);
connected:for(u=g->vertices;u<g->vertices+n;u++)o,u->bfs=NULL;
if(extraverbose){
printf("Depth-first search yields the following spanning tree:\n");
print_a(g);
}
if(verbose)printf("(%.15g mems for initialization)\n",mems);/*:16*/
#line 40 "grayspan.w"
;/*7:*/
#line 175 "grayspan.w"
change_e=NULL;
v=g->vertices;
for(l=1;l<n-1;l++){
o,del(l)=NULL;
enter:ooo,e=aa(l+1),u=e->tip,v=mate(e)->tip;
if(oo,u->deg>v->deg)v=u,e=mate(e),u=e->tip;/*10:*/
#line 226 "grayspan.w"
oo,k=u->deg+v->deg;
for(o,f=u->arcs->next,ff=NULL;o,f->tip;o,f=f->next)
if(f->tip==v)delete(f),delete(mate(f)),k-=2,o,f->link=ff,ff=f;
else o,mate(f)->tip=v;
oo,e->link=ff,v->deg=k;
if(extraverbose)
printf("level %d: Shrinking %d; now %s has degree %d\n",
l,e->len,v->name,v->deg);
o,ff=v->arcs;
oooo,f->prev->next=ff->next,ff->next->prev=f->prev;
ooo,f->next->prev=ff,ff->next=f->next;/*:10*/
#line 181 "grayspan.w"
;
o,aa(l)=e;
}
for(o,e=v->arcs->next;o,e->tip;o,e=e->next){
o,aa(l)=e;/*9:*/
#line 201 "grayspan.w"
count++;
if(verbose){
if(!change_e||extraverbose){
printf("%.15g:",count);
for(k=1;k<n;k++)printf(" %d",aa(k)->len);
if(extraverbose&&change_e)printf(" (-%d+%d)\n",change_e->len,e->len);
else printf("\n");
}else printf("%.15g: -%d+%d\n",count,change_e->len,e->len);
}/*:9*/
#line 186 "grayspan.w"
;
change_e=e;
}
for(l--;l;l--){
e=aa(l),u=e->tip,v=mate(e)->tip;/*11:*/
#line 245 "grayspan.w"
oo,f=u->arcs,ff=v->arcs;
ooo,ff->next=f->prev->next;o,ff->next->prev=ff;
ooo,f->prev->next=f,f->next->prev=f;
for(f=f->prev;o,f->tip;o,f=f->prev)o,mate(f)->tip=u;
for(oo,f=e->link,k=v->deg;f;o,f=f->link)
k+=2,undelete(mate(f)),undelete(f);
oo,v->deg=k-u->deg;
if(extraverbose)
printf("level %d: Unshrinking %d; now %s has degree %d\n",
l,e->len,v->name,v->deg);/*:11*/
#line 191 "grayspan.w"
;/*12:*/
#line 270 "grayspan.w"
if(o,u->deg==1){
if(extraverbose)printf("level %d: %d is a bridge with endpoint %s\n",
l,e->len,u->name);
goto bridge;
}
if(o,e->link->link){
if(extraverbose)printf("level %d: %d is parallel to %d\n",
l,e->len,e->link->len!=e->len?e->link->len:e->link->link->len);
goto nonbridge;
}
for(o,u->bfs=v,w=u;u!=v;o,u=u->bfs){
for(oo,f=u->arcs->next;o,f->tip;o,f=f->next)
if(o,f->tip->bfs==NULL){
if(f->tip==v){
if(f!=mate(e))/*13:*/
#line 296 "grayspan.w"
{
for(o,u=e->tip;u!=v;o,u->bfs=NULL,u=w)o,w=u->bfs;
goto nonbridge;
}/*:13*/
#line 284 "grayspan.w"
;
}else oo,f->tip->bfs=v,w->bfs=f->tip,w=f->tip;
}
}
if(extraverbose)printf("level %d: %d is a bridge\n",l,e->len);
for(o,u=e->tip;u!=v;o,u->bfs=NULL,u=w)o,w=u->bfs;
goto bridge;
nonbridge:change_e=e;/*14:*/
#line 302 "grayspan.w"
if(extraverbose)printf("level %d: deleting %d\n",l,e->len);
ooo,e->link=del(l),del(l)=e;
delete(e),delete(mate(e)),oo,e->tip->deg--,v->deg--;
goto enter;/*:14*/
#line 292 "grayspan.w"
;
bridge:/*:12*/
#line 192 "grayspan.w"
;/*15:*/
#line 308 "grayspan.w"
for(o,e=del(l);e;o,e=e->link){
oooo,mate(e)->tip->deg++,e->tip->deg++,undelete(mate(e)),undelete(e);
if(extraverbose)printf("undeleting %d\n",e->len);
}/*:15*/
#line 193 "grayspan.w"
;
}/*:7*/
#line 41 "grayspan.w"
;
printf("Altogether %.15g spanning trees, using %.15g mems.\n",count,mems);
exit(0);
}/*:1*/
  • 2
    There's nothing wrong with that `#define`. So the issue has to be later in the code when the define is actually used. – user3386109 Oct 12 '15 at 23:15
  • please post the actual contents of `grayspan.c`. Then we can relate the warning messages to the actual c code. One thing to keep in mind is that the 'knuth' products are several decades old and modern c compilers are a lot smarter than they were back then. – user3629249 Oct 12 '15 at 23:53
  • grayspan.c has been uploaded to http://www.squaring.net/polygons/grayspan.c – Stuart Anderson Oct 13 '15 at 00:00
  • And you expect to open an unknown external link? Edit your question's and add a [mcve]! – too honest for this site Oct 13 '15 at 01:09
  • You seem to misunderstand the question. This is Donald Knuth's program, not mine. The program is a complete piece of work, I am not sure how I would minimise it. The 'external link' is to a text file, ascii code, like html - pretty harmless! – Stuart Anderson Oct 13 '15 at 01:39
  • given this warning as an example: "grayspan.w:55:1: warning: format ‘%d’ expects argument of type ‘int’, but argument 4 has type ‘long int’ [-Wformat=] argv[1],panic_code);" `panic_code` is a 'long int' so the forth parameter in the associated statement: ` fprintf(stderr, "Sorry, can't create the graph from file %s! (error code %d)\n", argv[1],panic_code);` should be `%ld` rather than `%d` Most of the other warning messages are of a similar nature. Suggest fix all those simple warnings, then add the updated code to the question. – user3629249 Oct 13 '15 at 03:04
  • I just spent the last 2+ hours going through the .w and .c files. There are LOTS of syntax problems and poor programming practices exhibited in those files. Suggest comment out all the `#line` statements so the error/warnings are directed toward the .c file, then fix all those warnings. – user3629249 Oct 13 '15 at 03:07
  • our friend Knuth, is a very very good source for algorithms. However, as you have found out, not so good for actual code. The C language has massively changed since back when Knuth was writing pseudo code and converters to change that pseudo code to any of several different languages – user3629249 Oct 13 '15 at 03:10
  • @user3629249 Not so much of a substance had changed in the C language. Knuth's programs are a little bit bit-rotten (less than one would expect for programs of that age) but otherwise quite workable. See my answer. – oakad Oct 13 '15 at 03:26
  • For posterity, here is a short guide I wrote while trying to figure out how to run Don's programs, as someone who is rather computer-illiterate. Hope it helps someone: https://docs.google.com/document/d/1ZRgDA6G0e9RHAOeUG8Ldy2hGIlZccQy5QTiJ_Jf-8ME/ – ho boon suan Oct 25 '22 at 07:29

1 Answers1

2

First, you will need the Stanford graph base (http://ftp.cs.stanford.edu/pub/sgb/sgb.tar.gz) and ctangle (part of Tex Live package on most Linux distros) installed.

Unzipping the SGB and running make tests in its directory will produce the necessary include and source files (should work out of the box on any decent Linux).

Put grayspan.w into the SGB directory. Invoke ctangle on it to obtain the grayspan.c.

You may need to use a text editor to replace all occurrences of word "verbose" in grayspan.c with something else ("overbose" or something). This is because gb_graph.h now defines a global variable named "verbose". However, if everything is done as described hereby, this should not be necessary.

Invoke

gcc -m32 -o grayspan grayspan.c gb_graph.c gb_save.c gb_io.c

You will get a certain deal of non-critical warnings (easy to fix if you care) and a working "grayspan" program.

oakad
  • 6,945
  • 1
  • 22
  • 31
  • thanks for the info on the latest version of the pseudo code converter for C. and especially on the detail about the tool/header files defining `verbose` – user3629249 Oct 13 '15 at 03:48
  • Thanks you,yes that worked. I also needed to 'sudo apt-get install libc6-dev-i386' [http://stackoverflow.com/questions/23498237/compile-program-for-32bit-on-64bit-linux-os-causes-fatal-error] – Stuart Anderson Oct 13 '15 at 04:06
  • The program was clearly developed for 32b platform, so working 32b setup is implied. – oakad Oct 13 '15 at 04:08