parse.y (4495B)
1 %{ 2 #include <stdio.h> 3 #include <stdlib.h> 4 5 #include "ast.h" 6 #include "util.h" 7 8 #define YYDEBUG 1 9 10 extern char *yytext; 11 extern int yyleng; 12 extern size_t lineno, offset; 13 14 extern int yylex(); 15 extern void typecheck(struct ast_decs *); 16 17 int yyerror(const char *); 18 19 struct ast_decs *body; 20 %} 21 22 %union { 23 struct ast_dec *dec; 24 struct ast_expr *expr; 25 struct ast_decs *decs; 26 struct ast_exprs *exprs; 27 struct ast_type *type; 28 struct ast_arg *arg; 29 struct ast_args *args; 30 31 char *s; 32 long l; 33 } 34 35 %token <s> NAME 36 %token <l> NUMBER 37 %token FUNC RETTYPE 38 39 %type <decs> body 40 %type <expr> expr 41 %type <expr> func 42 %type <exprs> exprs 43 %type <dec> dec 44 %type <decs> decs 45 %type <type> type 46 %type <args> args 47 %type <arg> arg 48 %type <s> name 49 50 51 %left '+' '-' 52 %left '*' '/' 53 %left '(' ')' 54 %left '=' 55 56 %% 57 58 body : decs { body = $1; } 59 ; 60 61 decs : decs dec ';' { 62 struct ast_decs *decs = $1, *prev = NULL; 63 $$ = decs; 64 while (decs) { 65 prev = decs; 66 decs = decs->decs; 67 } 68 decs = alloczt(struct ast_decs); 69 prev->decs = decs; 70 decs->dec = $2; 71 } 72 | dec ';' { 73 $$ = alloczt(struct ast_decs); 74 $$->dec = $1; 75 } 76 ; 77 78 79 dec : type name { 80 $$ = alloczt(struct ast_dec); 81 $$->name = $2; 82 $$->type = $1; 83 } 84 | type name '=' expr { 85 $$ = alloczt(struct ast_dec); 86 $$->name = $2; 87 $$->value = $4; 88 $$->type = $1; 89 } 90 | type name '=' func { 91 $$ = alloczt(struct ast_dec); 92 $$->name = $2; 93 $$->value = $4; 94 $$->type = $1; 95 } 96 97 ; 98 99 exprs : exprs expr ';' { 100 struct ast_exprs *exprs = $1, *prev = NULL; 101 $$ = exprs; 102 while (exprs) { 103 prev = exprs; 104 exprs = exprs->exprs; 105 } 106 exprs = alloczt(struct ast_exprs); 107 prev->exprs = exprs; 108 exprs->expr = $2; 109 110 } 111 | expr ';' { 112 $$ = alloczt(struct ast_exprs); 113 $$->expr = $1; 114 } 115 ; 116 117 func : '(' args ')' RETTYPE type '{' decs exprs '}' { 118 $$ = alloczt(struct ast_expr); 119 $$->op = FUNCTION; 120 $$->args = $2; 121 $$->decs = $7; 122 $$->exprs = $8; 123 } 124 | '(' args ')' RETTYPE type '{' exprs '}' { 125 $$ = alloczt(struct ast_expr); 126 $$->op = FUNCTION; 127 $$->exprs = $7; 128 } 129 ; 130 131 expr : name '=' expr { 132 $$ = alloczt(struct ast_expr); 133 $$->op = ADD; 134 $$->children = allocztn(struct ast_expr, 2); 135 $$->fn = $1; 136 $$->children[0] = *$3; 137 } 138 | expr '+' expr { 139 $$ = alloczt(struct ast_expr); 140 $$->op = ADD; 141 $$->children = allocztn(struct ast_expr, 2); 142 $$->children[0] = *$1; 143 $$->children[1] = *$3; 144 } 145 | expr '-' expr { 146 $$ = alloczt(struct ast_expr); 147 $$->op = SUB; 148 $$->children = allocztn(struct ast_expr, 2); 149 $$->children[0] = *$1; 150 $$->children[1] = *$3; 151 } 152 | expr '/' expr { 153 $$ = alloczt(struct ast_expr); 154 $$->op = DIV; 155 $$->children = allocztn(struct ast_expr, 2); 156 $$->children[0] = *$1; 157 $$->children[1] = *$3; 158 } 159 | expr '*' expr { 160 $$ = alloczt(struct ast_expr); 161 $$->op = MUL; 162 $$->children = allocztn(struct ast_expr, 2); 163 $$->children[0] = *$1; 164 $$->children[1] = *$3; 165 } 166 | '(' expr ')' { 167 $$ = alloczt(struct ast_expr); 168 $$->op = NESTED; 169 $$->children = alloczt(struct ast_expr); 170 $$->children[0] = *$2; 171 $$->child_count++; 172 } 173 | NUMBER { 174 $$ = alloczt(struct ast_expr); 175 $$->op = VALUE; 176 $$->value = $1; 177 } 178 | name { 179 $$ = alloczt(struct ast_expr); 180 $$->op = VAR; 181 $$->fn = $1; 182 } 183 | name '(' ')' { 184 $$ = alloczt(struct ast_expr); 185 $$->op = FUNC; 186 $$->fn = $1; 187 } 188 ; 189 190 name : NAME { 191 192 $$ = strslice($1, yyleng); 193 } 194 ; 195 196 type : NAME { 197 $$ = alloczt(struct ast_type); 198 $$->t = BASIC_T; 199 $$->type = strslice($1, yyleng); 200 } 201 | FUNC '(' ')' RETTYPE type { 202 $$ = alloczt(struct ast_type); 203 $$->t = FUNCTION_T; 204 $$->ret = $5; 205 } 206 ; 207 208 args : args ',' arg { 209 $$ = append_arg($1, $3); 210 } 211 | arg { 212 $$ = alloczt(struct ast_args); 213 $$ = append_arg($$, $1); 214 } 215 ; 216 217 arg : type NAME { 218 $$ = alloczt(struct ast_arg); 219 $$->type = $1; 220 $$->name = $2; 221 } 222 ; 223 %% 224 225 int 226 yyerror(const char *msg) { 227 if (strcmp(msg, "syntax error") == 0) { 228 fprintf(stderr, "%ld:%ld: syntax error: %s\n", lineno + 1, offset - yyleng, yytext); 229 } 230 else 231 fprintf(stderr, "%s\n", msg); 232 } 233 234 int 235 main() { 236 gctx = newctx(); 237 yyparse(); 238 freectx(gctx); 239 }