How to convert Infix notation to postfix notation

S

spinoza1111

It really makes the regs (and, most especially, the reg-wannabees like
Mr. Streater here) nervous to be seen as in any way requesting anything
(other than order-in-the-court, of course).  That is, it destroys their
game to be seen as being in the position of asking for something as
opposed to always being the givers of knowledge.

Notice the recent hoo-hah about whether or not Kiki/RH had requested
anything from Jacob.  Notice how much virtual ink was expended
discussing what was, in fact, just a small, jocular, off-the-cuff remark
from Jacob.

Kiki was obviously much distressed by both of the following
implications, and spared no effort to try to dispel both:

    1) That they (Kiki and/or RH) had requested something from lowly Jacob.
    2) That, in response to and in fulfillment of said request, Jacob
        had actually, out of the goodness of his heart, produced something
        of value.- Hide quoted text -

- Show quoted text -

The least competent people here (Richard Heathfield, Peter Seebach,
and possibly Keith Thompson) have of course to maintain that they are
the most competent, but in fact they are at best only sources of good
advice on low-level code details AT BEST, and stunted by their
"knowledge". It's a real toxic inversion. If John Nash were to post
here anonymously, they'd kick the shit out of him because they're
thugs, and I hope to see the lot of them brought up on charges.

They've managed to reproduce the worst aspects of the corporate world:
the well-known technical inversions (where the worst technicians
become even worse managers), the bullying, the cover-ups and the
office politics. They have in fact very little interest in or passion
for technology.

In the 1970s, technology actually escaped the general filth and curse
because relationships of dominance and control hadn't been
established, but they have been re-established. Therefore these
animals use this newsgroup to play at the only thing they are really
any good at: hurting people, causing confusion, sowing hatred, and
starting fights which they're too cowardly to finish: for when a real
man fights back he discovers them claiming fashionable disorders and
calling him the bully.
 
S

spinoza1111

In

spinoza1111wrote:
// parser for gramar:
// expr -> term { [+-] term }
// term -> factor { [*/] factor }
Again it looks like you stole this,

It's a minor re"word"ing of p72 of the Dragon Book [Aho, Sethi, Ullman
1986].

1986? That edition is out of date, as you are. But I should have
looked at my second edition.

It's not there. Furthermore, Aho et al. use curley brackets not for
syntax but for semantic actions.

The grammar is messed up but the code looks correct: the grammar as
far as I can see doesn't accept 1+1+1 but the code does.

I'll run the code and back but not to you.
 
S

spinoza1111

i have a string as (a+b)+8-(c/d) in Infix form.
how can i convert it to postfix form using C language,,,????
I suppose that if this is homework, the due date has passed.
// Convert ;-separated infix expressions on stdin to postfix on
stdout.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
// error handler
void die(char *msg)
{
  fprintf(stderr, "\ndie: %s\n", msg);
  exit(1);
}
// scanner
int lookahead;
int peek() { return lookahead; }
int peek_is(char *set)
{
  return strchr(set, peek()) != NULL;
}
void advance(void)
{
  do lookahead = getchar(); while (isspace(lookahead));
}
// parser for gramar:
// expr -> term { [+-] term }
// term -> factor { [*/] factor }
// factor -> ALNUM | "(" expr ")"
void term(void);
void factor(void);
void expr(void)
{
  term();
  while (peek_is("+-")) {
    int op = peek();
    advance();
    term();
    printf("%c", op);
  }
}
void term(void)
{
  factor();
  while (peek_is("*/")) {
    int op = peek();
    advance();
    factor();
    printf("%c", op);
  }
}
void factor(void)
{
  if (isalnum(peek())) {
    int literal = peek();
    advance();
    printf("%c", literal);
  }
  else if (peek() == '(') {
    advance();
    expr();
    if (!peek_is(")")) die("expected )");
    advance();
  }
  else
    die("expected factor");
}
// user interface
int main(void)
{
  advance();
  do {
    expr();
    if (!peek_is(";")) die("expected ;");
    printf("\n");
    advance();
  } while (peek() != EOF);
  return 0;
}- Hide quoted text -
- Show quoted text -
Thanks for this. Looks like you stole my approach, but I find that
most gratifying if true, and an indication that "great minds think
alike" if not. Your contribution at a minimum is to show just how
gnomic and terse one can be in C. It would not be appropriate to
credit me since it is a common and solid algorithm that has been
around for years.
Hope you don't mind, but I'm going to copy this code and incorporate
it in what will not be a three way test: of my C Sharp version, my C
version and your gnomic C. I want to add more testing (using a random
generator in C Sharp), a GUI and timing comparisions and shall report
back.- Hide quoted text -

