use builtin operator associativity functionality
[ccc.git] / parse.y
1 %{
2 #include <stdio.h>
3 #include <string.h>
4 #include <stdlib.h>
5
6 #include "ast.h"
7 #define YYSTYPE struct ast *
8
9 #include "y.tab.h"
10
11 int yylex_debug = 1;
12 int yylex(void);
13
14 void yyerror(struct ast **result, const char *str)
15 {
16 fprintf(stderr, "error: %s\n", str);
17 }
18
19 int yywrap()
20 {
21 return 1;
22 }
23
24 %}
25
26 %define parse.error verbose
27 %token INTEGER PLUS MINUS TIMES DIVIDE BOPEN BCLOSE SEMICOLON POWER CONS MODULO BINOR BINAND INVERSE
28
29 %parse-param { struct ast **result }
30
31 %right BINOR
32 %right BINAND
33 %nonassoc EQ NEQ LEQ LE GEQ GE
34 %right CONS
35 %left PLUS MINUS
36 %left TIMES DIVIDE MODULO
37 %right POWER
38
39 %%
40
41 start : exprs { *result = $1; } ;
42
43 exprs
44 : { $$ = NULL; }
45 | exprs expr SEMICOLON { $$ = ast_cons($2, $1); }
46 ;
47
48 expr
49 : expr BINOR expr { $$ = ast_binop($1, binor, $3); }
50 | expr BINAND expr { $$ = ast_binop($1, binand, $3); }
51 | expr EQ expr { $$ = ast_binop($1, eq, $3); }
52 | expr NEQ expr { $$ = ast_binop($1, neq, $3); }
53 | expr LEQ expr { $$ = ast_binop($1, leq, $3); }
54 | expr LE expr { $$ = ast_binop($1, le, $3); }
55 | expr GEQ expr { $$ = ast_binop($1, geq, $3); }
56 | expr GE expr { $$ = ast_binop($1, ge, $3); }
57 | expr CONS expr { $$ = ast_binop($1, cons, $3); }
58 | expr PLUS expr { $$ = ast_binop($1, plus, $3); }
59 | expr MINUS expr { $$ = ast_binop($1, minus, $3); }
60 | expr TIMES expr { $$ = ast_binop($1, times, $3); }
61 | expr DIVIDE expr { $$ = ast_binop($1, divide, $3); }
62 | expr MODULO expr { $$ = ast_binop($1, modulo, $3); }
63 | expr POWER expr { $$ = ast_binop($1, power, $3); }
64 | MINUS expr { $$ = ast_unop(negate, $2); }
65 | INVERSE expr { $$ = ast_unop(inverse, $2); }
66 | BOPEN expr BCLOSE { $$ = $2; }
67 | INTEGER
68 ;