interpreter, Linux, Mac, Raspberry Pi

Zbudujmy interpreter (3) – zmienne

W kolejnym kroku budowy interpretera dodam obsługę zmiennych (dla ułatwienia przyjąłem, że zmienne będą oznaczone jedną literą – w sumie możemy wykorzystać 26 zmiennych – od a do z). Chciałbym aby można było przypisywać wartość liczbową do zmiennej oraz wykorzystywać zmienne do obliczeń. Parser i lekser muszę uzupełnić o obsługę wyrażenia:

<zmienna> = <wyrażenie>


Plik parser.y uzupełniłem w następujący sposób:

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

int vars[26];
%}
%start expression_list
%token NUM VARIABLE
%left '-' '+'
%left '*' '/'
%nonassoc UMINUS
%%
expression_list:
        expression_list statement '\n'{ printf(" = %d\n",$2); }
        | expression_list '\n'
        |
;
statement:
        expression
        | VARIABLE '=' expression { vars[$1] = $3; }
;
expression:
        NUM 
        | VARIABLE { $$ = vars[$3]; }
        | '-' expression %prec UMINUS { $$ = -$2; }
        | '(' expression ')' { $$ = $2; }
        | expression '+' expression  { $$ = $1 + $3; }
        | expression '-' expression  { $$ = $1 - $3; }
        | expression '*' expression  { $$ = $1 * $3; }
        | expression '/' expression  { $$ = $1 / $3; }
;
%%
void yyerror(char *s )
{
     fprintf (stderr, "%s\n", s);
}
int main (int argc, char **argv) {
     return yyparse();
}

W tablicy int vars[] będę przechowywał wartości zmiennych. W definicji parsera dodałem opis wyrażenia statement w celu rozróżnienia czy dokonujemy przypisanie wartości do zmiennej czy dokonujemy obliczenia wyrażenia.
Pozostaje nam zmienić jeszcze plik scan.l aby dodać identyfikację tokena VARIABLE oraz znaku = .

%{
#include 
#include "parse.h"

void yyerror(char *s);
%}

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

[0-9]+ { yylval =  atoi (yytext);
         return NUM;
        }
[-+()=/*\n]     return *yytext;

[ \t] ; /* skip whitespace */

.       yyerror("invalid character");
%%
Standard

Dodaj komentarz