This doesn't qualify as anything like theft or great thinking. For

It's better than anything Heathfield, Thompson or Seebach could do.
But I think you messed up the grammar...but not the code.

expr -> term { [+-] term }

doesn't parse 1+1+1.
 
G

Gene

i have a string as (a+b)+8-(c/d) in Infix form.
how can i convert it to postfix form using C language,,,????
I suppose that if this is homework, the due date has passed.
// Convert ;-separated infix expressions on stdin to postfix on
stdout.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
// error handler
void die(char *msg)
{
  fprintf(stderr, "\ndie: %s\n", msg);
  exit(1);
}
// scanner
int lookahead;
int peek() { return lookahead; }
int peek_is(char *set)
{
  return strchr(set, peek()) != NULL;
}
void advance(void)
{
  do lookahead = getchar(); while (isspace(lookahead));
}
// parser for gramar:
// expr -> term { [+-] term }
// term -> factor { [*/] factor }
// factor -> ALNUM | "(" expr ")"
void term(void);
void factor(void);
void expr(void)
{
  term();
  while (peek_is("+-")) {
    int op = peek();
    advance();
    term();
    printf("%c", op);
  }
}
void term(void)
{
  factor();
  while (peek_is("*/")) {
    int op = peek();
    advance();
    factor();
    printf("%c", op);
  }
}
void factor(void)
{
  if (isalnum(peek())) {
    int literal = peek();
    advance();
    printf("%c", literal);
  }
  else if (peek() == '(') {
    advance();
    expr();
    if (!peek_is(")")) die("expected )");
    advance();
  }
  else
    die("expected factor");
}
// user interface
int main(void)
{
  advance();
  do {
    expr();
    if (!peek_is(";")) die("expected ;");
    printf("\n");
    advance();
  } while (peek() != EOF);
  return 0;
}- Hide quoted text -
- Show quoted text -
Thanks for this. Looks like you stole my approach, but I find that
most gratifying if true, and an indication that "great minds think
alike" if not. Your contribution at a minimum is to show just how
gnomic and terse one can be in C. It would not be appropriate to
credit me since it is a common and solid algorithm that has been
around for years.
Hope you don't mind, but I'm going to copy this code and incorporate
it in what will not be a three way test: of my C Sharp version, my C
version and your gnomic C. I want to add more testing (using a random
generator in C Sharp), a GUI and timing comparisions and shall report
back.- Hide quoted text -
This doesn't qualify as anything like theft or great thinking. For

It's better than anything Heathfield, Thompson or Seebach could do.
But I think you messed up the grammar...but not the code.

expr -> term { [+-] term }

doesn't parse 1+1+1.


