%{ #include <stdio.h> #include "calc.h" #define YYDEBUG 1 %} %union { char *identifier; ParameterList *parameter_list; Expression *expression; } %token <expression> INT_LITERAL %token <expression> DOUBLE_LITERAL %token <identifier> IDENTIFIER %token DEFINE IF ELSE WHILE LP RP LC RC SEMICOLON COMMA ASSIGN EQ NE GT GE LT LE ADD SUB MUL DIV MOD %type <parameter_list> parameter_list %type <expression> expression expression_list equality_expression relational_expression additive_expression multiplicative_expression unary_expression postfix_expression primary_expression if_expression while_expression %% translation_unit : definition_or_expression | translation_unit definition_or_expression ; definition_or_expression : function_definition | expression SEMICOLON { clc_eval_expression($1); } | error { yyclearin; clc_reopen_current_storage(); } ; function_definition : DEFINE IDENTIFIER LP parameter_list RP LC expression_list RC { clc_function_define($2, $4, $7); } | DEFINE IDENTIFIER LP RP LC expression_list RC { clc_function_define($2, NULL, $6); } ; parameter_list : IDENTIFIER { $$ = clc_create_parameter($1); } | parameter_list COMMA IDENTIFIER { $$ = clc_chain_parameter($1, $3); } ; expression_list : expression { $$ = clc_create_expression_list($1); } | expression_list COMMA expression { $$ = clc_chain_expression_list($1, $3); } ; expression : equality_expression | IDENTIFIER ASSIGN equality_expression { $$ = clc_create_assign_expression($1, $3); } ; equality_expression : relational_expression | equality_expression EQ relational_expression { $$ = clc_create_binary_expression(EQ_EXPRESSION, $1, $3); } | equality_expression NE relational_expression { $$ = clc_create_binary_expression(NE_EXPRESSION, $1, $3); } ; relational_expression : additive_expression | relational_expression GT additive_expression { $$ = clc_create_binary_expression(GT_EXPRESSION, $1, $3); } | relational_expression GE additive_expression { $$ = clc_create_binary_expression(GE_EXPRESSION, $1, $3); } | relational_expression LT additive_expression { $$ = clc_create_binary_expression(LT_EXPRESSION, $1, $3); } | relational_expression LE additive_expression { $$ = clc_create_binary_expression(LE_EXPRESSION, $1, $3); } ; additive_expression : multiplicative_expression | additive_expression ADD multiplicative_expression { $$ = clc_create_binary_expression(ADD_EXPRESSION, $1, $3); } | additive_expression SUB multiplicative_expression { $$ = clc_create_binary_expression(SUB_EXPRESSION, $1, $3); } ; multiplicative_expression : unary_expression | multiplicative_expression MUL unary_expression { $$ = clc_create_binary_expression(MUL_EXPRESSION, $1, $3); } | multiplicative_expression DIV unary_expression { $$ = clc_create_binary_expression(DIV_EXPRESSION, $1, $3); } | multiplicative_expression MOD unary_expression { $$ = clc_create_binary_expression(MOD_EXPRESSION, $1, $3); } ; unary_expression : postfix_expression | SUB unary_expression { $$ = clc_create_minus_expression($2); } ; postfix_expression : primary_expression ; primary_expression : IDENTIFIER LP expression_list RP { $$ = clc_create_function_call_expression($1, $3); } | IDENTIFIER LP RP { $$ = clc_create_function_call_expression($1, NULL); } | if_expression | while_expression | LP expression RP { $$ = $2; } | IDENTIFIER { $$ = clc_create_identifier_expression($1); } | INT_LITERAL | DOUBLE_LITERAL ; if_expression : IF expression LC expression_list RC { $$ = clc_create_if_expression($2, $4, NULL); } | IF expression LC expression_list RC ELSE LC expression_list RC { $$ = clc_create_if_expression($2, $4, $8); } ; while_expression : WHILE expression LC expression_list RC { $$ = clc_create_while_expression($2, $4); } ; %%