c79a1ec8563492395706a2739edd7cd30c10cea5
[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 ast_free(*result);
17 fprintf(stderr, "error: %s\n", str);
18 }
19
20 int yywrap()
21 {
22 return 1;
23 }
24
25 %}
26
27 //%define parse.error verbose
28 %token ASSIGN BCLOSE BINAND BINOR BOOL BOPEN CCLOSE CHAR COMMA CONS COPEN
29 %token DIVIDE DOT ELSE IDENT IF INTEGER INVERSE MINUS MODULO NIL PLUS POWER
30 %token RETURN SEMICOLON TIMES VAR WHILE
31
32 %parse-param { struct ast **result }
33
34 %right BINOR
35 %right BINAND
36 %nonassoc EQ NEQ LEQ LE GEQ GE
37 %right CONS
38 %left PLUS MINUS
39 %left TIMES DIVIDE MODULO
40 %right POWER
41
42 %%
43
44 start : decls { *result = ast_list($1); } ;
45
46 decls
47 : { $$ = NULL; }
48 | decls vardecl SEMICOLON { $$ = ast_cons($2, $1); }
49 | decls fundecl { $$ = ast_cons($2, $1); }
50 ;
51
52 vardecl
53 : VAR IDENT ASSIGN expr { $$ = ast_vardecl($2, $4); }
54 ;
55
56 fundecl
57 : IDENT BOPEN args BCLOSE COPEN body CCLOSE
58 { $$ = ast_fundecl($1, ast_list($3), ast_list($6)); }
59 ;
60
61 args
62 : { $$ = NULL; }
63 | nargs
64 ;
65 nargs
66 : nargs COMMA IDENT { $$ = ast_cons($3, $1); }
67 | IDENT { $$ = ast_cons($1, NULL); }
68 ;
69
70 fargs
71 : { $$ = NULL; }
72 | fnargs
73 ;
74 fnargs
75 : fnargs COMMA expr { $$ = ast_cons($3, $1); }
76 | expr { $$ = ast_cons($1, NULL); }
77 ;
78 body
79 : { $$ = NULL; }
80 | body vardecl SEMICOLON { $$ = ast_cons($2, $1); }
81 | body stmt { $$ = ast_cons($2, $1); }
82 ;
83
84 stmt
85 : IF BOPEN expr BCLOSE COPEN body CCLOSE ELSE COPEN body CCLOSE
86 { $$ = ast_if($3, ast_list($6), ast_list($10)); }
87 | WHILE BOPEN expr BCLOSE COPEN body CCLOSE
88 { $$ = ast_while($3, ast_list($6)); }
89 | expr SEMICOLON { $$ = ast_stmt_expr($1); }
90 | IDENT ASSIGN expr SEMICOLON { $$ = ast_assign($1, $3); }
91 | RETURN expr SEMICOLON { $$ = ast_return($2); }
92 | RETURN SEMICOLON { $$ = ast_return(NULL); }
93 ;
94
95 field
96 : { $$ = NULL; }
97 | field DOT IDENT { $$ = ast_cons($3, $1); }
98
99 expr
100 : expr BINOR expr { $$ = ast_binop($1, binor, $3); }
101 | expr BINAND expr { $$ = ast_binop($1, binand, $3); }
102 | expr EQ expr { $$ = ast_binop($1, eq, $3); }
103 | expr NEQ expr { $$ = ast_binop($1, neq, $3); }
104 | expr LEQ expr { $$ = ast_binop($1, leq, $3); }
105 | expr LE expr { $$ = ast_binop($1, le, $3); }
106 | expr GEQ expr { $$ = ast_binop($1, geq, $3); }
107 | expr GE expr { $$ = ast_binop($1, ge, $3); }
108 | expr CONS expr { $$ = ast_binop($1, cons, $3); }
109 | expr PLUS expr { $$ = ast_binop($1, plus, $3); }
110 | expr MINUS expr { $$ = ast_binop($1, minus, $3); }
111 | expr TIMES expr { $$ = ast_binop($1, times, $3); }
112 | expr DIVIDE expr { $$ = ast_binop($1, divide, $3); }
113 | expr MODULO expr { $$ = ast_binop($1, modulo, $3); }
114 | expr POWER expr { $$ = ast_binop($1, power, $3); }
115 | MINUS expr { $$ = ast_unop(negate, $2); }
116 | INVERSE expr %prec TIMES { $$ = ast_unop(inverse, $2); }
117 | BOPEN expr BCLOSE { $$ = $2; }
118 | IDENT BOPEN fargs BCLOSE { $$ = ast_funcall($1, ast_list($3)); }
119 | INTEGER
120 | BOOL
121 | CHAR
122 | IDENT field { $$ = ast_ident($1, ast_list($2)); }
123 | NIL { $$ = ast_nil(); }
124 ;