help in K&R2 
Author Message
 help in K&R2

Hi all and thanks for taking the time to read this.
i have copied and compiled  the polish calculator program
the program compiles on turboc v2.01 and {*filter*}shed
dev c++ (as a c prog and not .ccp) it wont compile  on borland c++v4.5 as a
.c program it gives about five errors
any way this calc program compiles ok but has an error on the users output
scren saying
termination error
i am planning (and have spent many hours already) to spend alot of time
studyiing this k&r2 c program that i would like some kind person to check it
for me to see if
i've done things right
and i havent yet learnt to debug yet (althoughi am now trying)
i dont know if i posted all the code if i am breaking copyright laws could
i? should'nt i??
regards
aade


Tue, 20 Jan 2004 19:04:37 GMT  
 help in K&R2
  Read comments below:
<snip />

Quote:
> i dont know if i posted all the code if i am breaking copyright laws could
> i? should'nt i??

  I don't think you will be breaking copyright laws by posting that
code. I think it will qualify as fair use under the US Constitution's
Copyright Law (refer to section 107 - Limitations on exclusive rights:
Fair use).
  And I think people will be able to help much more if they'll see the
source of the error. Also post the exact error messages from the
compiler and when the run-time errors happen.

--
  Tom Alsberg - certified insane, complete illiterate.

        Homepage: http://www.cs.huji.ac.il/~alsbergt/
  * An idea is not responsible for the people who believe in it.



Tue, 20 Jan 2004 21:54:37 GMT  
 help in K&R2


Quote:
> Hi all and thanks for taking the time to read this.
> i have copied and compiled  the polish calculator program
> the program compiles on turboc v2.01 and {*filter*}shed
> dev c++ (as a c prog and not .ccp) it wont compile  on borland c++v4.5 as
a
> .c program it gives about five errors
> any way this calc program compiles ok but has an error on the users output
> scren saying
> termination error
> i am planning (and have spent many hours already) to spend alot of time
> studyiing this k&r2 c program that i would like some kind person to check
it
> for me to see if
> i've done things right
> and i havent yet learnt to debug yet (althoughi am now trying)
> i dont know if i posted all the code if i am breaking copyright laws could
> i? should'nt i??
> regards
> aade

i have found out the source of the problem  i didnt enter
in polish notation, now i do it works a charm i think??
what is polish notation
regards
aade


Tue, 20 Jan 2004 22:49:29 GMT  
 help in K&R2


Quote:
>   Read comments below:

> <snip />
> > i dont know if i posted all the code if i am breaking copyright laws
could
> > i? should'nt i??

>   I don't think you will be breaking copyright laws by posting that
> code. I think it will qualify as fair use under the US Constitution's
> Copyright Law (refer to section 107 - Limitations on exclusive rights:
> Fair use).
>   And I think people will be able to help much more if they'll see the
> source of the error. Also post the exact error messages from the
> compiler and when the run-time errors happen.

> --
>   Tom Alsberg - certified insane, complete illiterate.

> Homepage: http://www.*-*-*.com/ ~alsbergt/
>   * An idea is not responsible for the people who believe in it.

it worked on a {*filter*}shed dec++ compiler and workd but on a turboc v2.01  i
get these errors
scanf: floating point formats not linked
 abnormal program termination
heres the code
/* this file of code compiles on turboc  v 2.01  */
/* but terminates  with errors    */

#include <stdio.h>
#include <stdlib.h>  /* for atof()  */
#define MAXOP  100  /*max size of operand or operator  */
#define NUMBER  '0'  /* signal that a number was found  */

int getop(char []);
void push(double);
double pop(void);

/* reverse polish calculator  */
int main ()
{
   int type;
   double op2;
   char s[MAXOP];
   while ((type = getop(s))  != EOF)
   {
       switch (type)
       {
          case NUMBER:
  push(atof(s)); /* convert string to float  */
   break;
          case '+':
               push(pop() + pop());
               break;
          case '*':
               push(pop() * pop());
               break;
          case '-':
               op2 = pop();
               push(pop() - op2);
               break;
          case '/':
               op2 = pop();
        if  (op2  != 0.0)
                  push(pop() / op2);
        else
    printf("error: zero division\n");
                  break;
           case'\n':
              printf("\t%.8g\n" , pop());
              break;
           default:
              printf("error: unknown command %s\n",s);
              break;
            }
          }
    return 0;

Quote:
}

