%{ #include #include "rust.h" #define YYSTYPE BST int yyerror(char*); extern Variables global_variables; %} %token NUMBER IDENT ASSIGN %token PLUS MINUS MUL DIV %token LESSER GREATER LEFT RIGHT LCURL RCURL COMMA COLON LSQUARE RSQUARE %token END SYNTAXERROR %left PLUS MINUS %left MUL DIV %left LESSER GREATER %left NEG POS SQRT %start Input %% Input: /* empty input */ | Input Line ; Line: END // echo expressions to stdout | Expression END { print(bst_eval($1, &global_variables)); } // assignment | IDENT ASSIGN Expression END { insert_variable(&global_variables, $1, bst_eval($3, &global_variables)); } | SYNTAXERROR END { fprintf(stderr, "syntax error\n"); } ; // expressions are anything that can be evaluated Expression: // terminal nodes: a literal number and a variable NUMBER { $$ = yylval; } | IDENT { $$ = yylval; } // term separators | Expression PLUS Expression { $$ = add($1, $3); } | Expression MINUS Expression { $$ = sub($1, $3); } // mul/div | Expression MUL Expression { $$ = mul($1, $3); } | LEFT Expression RIGHT LEFT Expression RIGHT { $$ = mul($2, $5); } | Expression DIV Expression { $$ = divide($1, $3); } // unary + and - | MINUS Expression %prec NEG { $$ = neg($2); } | PLUS Expression %prec POS { $$ = $2; } | SQRT Expression { $$ = sqrt($2); } // parenthesis | LEFT Expression RIGHT { $$ = $2; } // there are a few ways to make a distribution // 1. standard deviation and mean // { u, o } | LCURL Expression COMMA Expression RCURL { $$ = two_var_distr($2, $4); } // 2. association // [ a: b, c: d, e: f ] | LSQUARE AssoList RSQUARE { $$ = $2; } | Expression LESSER Expression { $$ = less($1, $3); } | Expression GREATER Expression { $$ = more($1, $3); } ; AssoList: /* empty list */ { $$ = empty_list(); } | NonEmpyList { $$ = $1; } ; NonEmpyList: Expression COLON Expression { $$ = np_pair($1, $3); } | NonEmpyList COMMA Expression COLON Expression { $$ = np_pair_push($1, $3, $5); } ; %% int yyerror(char* msg) { return printf("%s\n", msg); }