k&r Ex1-24 without stack

E

El kroty

Hi folks!! i'm trying to write k&r ex1-24 without a stack.
I almost have it but there's a bug that makes me crazy and
can't find it :'( whit some files it works and with others
it doesn't. Here is the code, any clues?? Thanks.

<code>
#include <stdio.h>
#include <stdlib.h>

enum states { FREE, INQUOTE, INCOMMENT, SLASH, ASTERISK, SCAPE };

int
main(void)
{
int quotes = 0;
int parenth = 0, bracket = 0, brace = 0, comment = 0;
char c;
enum states state = FREE;

while ((c = getchar()) != EOF) {
switch (c) {
case '/':
if (state == FREE)
state = SLASH;
else if (state == ASTERISK) {
comment--;
state = FREE;
}
break;
case '*':
if (state == INCOMMENT)
state = ASTERISK;
else if (state == SLASH) {
state = INCOMMENT;
comment++;
}
break;
case '"':
case '\'':
if (state == SCAPE)
state = INQUOTE;
else if (state == FREE) {
state = INQUOTE;
quotes++;
} else if (state == INQUOTE) {
state = FREE;
quotes++;
}
break;
case '(':
if (state == FREE)
parenth++;
break;
case ')':
if (state == FREE)
parenth--;
break;
case '[':
if (state == FREE)
bracket++;
break;
case ']':
if (state == FREE)
bracket--;
break;
case '{':
if (state == FREE)
brace++;
break;
case '}':
if (state == FREE)
brace--;
break;
case '\\':
if (state == INQUOTE)
state = SCAPE;
else if (state == SCAPE)
state = INQUOTE;
break;
default:
if (state == SLASH)
state = FREE;
else if (state == ASTERISK)
state = INCOMMENT;
else if (state == SCAPE)
state = INQUOTE;
}
}

if (comment != 0)
printf("Missing \'/*\' or \'*/\' in comment.\n");
if ((quotes % 2) != 0)
printf("Missing quotes.\n");
if (parenth != 0)
printf("Missing parentheses.\n");
if (bracket != 0)
printf("Missing brackets.\n");
if (brace != 0)
printf("Missing braces.\n");

exit(EXIT_SUCCESS);
}
</code>
 
E

Eric Sosman

El said:
Hi folks!! i'm trying to write k&r ex1-24 without a stack.
I almost have it but there's a bug that makes me crazy and
can't find it :'( whit some files it works and with others
it doesn't. Here is the code, any clues?? Thanks.

My ancient copy of K&R only goes as high as 1-23,
so I don't know quite what you're trying to do. One of
your problems, though, is the topic of Question 12.1 in
the comp.lang.c Frequently Asked Questions (FAQ) list

http://www.eskimo.com/~scs/C-faq/top.html

There may, of course, be other difficulties as well.
 
M

Merrill & Michele

Eric Sosman wrote:
My ancient copy of K&R only goes as high as 1-23,
so I don't know quite what you're trying to do. One of
your problems, though, is the topic of Question 12.1 in
the comp.lang.c Frequently Asked Questions (FAQ).

K&R2 ex 1-24: Write a program to check a C program for rudimentary syntax
errors like unbalanced parentheses, brackets and braces. Don't forget about
the quotes, both single and double, escape sequences, [sic] and comments.
(This program is hard to do in full generality.)

I think it's ironic that an exercise to detect rudimentary errors contains
the first English error I've read from K&R. ( A comma can precede the
terminal 'and' in a list or not, but the style MUST remain consistent.)

As far as getting this with or without a stack, my only contribution will be
to state the exercise clearly. MPJ
 
D

Daniel Fischer

Merrill said:
As far as getting this with or without a stack, my only contribution will
be to state the exercise clearly.

#include "weak joke involving 'the state of the machine'"


Daniel
 
H

Herbert Rosenau

Hi folks!! i'm trying to write k&r ex1-24 without a stack.
I almost have it but there's a bug that makes me crazy and
can't find it :'( whit some files it works and with others
it doesn't. Here is the code, any clues?? Thanks.

<code>
#include <stdio.h>
#include <stdlib.h>

enum states { FREE, INQUOTE, INCOMMENT, SLASH, ASTERISK, SCAPE };

int
main(void)
{
int quotes = 0;
int parenth = 0, bracket = 0, brace = 0, comment = 0;
char c;

Bug!

getchar returns int not char.
enum states state = FREE;

while ((c = getchar()) != EOF) {
switch (c) {
case '/':
if (state == FREE)
state = SLASH;
else if (state == ASTERISK) {
comment--;
state = FREE;
}
break;
case '*':
if (state == INCOMMENT)
state = ASTERISK;
else if (state == SLASH) {
state = INCOMMENT;
comment++;
}
break;
case '"':
case '\'':
if (state == SCAPE)
state = INQUOTE;
else if (state == FREE) {
state = INQUOTE;
quotes++;
} else if (state == INQUOTE) {
state = FREE;
quotes++;
}
break;
case '(':
if (state == FREE)
parenth++;
break;
case ')':
if (state == FREE)
parenth--;
break;
case '[':
if (state == FREE)
bracket++;
break;
case ']':
if (state == FREE)
bracket--;
break;
case '{':
if (state == FREE)
brace++;
break;
case '}':
if (state == FREE)
brace--;
break;
case '\\':
if (state == INQUOTE)
state = SCAPE;
else if (state == SCAPE)
state = INQUOTE;
break;
default:
if (state == SLASH)
state = FREE;
else if (state == ASTERISK)
state = INCOMMENT;
else if (state == SCAPE)
state = INQUOTE;
}
}

if (comment != 0)
printf("Missing \'/*\' or \'*/\' in comment.\n");
if ((quotes % 2) != 0)
printf("Missing quotes.\n");
if (parenth != 0)
printf("Missing parentheses.\n");
if (bracket != 0)
printf("Missing brackets.\n");
if (brace != 0)
printf("Missing braces.\n");

exit(EXIT_SUCCESS);
}
</code>
 
P

Peter Shaggy Haywood

Groovy hepcat Merrill & Michele was jivin' on Thu, 21 Oct 2004
11:36:38 -0500 in comp.lang.c.
Re: k&r Ex1-24 without stack's a cool scene! Dig it!
I made no joke, Junge; you're OT. MPJ

No, no, Daniel made the joke, and one alluding to the way (or *a*
way, at least) to do the parsing required to check for syntax errors.
And humour is always on topic. :)

--

Dig the even newer still, yet more improved, sig!

http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
 
D

Dave Thompson

Hi folks!! i'm trying to write k&r ex1-24 without a stack.
I almost have it but there's a bug that makes me crazy and
can't find it :'( whit some files it works and with others
it doesn't. Here is the code, any clues?? Thanks.

Aside from some minor points marked below and the (char)EOF issue
noted already -- which is only a problem on some platforms, and
obviously not yours or it would always hang -- I don't see any
problems. There are of course some errors you can make it doesn't
catch, but that's inherent in the stated problem/requirement. Can you
give a minimal or at least small test case on which it falsely reports
an error, or fails to report an error (you think) it should catch?
switch (c) {
case '/':
if (state == FREE)
state = SLASH;
else if (state == ASTERISK) {
comment--;
state = FREE;
}
break;
case '*':
if (state == INCOMMENT)
state = ASTERISK;
else if (state == SLASH) {
state = INCOMMENT;
comment++;
}
break;

Your variable 'comment' looks like it is trying to count nesting
level, but C comments don't nest and your state machine correctly
implements that, so the variable is essentially redundant.
case '"':
case '\'':
if (state == SCAPE)
state = INQUOTE;
else if (state == FREE) {
state = INQUOTE;
quotes++;
} else if (state == INQUOTE) {
state = FREE;
quotes++;
}
break;

You won't catch a mismatch of "..' or '..". That is arguably not a
"rudimentary" error, but can be handled by a straightforward extension
of what you have already.
case '(':
if (state == FREE)
parenth++;
break;
case ')':
if (state == FREE)
parenth--;
break;
case '[':
if (state == FREE)
bracket++;
break;
case ']':
if (state == FREE)
bracket--;
break;
case '{':
if (state == FREE)
brace++;
break;
case '}':
if (state == FREE)
brace--;
break;
case '\\':
if (state == INQUOTE)
state = SCAPE;
else if (state == SCAPE)
state = INQUOTE;
break;
default:
if (state == SLASH)
state = FREE;
else if (state == ASTERISK)
state = INCOMMENT;
else if (state == SCAPE)
state = INQUOTE;
}
}

if (comment != 0)
printf("Missing \'/*\' or \'*/\' in comment.\n");

You don't need to escape ' in a "string", although it is legal if you
want to. The only situation 'comment != 0' can detect given the state
machine above is a final open /* with no */, so the output might more
accurately be something like "Unclosed comment". And you could drop
the variable and just check state == COMMENT or == ASTERISK.
if ((quotes % 2) != 0)
printf("Missing quotes.\n");

Again state == INQUOTE or == SCAPE would be as good.
if (parenth != 0)
printf("Missing parentheses.\n");
if (bracket != 0)
printf("Missing brackets.\n");
if (brace != 0)
printf("Missing braces.\n");
I would describe these as "mismatched". It could be an open for which
the close is missing, or an "extra" or "stray" open that shouldn't be
there in the first place; or vice versa.

- David.Thompson1 at worldnet.att.net
 

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

Similar Threads

K&R 1-24 15
Fibonacci 0
Command Line Arguments 0
K$R xrcise 1-13 (histogram) 4
Qsort() messing with my entire Code 0
Dont work, it´s something whit the loops? 1
K&R 5-10 11
K&R Exercise 1-21: entab 10

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,015
Latest member
AmbrosePal

Latest Threads

Top