#define MAXVAL   100 /* max depth of val stack  */
 int sp = 0; /* next free position  */
 double val[MAXVAL];  /*  value of stack  */
/*---------------------------------------------*/
/*      push: push f onto value stack          */
void  push(double f)
/*---------------------------------------------*/
 {
    if(sp < MAXVAL)
       val[sp++] = f;
   else
         printf("error: stack full, cant push %g\n",f);
Quote:
}

/*-------------------------------------------------*/
/*   pop: pop and return top value from stack      */
double pop(void)
/*-------------------------------------------------*/
{
   if (sp > 0)
       return val[--sp];
   else {
      printf("error: stack empty\n");
      return 0.0;
    }

Quote:
}

#include <ctype.h>
int getch(void);
void ungetch(int);

/*----------------------------------------------*/
/* getop: get next operator or numeric operand  */
int getop(char s[])
/*-----------------------------------------------*/
{
   int i ,c;

   while ((s[0] = c = getch())  == ' ' || c == '\t')
   s[1]  =  '\0';                 /* digit means a number  */
   if (!isdigit(c) && c != '.')   /*!isdigit not true if c isa digit  */
     return c;                    /* not a number */
     i = 0;
   if (isdigit(c))              /*collect integer part  */
       while (isdigit(s[++i] = c = getch()))
  ;
   if (c == '.')                /* collect fractional part  */
      while (isdigit(s[++i] = c = getch()))
    ;
    s[i] = '\0';
    if (c != EOF)
       ungetch(c);
    return NUMBER;   /* number found  */
 }

#define  BUFSIZE 100

char buf[BUFSIZE];  /* buffer for ungetch  */
 int bufp = 0;  /* next free position in buf  */
/*----------------------------------------------------------*/
/*  get a (possibly pushed back) character                  */
int getch(void)
/*----------------------------------------------------------*/
{
   return (bufp > 0) ? buf[--bufp] : getchar();
/*bufp pointer to next free position in buf[]       */

Quote:
}

/*-----------------------------------------------------*/
/*          push char back on input                    */
void  ungetch(int c)
/*-----------------------------------------------------*/
{
  if  (bufp >=BUFSIZE)
       printf("ungetch: too many characters\n");
  else
     buf[bufp++]  = c;

Quote:
}

sorry about over embelishing function s its just to point them out to me for
a while

regards
aade



Tue, 20 Jan 2004 23:09:11 GMT  
 help in K&R2


Wed, 18 Jun 1902 08:00:00 GMT  
 help in K&R2

Quote:

>  i have found out the source of the problem  i didnt enter
>  in polish notation, now i do it works a charm i think??
>  what is polish notation

K&R explain that briefly on page 74: it's a notation where an
operator follows its operands. The usual (infix) way of denoting the
addition of 2 and 3 is to put a + sign between the numbers:
    2 + 3
This format is what humans are used to seeing, but it is harder to
write a program that correctly parses it. The idea of Reverse Polish
notation is to put the operator *after* its operands:
    2 3 +
This looks unusual but is much simpler to parse in software, partly
because no parentheses are needed.

The way to parse it is simple (error checking omitted):
 - Read the next token.
 - If that token is a number:
   - Push it onto a stack.
 - Else if the token is an operator:
   - Pop the required number of operands off the stack.
   - Apply the operator to the operands.
   - Push the result onto the stack.
 - If there are unread tokens in the input stream:
   - Go to the first line.
 - Else (if no syntax errors occured):
   - There is exactly one value on the stack. Pop it off to get the
     input expression's value.

The implementation is given by K&R, and I think it should be fairly
easy to understand their code.

