-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcalculator.y
82 lines (70 loc) · 1.96 KB
/
calculator.y
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/*
* Parser para uma calculadora avancada
*/
%{
#include <stdio.h>
#include <stdlib.h>
#include "calculator.h"
%}
%union {
struct ast *a;
double d;
struct symbol *s; /* qual simbolo? */
struct symlist *sl;
int fn; /* qual funcao? */
}
/* declaracao de tokens */
%token <d> NUMBER
%token <s> NAME
%token <fn> FUNC
%token EOL
%token IF THEN ELSE WHILE DO LET FOR
%nonassoc <fn> CMP
%right '='
%left '+' '-'
%left '*' '/'
%type <a> exp stmt list explist
%type <sl> symlist
%start calclist
%%
stmt: IF exp THEN list { $$ = newflow('I', $2, $4, NULL); }
| IF exp THEN list ELSE list { $$ = newflow('I', $2, $4, $6); }
| WHILE exp DO list { $$ = newflow('W', $2, $4, NULL); }
| FOR '(' exp ';' exp ';' exp ')' list { $$ = newfor('O', $3, $5, newast('L', $9, $7)); }
| exp
;
list: /* vazio ! */ { $$ = NULL; }
| stmt ';' list { if ($3 == NULL)
$$ = $1;
else
$$ = newast('L', $1, $3);
}
;
exp: exp CMP exp { $$ = newcmp($2, $1, $3); }
| exp '+' exp { $$ = newast('+', $1, $3); }
| exp '-' exp { $$ = newast('-', $1, $3); }
| exp '*' exp { $$ = newast('*', $1, $3); }
| exp '/' exp { $$ = newast('/', $1, $3); }
| '(' exp ')' { $$ = $2; }
| NUMBER { $$ = newnum ($1); }
| NAME { $$ = newref($1); }
| NAME '=' exp { $$ = newasgn($1, $3); }
| FUNC '('explist ')' { $$ = newfunc($1, $3); }
| NAME '('explist')' { $$ = newcall($1, $3); }
;
explist: exp
| exp ',' explist { $$ = newast( 'L', $1, $3); }
;
symlist: NAME { $$ = newsymlist ($1, NULL); }
| NAME ',' symlist { $$ = newsymlist ($1, $3); }
;
calclist: /* vazio! */
| calclist stmt EOL {
printf("= %4.4g\n> ", eval($2));
treefree ($2);
}
| calclist LET NAME '(' symlist ')' '=' list EOL {
dodef( $3, $5, $8);
printf("Defined %s\n>", $3->name); }
| calclist error EOL { yyerrok; printf("> "); }
;