Without semicolons

J

Jeremy Yallop

Write a program that takes a C program in source form as input and
prints the source code for a program with equivalent behaviour, but
without semicolons, on standard output.

Please note that I'm not interested in the DMS Software Reengineering
Toolkit.

Jeremy.
 
C

Chris McDonald

Jeremy Yallop said:
Write a program that takes a C program in source form as input and
prints the source code for a program with equivalent behaviour, but
without semicolons, on standard output.
Please note that I'm not interested in the DMS Software Reengineering
Toolkit.


Yes sir, I'll get on to writing this program straight away.
I'm not interested in the DMS Software Reengineering Toolkit, either.

Chris.
 
M

Martin Johansen

int main(int x, char *t[]){if(puts(t[1])){}}

compile to file 'a' and run this in your command line

a "the source goes here"
 
J

Jeremy Yallop

Chris said:
Yes sir, I'll get on to writing this program straight away.
I'm not interested in the DMS Software Reengineering Toolkit, either.

If you were to search the archives (or lurk for a while) in order to
establish some context, you might be less inclined to post such rude
(and absurd) responses.

Jeremy.
 
J

Jeremy Yallop

Martin said:
int main(int x, char *t[]){if(puts(t[1])){}}

compile to file 'a' and run this in your command line

a "the source goes here"

I have no idea why you think this is a solution.

Jeremy.
 
S

Sam Dennis

Jeremy said:
Write a program that takes a C program in source form as input and
prints the source code for a program with equivalent behaviour, but
without semicolons, on standard output.

There is one really serious problem with that, other than string
literals and character constants (and being a stupid idea in the
first place): declarations are terminated with a semi-colon.
 
J

Jeremy Yallop

Sam said:
There is one really serious problem with that, other than string
literals and character constants (and being a stupid idea in the
first place): declarations are terminated with a semi-colon.

String literals and character constants are not a problem if you don't
mind restricting yourself to a particular character set. Declarations
are admittedly rather difficult to handle, but by no means impossible.
Here are a couple of clues:

int foo()
{
int x = 3;
float y = 2.0;
...
return something;
}

can be transformed to

void foo_helper(int x, float y, int *rv)
{
...
if (*rv = something) { }
}

void foo(int *rv)
{
if (foo_helper(3, 2.0, rv)) { }
}

It might appear that a (non-definition) declaration is required for at
least one of two mutually recursive functions, but that's not the
case:

void one()
{
if (((void (*)())two)(), 0) { }
}

void two()
{
if (one(), 0) { }
}

I'm pretty sure that it can be done, although I welcome
counterexamples. I'm sorry that you thought the problem was stupid; I
thought it was considerably more interesting than the usual "without
using a semicolon" sort of questions that come up fairly frequently,
and (if solved) it has the additional advantage of making it
unnecessary to ever have to think of answers to those questions again.

I think that a program I'm working on now will be able to solve the
problem (and many others) when finished, by the way, but it's not
written in C and it won't be ready for a couple of months at least.

Jeremy.
 
C

Chris McDonald

If you were to search the archives (or lurk for a while) in order to
establish some context, you might be less inclined to post such rude
(and absurd) responses.


I read this newsgroup everyday.
What possible context is there?
Please explain how the directive to write such a program should be obeyed
by our readers.

The initial request is the absurb matter.
 
J

Jeremy Yallop

Chris said:
I read this newsgroup everyday.
What possible context is there?
Please explain how the directive to write such a program should be obeyed
by our readers.

Could we talk about C, instead, please?

Jeremy.
 
J

Jeremy Yallop

Chris said:
I read this newsgroup everyday.
What possible context is there?
Please explain how the directive to write such a program should be obeyed
by our readers.

Could we talk about C instead, please?

Jeremy.
 
A

Arthur J. O'Dwyer

It might appear that a (non-definition) declaration is required for at
least one of two mutually recursive functions, but that's not the
case:

void one()
{
if (((void (*)())two)(), 0) { }

I don't think this does what you think it does. I *think* (pretty
strongly, but not entirely positive) that it implicitly declares
'two' as an 'int', and then tries to cast that 'int' to 'void(*)()'.
What you really meant to do was declare 'two' as a 'void(*)()', and
I think you might not be able to do that.
So, expert opinions needed on this, and also on this "solution":

void declare_voidCpDCD(void (*x)()) {}

void one()
{
if (declare_voidCpDCD(two), two(), 0) {}
}

Does the passing of 'two' to a function expecting a given type
implicitly declare 'two' with that type?

I'm pretty sure that it can be done, although I welcome
counterexamples. I'm sorry that you thought the problem was stupid; I
thought it was considerably more interesting than the usual "without
using a semicolon" sort of questions that come up fairly frequently,
and (if solved) it has the additional advantage of making it
unnecessary to ever have to think of answers to those questions again.
:-D