fun, I wrote the code in about 5 minutes after the OP posted (based onhttp://groups.google.com/group/comp.lang.c/msg/fe772c9d6a28fdc4), but
refrained from posting it because it was probably homework for the
OP.  This is a standard example or homework assignment for just about
any undergrad course that covers recursive descent parsing.  The
gramamr with minor variations is in at least a dozen complier design
textbooks including ASU. Usually it's given in left-recursive form,
and then the author or student go through the L-rec removal, left-
factoring, and BNF conversion.  RPN generation is a trivial example of
attribute evaluation.- Hide quoted text -

The curly braces are BNF for zero or more repeats. This translates to
the while loop. I can't see an error.
 
B

Ben Bacarisse

spinoza1111 said:
But I think you messed up the grammar...but not the code.

expr -> term { [+-] term }

doesn't parse 1+1+1.

The {} is a very common notation. I agree that [+-] is not usual, but were
you at all puzzled by what the notation meant? It is obviously
borrowed from regular expressions.

Wirth would have written:

expr = term { ("+"|"-") term } .

and in plain EBNF one would write

expr = term | { "+" , term } | { "-" , term } ;

both of which are a bit clumsy. I found Gene's shorthand quite clear.

<snip>
 
S

spinoza1111

But I think you messed up the grammar...but not the code.
expr -> term { [+-] term }
doesn't parse 1+1+1.

The {} is a very common notation.  I agree that [+-] is not usual, but were
you at all puzzled by what the notation meant?  It is obviously
borrowed from regular expressions.

OK, that's correct: [+-] is "the set of characters including plus and
minus" where one character is chosen from the set. But I shouldn't
have to do the work of expressing things clearly on your behalf in
English.

Nor should regular expression notation be mixed into BNF unless
absolutely necessary.

But in neither notation do curley braces imply iteration and as far as
I can see you need iteration to parse 1+1+1. What am I missing, dear
Ben?
Wirth would have written:

  expr = term { ("+"|"-") term } .

and in plain EBNF one would write

  expr = term | { "+" , term } | { "-" , term } ;

both of which are a bit clumsy.  I found Gene's shorthand quite clear.

They both look wrong (and note that unlike some of the thugs and
twerps here I don't infer your global ignorance). Period ordinarily
means end of string (which is needed as I have said when you do not
lookahead to balance parentheses)....not iteration.

The second is in particular absurd. If by | you mean BNF or, then
you're saying that an expr may start with a plus sign. If you add
unary minus it may but I do not believe this was your intent. I think
you either have a private BNF notation, Bacarisse Normal Form, or you
don't know how to use BNF at all.

Here is the correct BNF as far as I can tell:

expr := addFactor
expr := addFactor ( [+-] addFactor ) *

As a favor to you I use the square bracket set notation and instead of
square brackets for optional sequence I've split the production into
two parts, using round parentheses to group and asterisk to iterate.

This is a correct grammar which cannot be used to generate a parser as
is:

expr := addFactor
expr := addFactor [+-] expr

If you get rid of recursion on the right, it must be replaced with
iteration, and you need an operator for iteration. I've taken asterisk
from regular expressions (which shouldn't be confused with BNF) to
express iteration.

With all due respect, Ben, and I mean this sincerely, you don't appear
to me to understand either regular expressions or BNF independent of
their corruption by programmers.
 
S

spinoza1111

Seebs as commented on the code in detail, so I'll just add that you
need more work on some error cases.  Despite a lot of unnecessary
counting of parentheses, cases like "1)" and "(((0))))" are silently
ignored.

Thanks, Ben, I have confirmed that the C version of the code fails for
these cases but that the latest C Sharp does not. Therefore I have
more work to do!

I would advise you, however, to use "I think" more often as an
operator. When you make positive statements but without enough detail
for the thugs and the twerps here to know to which version you refer
to, the thugs and twerps think these are new error reports about the
old code and in general they have a distinct tendency (seen in "C: The
Complete Nonsense") to increase error counts by a couple orders of
magnitude, both because they are thugs and twerps, and also because
they can't tell the difference between a fact and a report of a fact.

Be more "verbose". I am "verbose" because I am trying not to accuse
people of falsehoods and this is even true when I am calling people
"assholes" in a legitimate self-defemse.

I appreciate your insights but I retain the right to defend myself.
Also, I think it would be better to try to detect all input that can't
be converted.  For example, "&" gives an error, but "1&2" does not.

In order to be positive, I'll stick my neck out and post my solution.
No one has posted the classic operator priority parsing algorithm, so
this solution is new in the thread.  The code is simpler than the code
you get from turning grammar rules directly into paring functions,
although the benefit is certainly borderline for expressions with only
two priorities.  I've added an extra, high priority, operator (^) to
illustrate the algorithm's generality.

All the work heavy is done in one function (convert_operators in the
code below) that parses sequences of terms whose length is determined
by the priority of the operators that are seen.  If these are
determined from a run-time table, you get the advantage of being able
to add and remove operators as well as changing the operator
precedences as the parser runs.

Most of the code is scaffolding and includes an expanding character
buffer to hold the growing output string.  C99 features are used in a
couple of places.

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

/*
 * This type, and the two str_ functions, provide an expanding
 * character buffer to take the growing output string.
 */

typedef struct string string;

void str_add(string *s, char c);
const char *str_string(string *s);

static bool convert_term(const char **s, string *out);
static bool convert_operators(const char **s, int precedence, string *out);
static bool convert_expression(const char **s, string *out);

static char next(const char **s);
static bool expect(const char **s, char c);
static bool missing(const char *what, char where);

/*
 * The grammar is largely specified by this function that determines
 * if a token (in this case a single character) is an operator and,
 * if so, what precedence it has.
 */

static int precedence_of(char op)
{
     static const char *op_table[] = { "+-", "*/", "^", NULL };
     if (op != '\0')
          for (int i = 0; op_table; i++)
               if (strchr(op_table, op))
                    return i;
     return -1; /* not a operator */

}

bool infix_to_postfix(const char *s, string *out)
{
     return convert_expression(&s, out) && expect(&s, '\0');

}

static bool convert_expression(const char **s, string *out)
{
     return convert_term(s, out) && convert_operators(s, 0, out);

}

static bool convert_operators(const char **s, int precedence, string *out)
{
     char op;
     int prec, right_prec;
     while ((prec = precedence_of(op = next(s))) >= precedence) {
          *s += 1;
          if (convert_term(s, out))
               while ((right_prec = precedence_of(next(s))) > prec) {
                    if (!convert_operators(s, right_prec, out))
                         return false;
               }
          else return false;
          str_add(out, op);
          str_add(out, ' ');
     }
     return true;

}

static bool convert_term(const char **s, string *out)
{
     unsigned char c = next(s);
     if (isalpha(c)) {
          str_add(out, c);
          str_add(out, ' ');
          *s += 1;
          return true;
     }
     else if (isdigit(c)) {
          while (isdigit((unsigned char)**s))
               str_add(out, *(*s)++);
          str_add(out, ' ');
          return true;
     }
     else if (c == '(') {
          *s += 1;
          return convert_expression(s, out) && expect(s, ')');
     }
     else return missing("Term", c);

}

static char next(const char **s)
{
     while (isspace((unsigned char)**s)) *s += 1;
     return **s;

}

static bool missing(const char *what, char where)
{
     fprintf(stderr, "%s expected where %s found.\n", what,
             where ? (char []){where, 0} : "end of input");
     return false;

}

static bool expect(const char **s, char c)
{
     if (next(s) != c)
          return missing(c ? (char []){c, 0} : "end of input", **s);
     *s += 1;
     return true;

}

/*
 *  An implementation of an expanding character buffer.
 */

struct string {
     size_t capacity, size;
     char *string;

};

void str_add(string *s, char c)
{
     if (s->size >= s->capacity) {
          size_t new_cap = s->capacity * 3 / 2 + 8;
          char *new_s = realloc(s->string, new_cap);
          if (!new_s) {
               fprintf(stderr, "String add: out of memory\n");
               exit(EXIT_FAILURE);
          }
          s->string = new_s;
          s->capacity = new_cap;
     }
     s->string[s->size++] = c;

}

const char *str_string(string *s)
{
     str_add(s, '\0');
     return s->string;

}

int main(int argc, char *argv[])
{
     bool result = true;
     while (--argc > 0) {
          string postfix = {0};
          if (infix_to_postfix(*++argv, &postfix))
               printf("%s\n", str_string(&postfix));
          else result = false;
          free(postfix.string);
     }
     return result ? EXIT_SUCCESS : EXIT_FAILURE;

}
 
S

spinoza1111

spinoza1111 said:
This post contains the promised C code version of the infix to Polish
notation convertor.

Seebs as commented on the code in detail, so I'll just add that you
need more work on some error cases.  Despite a lot of unnecessary
counting of parentheses, cases like "1)" and "(((0))))" are silently
ignored.

Also, I think it would be better to try to detect all input that can't
be converted.  For example, "&" gives an error, but "1&2" does not.

In order to be positive, I'll stick my neck out and post my solution.
No one has posted the classic operator priority parsing algorithm, so
this solution is new in the thread.  The code is simpler than the code
you get from turning grammar rules directly into paring functions,
although the benefit is certainly borderline for expressions with only
two priorities.  I've added an extra, high priority, operator (^) to
illustrate the algorithm's generality.

All the work heavy is done in one function (convert_operators in the
code below) that parses sequences of terms whose length is determined
by the priority of the operators that are seen.  If these are
determined from a run-time table, you get the advantage of being able
to add and remove operators as well as changing the operator
precedences as the parser runs.

Most of the code is scaffolding and includes an expanding character
buffer to hold the growing output string.  C99 features are used in a
couple of places.

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

/*
 * This type, and the two str_ functions, provide an expanding
 * character buffer to take the growing output string.
 */

typedef struct string string;

void str_add(string *s, char c);
const char *str_string(string *s);

static bool convert_term(const char **s, string *out);
static bool convert_operators(const char **s, int precedence, string *out);
static bool convert_expression(const char **s, string *out);

static char next(const char **s);
static bool expect(const char **s, char c);
static bool missing(const char *what, char where);

/*
 * The grammar is largely specified by this function that determines
 * if a token (in this case a single character) is an operator and,
 * if so, what precedence it has.
 */

static int precedence_of(char op)
{
     static const char *op_table[] = { "+-", "*/", "^", NULL };
     if (op != '\0')
          for (int i = 0; op_table; i++)
               if (strchr(op_table, op))
                    return i;
     return -1; /* not a operator */

}

bool infix_to_postfix(const char *s, string *out)
{
     return convert_expression(&s, out) && expect(&s, '\0');

}

static bool convert_expression(const char **s, string *out)
{
     return convert_term(s, out) && convert_operators(s, 0, out);

}

static bool convert_operators(const char **s, int precedence, string *out)
{
     char op;
     int prec, right_prec;
     while ((prec = precedence_of(op = next(s))) >= precedence) {
          *s += 1;
          if (convert_term(s, out))
               while ((right_prec = precedence_of(next(s))) > prec) {
                    if (!convert_operators(s, right_prec, out))
                         return false;
               }
          else return false;
          str_add(out, op);
          str_add(out, ' ');
     }
     return true;

}

static bool convert_term(const char **s, string *out)
{
     unsigned char c = next(s);
     if (isalpha(c)) {
          str_add(out, c);
          str_add(out, ' ');
          *s += 1;
          return true;
     }
     else if (isdigit(c)) {
          while (isdigit((unsigned char)**s))
               str_add(out, *(*s)++);
          str_add(out, ' ');
          return true;
     }
     else if (c == '(') {
          *s += 1;
          return convert_expression(s, out) && expect(s, ')');
     }
     else return missing("Term", c);

}

static char next(const char **s)
{
     while (isspace((unsigned char)**s)) *s += 1;
     return **s;

}

static bool missing(const char *what, char where)
{
     fprintf(stderr, "%s expected where %s found.\n", what,
             where ? (char []){where, 0} : "end of input");
     return false;

}

static bool expect(const char **s, char c)
{
     if (next(s) != c)
          return missing(c ? (char []){c, 0} : "end of input", **s);
     *s += 1;
     return true;

}

/*
 *  An implementation of an expanding character buffer.
 */

struct string {
     size_t capacity, size;
     char *string;

};

void str_add(string *s, char c)
{
     if (s->size >= s->capacity) {
          size_t new_cap = s->capacity * 3 / 2 + 8;
          char *new_s = realloc(s->string, new_cap);
          if (!new_s) {
               fprintf(stderr, "String add: out of memory\n");
               exit(EXIT_FAILURE);
          }
          s->string = new_s;
          s->capacity = new_cap;
     }
     s->string[s->size++] = c;

}

const char *str_string(string *s)
{
     str_add(s, '\0');
     return s->string;

}

int main(int argc, char *argv[])
{
     bool result = true;
     while (--argc > 0) {
          string postfix = {0};
          if (infix_to_postfix(*++argv, &postfix))
               printf("%s\n", str_string(&postfix));
          else result = false;
          free(postfix.string);
     }
     return result ? EXIT_SUCCESS : EXIT_FAILURE;

}


Looks great. Thank you. I shall incorporate it into a comparative
study with my C Sharp code, my C code, Gene's and now yours. I want to
regression and time test all the code so far. The final result will go
here and on my wordpress blog and you shall be credited. If you would
prefer to be anonymous as in the past please let me know here or by
email.

But the more I relearn about C from experts like you, the more I
wonder why this language is still in use. Perhaps it will be
eradicated in 2038 as much old Cobol was eradicated to prevent Y2K,
since C shall blow us all to kingdom come when its timers overflow in
that year. I shall work out and not drink or smoke to see that happy
day.
 
C

Chris McDonald

spinoza1111 said:
But the more I relearn about C from experts like you, the more I
wonder why this language is still in use. Perhaps it will be
eradicated in 2038 as much old Cobol was eradicated to prevent Y2K,
since C shall blow us all to kingdom come when its timers overflow in
that year. I shall work out and not drink or smoke to see that happy
day.

Which part of the C standard do you believe links C to the year 2038?
 
S

Seebs

Is there a neat way to write it in C that is clearer?

I can't think of one.
I have a background in teaching and have often wrestled with getting
fragments of code to fit on one OHP slide. As a result, I have an
unnatural urge to bracket minimally, but I agree that it is not
obviously the best way to do things.

Ahh, that makes sense.
Yup, but if I commented it, I'd have to justify the 3/2 factor! I do
that for hysterical raisins, more than anything else. If I thought
about it, I'd just double the capacity. The +8 (as I am sure you
spotted) is just a hack to avoid having to treat the initial zero as a
special case. The "code for clarity" version is probably:
size_t new_cap = s->capacity ? 2 * s->capacity : 8;

Actually, I've found 3/2 to be a better choice -- it wastes a lot less
space in most cases. I hadn't thought about the 0 case, just the 1 case
(and the general rule that it's going to be called very often for the
first few bytes).

I once did some kind of messing with an algorithm like this, I think it
was for the buffers used in my "unsort" utility, and ended up on 3/2.

-s
 
S

Seebs

Chris Torek (wherever he's got to)

He's been too busy to post to Usenet. (He's one of my coworkers, and I
actually did remember to pass on that people in CLC remember him.)

-s
 
S

spinoza1111

i have a string as (a+b)+8-(c/d) in Infix form.
how can i convert it to postfix form using C language,,,????
I suppose that if this is homework, the due date has passed.
// Convert ;-separated infix expressions on stdin to postfix on
stdout.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
// error handler
void die(char *msg)
{
  fprintf(stderr, "\ndie: %s\n", msg);
  exit(1);
}
// scanner
int lookahead;
int peek() { return lookahead; }
int peek_is(char *set)
{
  return strchr(set, peek()) != NULL;
}
void advance(void)
{
  do lookahead = getchar(); while (isspace(lookahead));
}
// parser for gramar:
// expr -> term { [+-] term }
// term -> factor { [*/] factor }
// factor -> ALNUM | "(" expr ")"
void term(void);
void factor(void);
void expr(void)
{
  term();
  while (peek_is("+-")) {
    int op = peek();
    advance();
    term();
    printf("%c", op);
  }
}
void term(void)
{
  factor();
  while (peek_is("*/")) {
    int op = peek();
    advance();
    factor();
    printf("%c", op);
  }
}
void factor(void)
{
  if (isalnum(peek())) {
    int literal = peek();
    advance();
    printf("%c", literal);
  }
  else if (peek() == '(') {
    advance();
    expr();
    if (!peek_is(")")) die("expected )");
    advance();
  }
  else
    die("expected factor");
}
// user interface
int main(void)
{
  advance();
  do {
    expr();
    if (!peek_is(";")) die("expected ;");
    printf("\n");
    advance();
  } while (peek() != EOF);
  return 0;
}- Hide quoted text -
- Show quoted text -
Thanks for this. Looks like you stole my approach, but I find that
most gratifying if true, and an indication that "great minds think
alike" if not. Your contribution at a minimum is to show just how
gnomic and terse one can be in C. It would not be appropriate to
credit me since it is a common and solid algorithm that has been
around for years.
Hope you don't mind, but I'm going to copy this code and incorporate
it in what will not be a three way test: of my C Sharp version, my C
version and your gnomic C. I want to add more testing (using a random
generator in C Sharp), a GUI and timing comparisions and shall report
back.- Hide quoted text -
This doesn't qualify as anything like theft or great thinking. For
It's better than anything Heathfield, Thompson or Seebach could do.
But I think you messed up the grammar...but not the code.
expr -> term { [+-] term }
doesn't parse 1+1+1.

The curly braces are BNF for zero or more repeats.  This translates to
the while loop.  I can't see an error.- Hide quoted text -

OK, I can deal with that. Thanks for the clarification. I don't recall
that notation being used by my teacher of compiler design in grad
school but it's been some time.
 
C

Chris McDonald

A lot of people are not aware that time_t is not required to be only 32
bits.

Yes, Ben Pfaff helpfully explained that to me a few months ago,
but I'm waiting for Spinny to either state that Ben was wrong,
or that any intelligent programmer would expect time_t to be 32 bits.
 
N

Nick Keighley

Watching Spinny's train of "logic", I'm reminded of the Soviets'
constant denigration of the West as "warmongers", the rationale for
which which went something like as follows:

1) We are in conflict with you
2) If you were to agree with our point of view, the conflict would cease
3) Since you choose not to take an action which would remove the
conflict, you are actively seeking to prolong the conflict
4) In actively seeking to prolong the conflict, you are therefore a
warmonger