The question that remains is "how do I convert an expression from
infix notation to Reverse Polish and vice versa?" A simple way to do
that is to draw (or at least imagine) a parse tree. Consider the
following expression as an example:
    ((1 + 2) * 3) % 4 + 5 * 6
As you can see, parentheses were needed to indicate which operations
should be performed first. As a first step towards a parse tree, it
helps to add even more parentheses (I'll use square brackets instead
to make them stick out) according to operator precedence:
    [ [ [ ((1 + 2) * 3) ] % 4 ] + [ 5 * 6 ] ]
At this point, knowledge of precedence is no longer needed: we don't
need to remember that multiplication comes before addition because
the brackets leave no ambiguity.
Once we have come this far, we can start drawing the parse tree
(you'll need to view this mess in a fixed width font). The next
thing to do is to find the "uppermost" operator, i.e. the one that
has the least number of brackets around it. In our case that is the
second + sign in the expression. We use that + sign as the root of a
tree and draw two children: the two subexpressions it operates on.

                              "+"
                              / \
                            /     \
    [ [ ((1 + 2) * 3) ] % 4 ]     [ 5 * 6 ]

Now you apply the same rule recursively to each of the children:

                          "+"
                          / \
                        /     \
                     "%"       "*"
                     / \       / \
    [ ((1 + 2) * 3) ]   4     5   6

You keep going until there are no brackets or parentheses left. The
complete parse tree then looks like this:

             "+"
             / \
           /     \
         "%"     "*"
         / \     / \
       "*"  4   5   6
       / \
     "+"  3
     / \
    1   2

If this looks like a lot of work so far, that's because it was. But
you don't really have to draw the parse tree every time you want to
parse an infix expression; with a little practice it will form in
your head automatically.
Now that we have built the tree, we'll take it apart right away: to
build the expression's Reverse Polish representation, you start at
the bottom and work upwards, taking two operands off the tree and
writing the connecting operator behind them.
In our example, we first take 1 and 2 and the + sign that operates
on them:
    1 2 +
(Inside the calculator, as soon as these three tokens are read,
their result is computed and pushed back to the stack. In our tree
that would mean deleting 1 and 2 and replacing the first + sign by
the literal 3, the result of the addition.)
Now we look at he next operator from the bottom: It's the * sign
that connects (1 2 +) and 3. Again, we write down the operands,
followed by their operator:
    1 2 + 3 *
We keep executing this step until the whole tree has been processed.
In our example [as a reminder to you, and especially to me, the
original expression was ((1 + 2) * 3) % 4 + 5 * 6 ], the complete
Reverse Polish expression comes out to be the following:
    1 2 + 3 * 4 % 5 6 * +
Note that the numbers appear in the same order as they did in the
original expression, and the operators in the order we read them out
of the parse tree, i.e. bottom to top, left to right.

For the conversion back to infix notation we can use these
properties to again build a parse tree, this time from bottom to
top; start with "1 2 +":

     "+"
     / \
    1   2

then add the 3 and the multiplication sign, etc. The tree will come
out to be the same as the one we built to convert from infix. To
read the infix representation out of the parse tree, read it again,
from bottom to top, left to right. First you will encounter the
branches denoting this subexpression:
    1 + 2
Surround it with parentheses:
    (1 + 2)
Keep going, on to the multiplication and the 3, and add parentheses:
    ((1 + 2) * 3)
and so on, until the whole tree has been read:
    ((((1 + 2) * 3) % 4) + (5 * 6))
Finally, drop unnecessary parentheses:
    ((1 + 2) * 3) % 4 + 5 * 6
and you are back to the original expression.
I hope this explanation was clear and detailed enough to answer your
questions about Reverse Polish notation; further questions are
welcome but should maybe dealt with outside of comp.lang.c where
this is increasingly off-topic.
Fla^H^H^HCorrections are also welcome.

Gergo

--
In the stairway of life, you'd best take the elevator.



Wed, 21 Jan 2004 00:31:47 GMT  
 help in K&R2
  [Off-topic:]
  This is a good way to convert infix notation to postfix notation. But
there is a simpler one for an algorithm to follow, without needing to
parenthesise or build a parse tree. Given that the stream is tokenized,
and the operator precedence/associativity is known, the following does
it using a stack, getting an infix noted expression on input and
outputting a postfix noted expression:

While there are tokens left in the input, do:
  Read token from input
  If token is:
    - an operand - send to output.

    - an operator or opening paren - pop elements from stack and send to
                                     output until either of the following
                                     is reached:
                                       * an operator of lower
                                         precedence, or
                                       * a right associative operator of
                                         equal precedence.
                                     then push operator/paren to stack.

    - a closing paren - pop elements from stack and send to output until
                        an opening paren is reached.

    - end of input - pop remaining tokens from stack, and send to
                     output.

  -- Tom



<snip />

Quote:

> The question that remains is "how do I convert an expression from
> infix notation to Reverse Polish and vice versa?" A simple way to do
> that is to draw (or at least imagine) a parse tree. Consider the
> following expression as an example:
>     ((1 + 2) * 3) % 4 + 5 * 6
> As you can see, parentheses were needed to indicate which operations
> should be performed first. As a first step towards a parse tree, it
> helps to add even more parentheses (I'll use square brackets instead
> to make them stick out) according to operator precedence:
>     [ [ [ ((1 + 2) * 3) ] % 4 ] + [ 5 * 6 ] ]
> At this point, knowledge of precedence is no longer needed: we don't
> need to remember that multiplication comes before addition because
> the brackets leave no ambiguity.
> Once we have come this far, we can start drawing the parse tree
> (you'll need to view this mess in a fixed width font). The next
> thing to do is to find the "uppermost" operator, i.e. the one that
> has the least number of brackets around it. In our case that is the
> second + sign in the expression. We use that + sign as the root of a
> tree and draw two children: the two subexpressions it operates on.

>                               "+"
>                               / \
>                             /     \
>     [ [ ((1 + 2) * 3) ] % 4 ]     [ 5 * 6 ]

> Now you apply the same rule recursively to each of the children:

>                           "+"
>                           / \
>                         /     \
>                      "%"       "*"
>                      / \       / \
>     [ ((1 + 2) * 3) ]   4     5   6

> You keep going until there are no brackets or parentheses left. The
> complete parse tree then looks like this:

>              "+"
>              / \
>            /     \
>          "%"     "*"
>          / \     / \
>        "*"  4   5   6
>        / \
>      "+"  3
>      / \
>     1   2

> If this looks like a lot of work so far, that's because it was. But
> you don't really have to draw the parse tree every time you want to
> parse an infix expression; with a little practice it will form in
> your head automatically.
> Now that we have built the tree, we'll take it apart right away: to
> build the expression's Reverse Polish representation, you start at
> the bottom and work upwards, taking two operands off the tree and
> writing the connecting operator behind them.
> In our example, we first take 1 and 2 and the + sign that operates
> on them:
>     1 2 +
> (Inside the calculator, as soon as these three tokens are read,
> their result is computed and pushed back to the stack. In our tree
> that would mean deleting 1 and 2 and replacing the first + sign by
> the literal 3, the result of the addition.)
> Now we look at he next operator from the bottom: It's the * sign
> that connects (1 2 +) and 3. Again, we write down the operands,
> followed by their operator:
>     1 2 + 3 *
> We keep executing this step until the whole tree has been processed.
> In our example [as a reminder to you, and especially to me, the
> original expression was ((1 + 2) * 3) % 4 + 5 * 6 ], the complete
> Reverse Polish expression comes out to be the following:
>     1 2 + 3 * 4 % 5 6 * +
> Note that the numbers appear in the same order as they did in the
> original expression, and the operators in the order we read them out
> of the parse tree, i.e. bottom to top, left to right.

> For the conversion back to infix notation we can use these
> properties to again build a parse tree, this time from bottom to
> top; start with "1 2 +":

>      "+"
>      / \
>     1   2

> then add the 3 and the multiplication sign, etc. The tree will come
> out to be the same as the one we built to convert from infix. To
> read the infix representation out of the parse tree, read it again,
> from bottom to top, left to right. First you will encounter the
> branches denoting this subexpression:
>     1 + 2
> Surround it with parentheses:
>     (1 + 2)
> Keep going, on to the multiplication and the 3, and add parentheses:
>     ((1 + 2) * 3)
> and so on, until the whole tree has been read:
>     ((((1 + 2) * 3) % 4) + (5 * 6))
> Finally, drop unnecessary parentheses:
>     ((1 + 2) * 3) % 4 + 5 * 6
> and you are back to the original expression.
> I hope this explanation was clear and detailed enough to answer your
> questions about Reverse Polish notation; further questions are
> welcome but should maybe dealt with outside of comp.lang.c where
> this is increasingly off-topic.
> Fla^H^H^HCorrections are also welcome.

> Gergo

--
  Tom Alsberg - certified insane, complete illiterate.

        Homepage: http://www.cs.huji.ac.il/~alsbergt/
  * An idea is not responsible for the people who believe in it.


Wed, 21 Jan 2004 01:05:26 GMT  
 help in K&R2


Quote:

> >  i have found out the source of the problem  i didnt enter
> >  in polish notation, now i do it works a charm i think??
> >  what is polish notation

> K&R explain that briefly on page 74: it's a notation where an
> operator follows its operands. The usual (infix) way of denoting the
> addition of 2 and 3 is to put a + sign between the numbers:
>     2 + 3
> This format is what humans are used to seeing, but it is harder to
> write a program that correctly parses it. The idea of Reverse Polish
> notation is to put the operator *after* its operands:
>     2 3 +
> This looks unusual but is much simpler to parse in software, partly
> because no parentheses are needed.

> The way to parse it is simple (error checking omitted):
>  - Read the next token.
>  - If that token is a number:
>    - Push it onto a stack.
>  - Else if the token is an operator:
>    - Pop the required number of operands off the stack.
>    - Apply the operator to the operands.
>    - Push the result onto the stack.
>  - If there are unread tokens in the input stream:
>    - Go to the first line.
>  - Else (if no syntax errors occured):
>    - There is exactly one value on the stack. Pop it off to get the
>      input expression's value.

> The implementation is given by K&R, and I think it should be fairly
> easy to understand their code.

> The question that remains is "how do I convert an expression from
> infix notation to Reverse Polish and vice versa?" A simple way to do
> that is to draw (or at least imagine) a parse tree. Consider the
> following expression as an example:
>     ((1 + 2) * 3) % 4 + 5 * 6
> As you can see, parentheses were needed to indicate which operations
> should be performed first. As a first step towards a parse tree, it
> helps to add even more parentheses (I'll use square brackets instead
> to make them stick out) according to operator precedence:
>     [ [ [ ((1 + 2) * 3) ] % 4 ] + [ 5 * 6 ] ]
> At this point, knowledge of precedence is no longer needed: we don't
> need to remember that multiplication comes before addition because
> the brackets leave no ambiguity.
> Once we have come this far, we can start drawing the parse tree
> (you'll need to view this mess in a fixed width font). The next
> thing to do is to find the "uppermost" operator, i.e. the one that
> has the least number of brackets around it. In our case that is the
> second + sign in the expression. We use that + sign as the root of a
> tree and draw two children: the two subexpressions it operates on.

>                               "+"
>                               / \
>                             /     \
>     [ [ ((1 + 2) * 3) ] % 4 ]     [ 5 * 6 ]

> Now you apply the same rule recursively to each of the children:

>                           "+"
>                           / \
>                         /     \
>                      "%"       "*"
>                      / \       / \
>     [ ((1 + 2) * 3) ]   4     5   6

> You keep going until there are no brackets or parentheses left. The
> complete parse tree then looks like this:

>              "+"
>              / \
>            /     \
>          "%"     "*"
>          / \     / \
>        "*"  4   5   6
>        / \
>      "+"  3
>      / \
>     1   2

> If this looks like a lot of work so far, that's because it was. But
> you don't really have to draw the parse tree every time you want to
> parse an infix expression; with a little practice it will form in
> your head automatically.
> Now that we have built the tree, we'll take it apart right away: to
> build the expression's Reverse Polish representation, you start at
> the bottom and work upwards, taking two operands off the tree and
> writing the connecting operator behind them.
> In our example, we first take 1 and 2 and the + sign that operates
> on them:
>     1 2 +
> (Inside the calculator, as soon as these three tokens are read,
> their result is computed and pushed back to the stack. In our tree
> that would mean deleting 1 and 2 and replacing the first + sign by
> the literal 3, the result of the addition.)
> Now we look at he next operator from the bottom: It's the * sign
> that connects (1 2 +) and 3. Again, we write down the operands,
> followed by their operator:
>     1 2 + 3 *
> We keep executing this step until the whole tree has been processed.
> In our example [as a reminder to you, and especially to me, the
> original expression was ((1 + 2) * 3) % 4 + 5 * 6 ], the complete
> Reverse Polish expression comes out to be the following:
>     1 2 + 3 * 4 % 5 6 * +
> Note that the numbers appear in the same order as they did in the
> original expression, and the operators in the order we read them out
> of the parse tree, i.e. bottom to top, left to right.

> For the conversion back to infix notation we can use these
> properties to again build a parse tree, this time from bottom to
> top; start with "1 2 +":

>      "+"
>      / \
>     1   2

> then add the 3 and the multiplication sign, etc. The tree will come
> out to be the same as the one we built to convert from infix. To
> read the infix representation out of the parse tree, read it again,
> from bottom to top, left to right. First you will encounter the
> branches denoting this subexpression:
>     1 + 2
> Surround it with parentheses:
>     (1 + 2)
> Keep going, on to the multiplication and the 3, and add parentheses:
>     ((1 + 2) * 3)
> and so on, until the whole tree has been read:
>     ((((1 + 2) * 3) % 4) + (5 * 6))
> Finally, drop unnecessary parentheses:
>     ((1 + 2) * 3) % 4 + 5 * 6
> and you are back to the original expression.
> I hope this explanation was clear and detailed enough to answer your
> questions about Reverse Polish notation; further questions are
> welcome but should maybe dealt with outside of comp.lang.c where
> this is increasingly off-topic.
> Fla^H^H^HCorrections are also welcome.

> Gergo

> --
> In the stairway of life, you'd best take the elevator.

thank  you gergo Barany for such a great explanation
i'll be saving this for lookup times
regards
aade


Wed, 21 Jan 2004 01:04:05 GMT  
 help in K&R2


Wed, 18 Jun 1902 08:00:00 GMT  
 help in K&R2

Quote:
>i have found out the source of the problem  i didnt enter
>in polish notation, now i do it works a charm i think??
>what is polish notation
>regards
>aade

would you rather remember
         lucasiewicz notation
with a bar trhough the l

he realized that if you prefixed operators only with fixed arity you do
not need parenthesis

        + * 1 2 * 3 4 for 1*2 + 3*4
        * + 1 2 + 3 4 for (1+2)*(4+4)
        + * 2 3 4 for 2*3 + 4
        * + 2 3 4 for (2+3) * 4

polish notation can be implemented with an operator stack and operand stack

reverse polish notation uses postfixed operators so it only needs an
operand stack

        1 2 * 3 4 * +
        1 2 + 3 4 + *
        2 3 * 4 +
        2 3 + 4 *



Wed, 21 Jan 2004 03:20:47 GMT  
 
 [ 10 post ] 

 Relevant Pages 

1. help with K&R2

2. Help->Can't Compile Ex in pp.140, K&R2

3. K&R1 vs. K&R2

4. Newbie getting runtime Exception (STATUS_ACCESS_VIOLATION) trying to implement Ex. 2-4 from K&R2

5. K&R2's implicit declaration of exit()

6. New K&R2 exercise: fix getint

7. Have K&R2, looking for simpler resource on pointers

8. In the reference manual of K&R2 (2)

9. k&r2 question 4.3

10. k&r2 advice

11. k&r2 question

12. One more trivial question on K&R2?

 

 
Powered by phpBB® Forum Software