I think that a program I'm working on now will be able to solve the
problem (and many others) when finished,

This program isn't called the Analytical Engine, by any chance? ;)

-Arthur
 
S

Sam Dennis

Jeremy said:
It might appear that a (non-definition) declaration is required for at
least one of two mutually recursive functions, but that's not the
case:

....in C89. Implicit function declarations were removed for C99.
(Besides, I'm pretty sure that even in C89 you couldn't cast any
undeclared identifier and then call it as a function; it appears
that it may be solvable in C89 by other means, though. Wrappers
are your friends here, if you really want to spend as many hours
of your life as this will indubitably take to accomplish without
any gaps on such a project.)
 
C

CBFalconer

Chris said:
I read this newsgroup everyday. What possible context is there?

There is a poster, who shall remain nameless, who pops up
periodically to flog the aforementioned Toolkit as the solution to
various problems. He never has any other comments or knowledge to
offer. That was a joke son, which you failed to recognize and
converted into a flame.
 
J

Jeremy Yallop

Arthur said:
I don't think this does what you think it does. I *think* (pretty
strongly, but not entirely positive) that it implicitly declares
'two' as an 'int', and then tries to cast that 'int' to 'void(*)()'.

It's worse than that: it's just a plain error. "Implicit int" refers
to variable declarations without a type specifier, such as

static x;

As Sam Dennis points out, you can't use an undeclared identifier in
this context.
What you really meant to do was declare 'two' as a 'void(*)()', and
I think you might not be able to do that.
So, expert opinions needed on this, and also on this "solution":

void declare_voidCpDCD(void (*x)()) {}

void one()
{
if (declare_voidCpDCD(two), two(), 0) {}
}

Does the passing of 'two' to a function expecting a given type
implicitly declare 'two' with that type?

Unfortunately not: any undeclared identifier used as a function
designator is implicitly declared as returning int. I've realised
since I wrote the post you're replying to that implicit declaration
won't work at all here, since it can only be used for functions
returning int.
This program isn't called the Analytical Engine, by any chance? ;)

Heh. That's not a bad name, actually. It's intended to be used for
general syntactic analysis (and transformations) of C source code;
basically a fancy parser with a bunch of hooks. I'm happy to say,
though, that its completion isn't dependent on the support of the
British government.

Jeremy.
 
G

Grumble

Jeremy said:
If you were to search the archives (or lurk for a while) in order
to establish some context, you might be less inclined to post such
rude (and absurd) responses.

"Yes sir, I'll get on to writing this program straight away." is
rude?!? You, my friend, seem to lack perspective.
 
T

Thomas Matthews

Jeremy said:
Write a program that takes a C program in source form as input and
prints the source code for a program with equivalent behaviour, but
without semicolons, on standard output.

Please note that I'm not interested in the DMS Software Reengineering
Toolkit.

Jeremy.

The answer has been posted here many times.
Please search the newsgroups for "without" and "semicolon".

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book
http://www.sgi.com/tech/stl -- Standard Template Library
 
C

Case

Jeremy said:
Write a program that takes a C program in source form as input and
prints the source code for a program with equivalent behaviour, but
without semicolons, on standard output.

Replace all semicolons with NOT_A_SEMICOLON between some white space
and compile with the appropriate-something-like -DNOT_A_SIMICOLON=;
flag :)

Or is this not funny?

Case
 
M

Martin Dickopp

Case said:
Replace all semicolons with NOT_A_SEMICOLON between some white space
and compile with the appropriate-something-like -DNOT_A_SIMICOLON=;
flag :)

A compiler invoked with such a flag is *not* a conforming C
implementation.

Martin
 
A

Arthur J. O'Dwyer

I don't think this does what you think it does. I *think* (pretty
strongly, but not entirely positive) that it implicitly declares
'two' as an 'int', and then tries to cast that 'int' to 'void(*)()'.

It's worse than that: it's just a plain error. [snip]
As Sam Dennis points out, you can't use an undeclared identifier in
this context.

said:
Unfortunately not: any undeclared identifier used as a function
designator is implicitly declared as returning int.

<slaps your forehead> ;) No, I wasn't thinking again. This code
suffers from the same problem Sam Dennis showed with your code ---
'two' is undeclared in the first place it appears. That's a
syntax error. Still, we could write

if (0, two()) {}
if (((void(*)())two)(), 0) {}

and I believe the code would be strictly conforming. Or even:

if (sizeof two(), ((void(*)())two)(), 0) {}

Both of these implicitly declare 'two' as a function (of whatever
type), and then we cast the value of 'two' to the correct function
pointer type before we actually call it.

But the original problem, mutual recursion, is much easier
anyway:

void one(void (*two)()) {
if (two(one), 0) {}
}

void two(void (*one)()) {
if (one(two), 0) {}
}

int main(void) {
if (one(two), 0) {}
}

We were just trying to over-complicate things. :)
-Arthur
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top