1

I’m trying to implement my own calculator with “IF ELSE” statements. Here is the basic calculator example:

 /* description: Parses end executes mathematical expressions. */

/* lexical grammar */
%lex
%%

\s+                   /* skip whitespace */
[0-9]+("."[0-9]+)?\b  return 'NUMBER'
"*"                   return '*'
"/"                   return '/'
"-"                   return '-'
"+"                   return '+'
"^"                   return '^'
"("                   return '('
")"                   return ')'
"PI"                  return 'PI'
"E"                   return 'E'
<<EOF>>               return 'EOF'
.                     return 'INVALID'

/lex

/* operator associations and precedence */

%left '+' '-'
%left '*' '/'
%left '^'
%left UMINUS

%start expressions

%% /* language grammar */

expressions
    : e EOF
        {return $1;}
    ;

e
    : e '+' e
        {$$ = $1+$3;}
    | e '-' e
        {$$ = $1-$3;}
    | e '*' e
        {$$ = $1*$3;}
    | e '/' e
        {$$ = $1/$3;}
    | e '^' e
        {$$ = Math.pow($1, $3);}
    | '-' e %prec UMINUS
        {$$ = -$2;}
    | '(' e ')'
        {$$ = $2;}
    | NUMBER
        {$$ = Number(yytext);}
    | E
        {$$ = Math.E;}
    | PI
        {$$ = Math.PI;}
    ;

I don’t understand if I add the “IF” statements like this:

IfStatement
: "IF" "(" Expression ")" Statement
    {
        $$ = new IfStatementNode($3, $5, null, createSourceLocation(null, @1, @5));
    }
| "IF" "(" Expression ")" Statement "ELSE" Statement
    {
        $$ = new IfStatementNode($3, $5, $7, createSourceLocation(null, @1, @7));
    }
;

The parser generates well. So how I can use the statement like this IF(5>2)THEN (5+2) ELSE (5*2). The calculator’s functionality works well of course, but “IF” doesn’t.

Paul
  • 103
  • 13

2 Answers2

2

It seems that you are looking for two sorts of constructs: an IF statement and an IF expression. Fortunately, your example uses the THEN keyword to distinguish them. Your IF expression production would be something like:

IfExpression
: "IF" "(" Expression ")" "THEN" "(" Expression ")"
    {
        $$ = new IfExpressionNode(/* pass arguments as desired */);
    }
| "IF" "(" Expression ")" "THEN" "(" Expression ")" "ELSE" "(" Expression ")"
    {
        $$ = new IfExpressionNode(/* arguments */);
    }
;
David Gorsline
  • 4,933
  • 12
  • 31
  • 36
0

You don't show how your two pieces of grammar are bound together, so it's hard to answer. Have you also looked at other questions, such as Reforming the grammar to remove shift reduce conflict in if-then-else?

Community
  • 1
  • 1
akim
  • 8,255
  • 3
  • 44
  • 60