There must be a word which describes this sort of thought process.

invented
 
N

Nick Keighley

As a general rule, your view of other people is informed primarily
by your experience of yourself.

Most people don't lie very often.  The exceptions, though, have the
interesting trait that they think everyone else does it too -- especially
people they dislike.

I've met a couple of "pathological liars" in my time. People who
constantly re-invent their biographical details to such an extent that
not only cridibility but space-time (in the sense that you can't have
three full-time careers *and* beat heroin simultaneously) itself is
strained to breaking point. They can be amusing once you realise what
they are doing. But I hadn't noticed any overt evidence that they
thought other people lied. Maybe they just took it as axiomatic, but
they gave no obvious sign.


<snip>
 
N

Nick Keighley

spinoza1111 wrote:

foo.c:1: stdio.H: No such file or directory
foo.c: In function `stringAppendChar':
foo.c:37: warning: passing arg 1 of `errorHandler' discards qualifiers
from pointer target type
foo.c:54: warning: passing arg 2 of `stringAppendChar' with different
width due to prototype
foo.c:143: warning: no previous prototype for `addFactor'
foo.c:209: warning: no previous prototype for `infix2Polish'
foo.c:221: warning: return discards qualifiers from pointer target
type
foo.c:227: warning: function declaration isn't a prototype
foo.c: In function `tester':
foo.c: In function `main':
foo.c:263: warning: `return' with no value, in function returning
non-void

