fela

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

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 }