0
votes

I'm writing a calculator in Flex/Bison that allows variables. Right now I only have one variable (x) that you can use. I want to be able to use more than just x. (Rather like a-z). Can anyone help? Here's what I have so far:

Calculator.y

%{
    #include <stdio.h>
    #include <math.h>
    void yyerror(char *);
    int yylex(void);
    int symbol;
%}

%token INTEGER VARIABLE
%left '+' '-' '*' '/' '^'

%%

program:
    program statement '\n'
    | /* NULL */
    ;
statement:
    expression          { printf("%d\n", $1); }
    | VARIABLE '=' expression   { symbol = $3; }
    ;
expression:
        INTEGER

    | VARIABLE          { $$ = symbol; }
    | '-' expression        { $$ = -$2; }
    | expression '+' expression { $$ = $1 + $3; }
    | expression '-' expression { $$ = $1 - $3; }
    | expression '*' expression { $$ = $1 * $3; }
    | expression '/' expression { $$ = $1 / $3; }
    | expression '^' expression { $$ = pow($1, $3); }
    | '(' expression ')'        { $$ = $2; }
    ;

%%

void yyerror(char *s) {
    fprintf(stderr, "%s\n", s);
}
int main(void) {
    yyparse();
}

calculator.l

    /* calculator */
%{
    #include "y.tab.h"
    #include <math.h>
    #include <stdlib.h>
    void yyerror(char *);
%}

%%

[x] {
        yylval = *yytext - 'a';
        return VARIABLE;
    }

[0-9]+ { 
        yylval = atoi(yytext);
        return INTEGER;
       }

[-+*/^()=\n] { return *yytext; }

[ \t]   ; /* skip whitespace */

.          yyerror("Unknown Character");

%%

int yywrap(void) {
    return 1;
}
1

1 Answers

1
votes

Your lexer needs to recognize [a-z] instead of just [x].

In the grammar, you need to define an array int variables[26];

In the rule(s) where VARIABLE is assigned, assign to variables[$1] (for example) and where VARIABLE is referenced, use $$ = variables[$1]; (for example). Check that the n in $n is the correct value.