but if you remove the repeats that's about six problems. Mismatched
prototypes would worry me.

foo.c:260: warning: unused parameter `intArgCount'
foo.c:260: warning: unused parameter `strArgs'

I tend to label these "picky compiler"
 
S

Seebs

I've met a couple of "pathological liars" in my time. People who
constantly re-invent their biographical details to such an extent that
not only cridibility but space-time (in the sense that you can't have
three full-time careers *and* beat heroin simultaneously) itself is
strained to breaking point. They can be amusing once you realise what
they are doing. But I hadn't noticed any overt evidence that they
thought other people lied. Maybe they just took it as axiomatic, but
they gave no obvious sign.

The full-on pathological liars are often much less conscious of it -- and
some actually believe all those mutually exclusive things they claim. It's
the people who are lying to gain advantage, not the people who are lying
for no particular reason, who infer that everyone else lies to gain
advantage.

-s
 
S

Seebs

Yeah. If ever he gets around to fixing them in my lifetime, I'll look
at the resulting code.

You missed some pretty fun stuff in there, though.

I think I'm actually willing to half-concede one of his points: For him,
it is probably true that C is an inherently unsafe language. Note the
qualifier, though.

-s
 

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
474,079
Messages
2,570,575
Members
47,207
Latest member
HelenaCani

Latest Threads

Top