cannot perform desired operation

Discussion in 'C Programming' started by jiten, Apr 16, 2010.

  1. jiten

    jiten Guest

    Hi all,
    I have a small request. I am a newbie to lex/yacc and as part of term
    assignment was developing a calculator. But, I have problem that I
    cannot perform any real data type operation. Not even addition. At
    best, the response is :
    > command not found (e.g., for i/p: 5.0+6.0); else it is 'syntax

    error'.
    Kindly find the two files posted below:

    calc.y
    ==========
    %{#include<stdio.h>
    %}
    /*%union {double real; int integer;}*/
    %token <real> REAL
    %token <integer> INTEGER
    %token PLUS MINUS TIMES DIVIDE LP RP NL UL
    %type <real> rexpr
    %type <integer> iexpr
    %left PLUS MINUS
    %left TIMES DIVIDE
    %left UMINUS
    %%
    lines : /* nothing*/
    | lines line
    ;
    line : NL
    |iexpr NL
    { printf("%d)%d\n", lineno, $1);}
    |rexpr UL
    { printf("%d)%15.8lf\n", lineno, $1);}
    iexpr : INTEGER
    |iexpr PLUS iexpr
    { $$ = $1 + $3; }
    |iexpr MINUS iexpr
    { $$ = $1 - $3; }
    |iexpr TIMES iexpr
    { $$ = $1 * $3; }
    |iexpr DIVIDE iexpr
    { if($3) $$ = $1/$3;
    else {yyerror("divide by zero"); }
    }
    |MINUS iexpr %prec UMINUS
    { $$ = -$2;}
    |LP iexpr RP
    { $$ = $2; }
    rexpr : REAL
    |rexpr PLUS rexpr
    { $$ = $1 + $3; }
    |rexpr MINUS rexpr
    { $$ = $1 - $3; }
    |rexpr TIMES rexpr
    { $$ = $1 * $3; }
    |rexpr DIVIDE rexpr
    { if($3) $$ = $1/$3;
    else {yyerror("divide by zero"); }
    }
    |MINUS rexpr %prec UMINUS
    { $$ = -$2;}
    |LP rexpr RP
    { $$ = $2; }
    |iexpr PLUS rexpr
    { $$ = (double)$1 + $3; }
    |iexpr MINUS rexpr
    { $$ = (double)$1 - $3; }
    |iexpr TIMES rexpr
    { $$ = (double)$1 * $3; }
    |iexpr DIVIDE rexpr
    { if($3) $$ = (double)$1/$3;
    else {yyerror("divide by zero"); }
    }
    |rexpr PLUS iexpr
    { $$ = $1 +(double)$3;}
    |rexpr MINUS iexpr
    { $$ = $1 -(double)$3;}
    |rexpr DIVIDE iexpr
    { if($3) $$ = (double)$1/$3;
    else{yyerror("divide by zero"); }
    }
    %%
    #include "lex.yy.c"
    int lineno;
    main()
    {
    return yyparse();
    }
    yyerror(char *s)
    {
    fprintf(stderr, "%s\n", s);
    }

    =============
    calc.l
    -----------
    %{
    #include"y.tab.h"
    %}

    integer [0-9]+
    dreal ([0-9]*\.[0-9]+)
    ereal ([0-9]*\.[0-9]+[Ee][+-]?[0-9]+)
    real {dreal}|{ereal}
    nl \n

    %%

    [ \t] ;
    {integer} { sscanf(yytext, "%d", &yylval.integer);
    return INTEGER;
    }
    {real} { sscanf(yytext, "%lf", &yylval.real);
    return REAL;
    }
    \+ {return PLUS;}
    \- {return MINUS;}
    \* {return TIMES;}
    \/ {return DIVIDE;}
    \( {return LP;}
    \) {return RP;}
    {nl} {extern int lineno; lineno++; return NL;}
    .. {return yytext[0];} /* to return any character otherwise
    not handled as a single char. token to the parser*/

    %%

    int yywrap() { return 1;}




    Best regards,
    Jitender Ahuja
     
    jiten, Apr 16, 2010
    #1
    1. Advertising

  2. jiten

    Seebs Guest

    On 2010-04-16 00:06:52 -0500, jiten said:

    > Hi all,
    > I have a small request. I am a newbie to lex/yacc and as part of term
    > assignment was developing a calculator.


    lex and yacc are not C, even though they are often used to develop C code.

    I'd guess that comp.unix.programmer would have more people who are up to speed
    on them.

    If you're getting messages like "command not found", that sounds like you're
    ending up entering your commands at the shell prompt, rather than submitting
    them to your program -- but this would be something that, again, has more to
    do with your work environment than with C.

    -s
    --
    Copyright 2010, all wrongs reversed. Peter Seebach /
    http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
    http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
     
    Seebs, Apr 16, 2010
    #2
    1. Advertising

  3. jiten

    spinoza1111 Guest

    On Apr 16, 1:06 pm, jiten <> wrote:
    > Hi all,
    > I have a small request. I am  a newbie to lex/yacc and as part of term
    > assignment was developing a calculator. But, I have problem that I
    > cannot perform any real data type operation. Not even addition.  At
    > best, the response is :
    >  >  command not found (e.g., for i/p: 5.0+6.0); else it is 'syntax
    > error'.
    > Kindly find the two files posted below:
    >
    > calc.y
    > ==========
    >  %{#include<stdio.h>
    > %}
    > /*%union {double real; int integer;}*/
    > %token <real> REAL
    > %token <integer> INTEGER
    > %token PLUS MINUS TIMES DIVIDE LP RP NL UL
    > %type <real> rexpr
    > %type <integer> iexpr
    > %left PLUS MINUS
    > %left TIMES DIVIDE
    > %left UMINUS
    > %%
    > lines : /* nothing*/
    >       | lines line
    >       ;
    > line  : NL
    >       |iexpr NL
    >        { printf("%d)%d\n", lineno, $1);}
    >       |rexpr UL
    >        { printf("%d)%15.8lf\n", lineno, $1);}
    > iexpr : INTEGER
    >       |iexpr PLUS iexpr
    >        { $$ = $1 + $3; }
    >       |iexpr MINUS iexpr
    >        { $$ = $1 - $3; }
    >       |iexpr TIMES iexpr
    >        { $$ = $1 * $3; }
    >       |iexpr DIVIDE iexpr
    >        { if($3) $$ = $1/$3;
    >          else {yyerror("divide by zero"); }
    >        }
    >       |MINUS iexpr %prec UMINUS
    >       { $$ = -$2;}
    >       |LP iexpr RP
    >       { $$ = $2; }
    > rexpr : REAL
    >       |rexpr PLUS rexpr
    >        { $$ = $1 + $3; }
    >       |rexpr MINUS rexpr
    >        { $$ = $1 - $3; }
    >       |rexpr TIMES rexpr
    >        { $$ = $1 * $3; }
    >       |rexpr DIVIDE rexpr
    >        { if($3) $$ = $1/$3;
    >          else {yyerror("divide by zero"); }
    >        }
    >       |MINUS rexpr %prec UMINUS
    >       { $$ = -$2;}
    >       |LP rexpr RP
    >       { $$ = $2; }
    >       |iexpr PLUS rexpr
    >        { $$ = (double)$1 + $3; }
    >       |iexpr MINUS rexpr
    >        { $$ = (double)$1 - $3; }
    >       |iexpr TIMES rexpr
    >        { $$ = (double)$1 * $3; }
    >       |iexpr DIVIDE rexpr
    >        { if($3) $$ = (double)$1/$3;
    >          else {yyerror("divide by zero"); }
    >        }
    >       |rexpr PLUS iexpr
    >        { $$ = $1 +(double)$3;}
    >       |rexpr MINUS iexpr
    >        { $$ = $1 -(double)$3;}
    >       |rexpr DIVIDE iexpr
    >        { if($3) $$ = (double)$1/$3;
    >          else{yyerror("divide by zero"); }
    >        }
    > %%
    > #include "lex.yy.c"
    > int lineno;
    > main()
    > {
    >   return yyparse();}
    >
    > yyerror(char *s)
    > {
    >   fprintf(stderr, "%s\n", s);
    >
    > }
    >
    > =============
    > calc.l
    > -----------
    > %{
    > #include"y.tab.h"
    > %}
    >
    > integer [0-9]+
    > dreal   ([0-9]*\.[0-9]+)
    > ereal   ([0-9]*\.[0-9]+[Ee][+-]?[0-9]+)
    > real    {dreal}|{ereal}
    > nl      \n
    >
    > %%
    >
    > [ \t]        ;
    > {integer}    { sscanf(yytext, "%d", &yylval.integer);
    >                return INTEGER;
    >              }
    > {real}       { sscanf(yytext, "%lf", &yylval.real);
    >                return REAL;
    >              }
    > \+           {return PLUS;}
    > \-           {return MINUS;}
    > \*           {return TIMES;}
    > \/           {return DIVIDE;}
    > \(           {return LP;}
    > \)           {return RP;}
    > {nl}         {extern int lineno; lineno++; return NL;}
    > .            {return yytext[0];} /* to return any character otherwise
    > not handled as a single                                                 char. token to the parser*/
    >
    > %%
    >
    > int yywrap() { return 1;}
    >
    > Best regards,
    > Jitender Ahuja


    Mr. Ahuja, I shall be brief and general since the policy here is not
    to over-help on homework, and this looks like homework.

    A cursory examination shows IEXPR and REXPR on both sides of a binary
    operator which is normally a problem. Your code needs a more precise
    grammatical class on the left hand side of the binary operator in the
    right hand side production, followed by the optional operator,
    followed if by a recursive occurence of the grammatical class being
    defined dependent on the presence of the operator:

    expression := addFactor [ addOp expression ]
    addOp := '+' | '-'
    addFactor := mulFactor [ mulOp addfactor ]
    mulOp := '*' | '/'
    mulFactor := NUMBER | VARIABLE | '(' expression ')'

    The above grammar requires (in its definition of mulFactor) that
    special code be written to count the nesting level of parentheses so
    as to find the balancing right parenthesis and not the leftmost which
    is a flaw of this grammar (check yours for a similar flaw).

    The above pseudocode I have shown you is NOT YACC. It is an obvious
    formal notation in which you can probably see that square brackets
    mean "the grammar inside us is optional but must be satisfied if the
    first grammar symbol inside of us is present". Although I have used
    yacc, don't get me started on how bad it is, starting with its C
    centricity.

    It doesn't appear to me that your code handles operator precedence if
    that was a requirement, and on cursory examination, it appears that
    you unnecessarily distinguish integer and real expressions.

    It appears to me that you're being expected to understand a bit of
    compiler design theory as embedded in yacc, truly an out of date
    compiler "generator" that doesn't generate a compiler, only a pretty
    bad bottom up recognizer.

    If you're interested, my book ("Build Your Own .Net Language and
    Compiler", Edward G. Nilges, apress 2004) discusses this in detail
    especially in chapter 4. However, it abstracts compiler design theory
    from its usual lair (C coding) and parachutes it into Visual Basic of
    all places. This was meant to show that "computer science" is
    rigorously independent of C coding despite what some of the folks here
    might feel.
     
    spinoza1111, Apr 16, 2010
    #3
  4. jiten

    steve Guest

    On Apr 15, 10:14 pm, Seebs <> wrote:
    > On 2010-04-16 00:06:52 -0500, jiten said:
    >
    > > Hi all,
    > > I have a small request. I am  a newbie to lex/yacc and as part of term
    > > assignment was developing a calculator.

    >
    > lex and yacc are not C, even though they are often used to develop C code..
    >
    > I'd guess that comp.unix.programmer would have more people who are up to speed
    > on them.


    comp.compilers would be a much better choice. 1) It's a
    moderated newsgroup. 2) The moderator is John Levine,
    who wrote the O'rielly book on Lex and Yacc. 3) John
    does not allow flamewars in comp.compilers.

    --
    steve
     
    steve, Apr 16, 2010
    #4
  5. jiten

    spinoza1111 Guest

    On Apr 16, 10:55 pm, steve <> wrote:
    > On Apr 15, 10:14 pm, Seebs <> wrote:
    >
    > > On 2010-04-16 00:06:52 -0500, jiten said:

    >
    > > > Hi all,
    > > > I have a small request. I am  a newbie to lex/yacc and as part of term
    > > > assignment was developing a calculator.

    >
    > > lex and yacc are not C, even though they are often used to develop C code.

    >
    > > I'd guess that comp.unix.programmer would have more people who are up to speed
    > > on them.

    >
    > comp.compilers would be a much better choice.  1) It's a
    > moderated newsgroup.  2) The moderator is John Levine,
    > who wrote the O'rielly book on Lex and Yacc.  3) John
    > does not allow flamewars in comp.compilers.


    I have been totally thrown out of that site. My belief is that John is
    an enabler and plays favorites. He thinks I start trouble (who, me?).
    It's OK, but overly C and yacc centric for obvious reasons. Of course,
    the OP has a yacc problem.

    But...it seems to me that the OP's class is so focused on a truly
    outdated tool for parser generation that the professor didn't bother
    to teach the basics, including how operator precedence is implemented
    in syntax and how the leftpart of a grammar rule cannot, for most
    parsers, recursively call itself, but must instead provide a sort of
    "handle" in the form of a lower-level grammar category. This "handle"
    must further reduce down to a lexical symbol that is hopefully unique;
    this way the grammar can choose the correct form without lookahead.

    This is not possible in disambiguating a+b and a*c, but here, the
    disambiguation is the combination of "addFactor and plus" and
    "mulFactor and times".

    Possibly, yacc was thrown at the OP as a substitute for an
    introduction to parsing as if the mad dream of yesteryear
    (automatically generated compilers and software too) had come true,
    and yacc would replace thinking.

    John Levine's readiness to shitcan people in the typically Maoist
    fashion increasingly characteristic of the Web as a whole is an aspect
    of this anti-intellectualism.

    Furthermore, "flamewars" usually imply a false equality between
    people. What usually happens is simple bullying. Someone with original
    ideas gets the shit kicked out of him, and codependents make less than
    helpful suggestions, usually attempting to blame the victim.
    >
    > --
    > steve
     
    spinoza1111, Apr 17, 2010
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Henry van der Beek

    Perform operation whenever dir is altered

    Henry van der Beek, Jul 5, 2004, in forum: Python
    Replies:
    1
    Views:
    466
    John Lenton
    Jul 5, 2004
  2. Tim Golden
    Replies:
    0
    Views:
    410
    Tim Golden
    Jul 5, 2004
  3. ssg31415926
    Replies:
    3
    Views:
    1,908
    ssg31415926
    Aug 3, 2007
  4. Rishi
    Replies:
    1
    Views:
    3,741
    Alexey Smirnov
    Nov 11, 2009
  5. Arturo
    Replies:
    0
    Views:
    182
    Arturo
    Feb 6, 2004
Loading...

Share This Page