forked from danigfavero/Projeto-MAC0316
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmcalc.y
96 lines (79 loc) · 2.15 KB
/
mcalc.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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/* Calculadora infixa */
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *iffer(char *c, char *y, char *n) {
char *res = malloc(strlen(c)+strlen(y)+strlen(n)+6);
sprintf(res, "(if %s %s %s)", c, y, n);
return res;
}
char *caller(char *f, char *x) {
char *res = malloc(strlen(f) + strlen(x) + 10);
sprintf(res, "(call %s %s)", f, x);
return res;
}
char *deefer(char *f, char *x, char *b, char *v) {
char *plc = caller(f, v);
char *res = malloc(2*strlen(f) + strlen(x) + strlen(b) + strlen(plc) + 37);
sprintf(res, "(def %s 1729 (seq (:= %s (func %s %s)) %s))", f, f, x, b, plc);
return res;
}
char *varrer(char *n, char* v){
char *res = malloc(2*strlen(n) + strlen(v) + 10);
sprintf(res, "(def %s %s %s)", n, v, n);
return res;
}
char *oper(char op, char *l, char *r) {
char *res = malloc(strlen(l)+strlen(r)+6);
sprintf(res, "(%c %s %s)", op, l, r);
return res;
}
char *dup(char *orig) {
char *res = malloc(strlen(orig)+1);
strcpy(res,orig);
return res;
}
int yylex();
void yyerror(char *);
%}
%union {
char *val;
}
%token <val> NUM NAME
%token IF ADD SUB MUL DIV OPEN CLOSE DEF CALL NEG VAR
%type <val> exp
/* Precedência */
%left DEF VAR CALL
%left IF
%left ADD SUB
%left MUL DIV
%left NEG
/* Gramatica */
/* As operações em nossa gramática (soma, subtração, multiplicação, divisão)
são lidas como em uma calculadora comum x + y
Nosso if é lido no formato if condição true false
Nossas funções são lidas no formato função arg
*/
%%
input:
| exp { puts($1);}
| error { fprintf(stderr, "Entrada inválida\n"); }
;
exp: NUM { $$ = dup($1); }
| NAME { $$ = dup($1); }
| CALL exp exp { $$ = caller($2, $3);}
| OPEN exp CLOSE { $$ = dup($2);}
| DEF exp exp exp exp { $$ = deefer($2, $3, $4, $5);}
| VAR exp exp { $$ = varrer($2, $3);}
| IF exp exp exp { $$ = iffer($2, $3, $4);}
| exp ADD exp { $$ = oper('+', $1, $3);}
| exp SUB exp { $$ = oper('-', $1, $3);}
| exp MUL exp { $$ = oper('*', $1, $3);}
| exp DIV exp { $$ = oper('/', $1, $3);}
| SUB exp %prec NEG { $$ = oper('~', $2, "");}
;
%%
void yyerror(char *s) {
fprintf(stderr,"%s\n",s);
}