%{ #include #include extern int yylineno; extern int yylex(); extern int yyparse(); void yyerror(const char *str) { fprintf(stderr, "Error: %s, line %d\n", str, yylineno); } int yywrap() { return 1; } int main() { yyparse(); return 0; } %} %locations %token COMMENT PL_PID_CONF PL_SET_TEMP PL_WAIT_FOR_TEMP PL_WAIT_FOR_TIME PL_SET_RAMP PL_LOUDSPEAKER_SET PL_OFF PL_CLEAR_FLAGS PL_DIGIO_CONF PL_DIGIO_SET PL_DIGIO_WAIT NEWLINE LITERAL %token NUMBER %token INT_NUMBER %type any_num %union { int int_value; float float_value; } %% program: /* empty */ | program command | program NEWLINE | program cmt_line ; command: command_core NEWLINE | command_core cmt_line ; command_core: pid_conf | temp_set | wait_time | wait_temp | temp_ramp | beep | temp_off | clear_flags | digio_conf | digio_set | digio_wait; pid_conf: PL_PID_CONF any_num any_num any_num any_num any_num any_num { printf("PID Config\n"); } ; temp_set: PL_SET_TEMP any_num { printf("Target temp set: %f\n", $2); } ; wait_time: PL_WAIT_FOR_TIME any_num { printf("Wait for %f seconds\n", $2); } ; wait_temp: PL_WAIT_FOR_TEMP any_num { printf("Wait for temperature %f\n", $2); } ; temp_ramp: PL_SET_RAMP any_num any_num { printf("Temperature ramp. Target %f, duration: %f\n", $2, $3); } ; cmt_line: COMMENT NEWLINE { printf("Comment line detected\n"); }; beep: PL_LOUDSPEAKER_SET INT_NUMBER { printf("Beep: %d\n", $2); } | PL_LOUDSPEAKER_SET NUMBER { printf("Warning: Float value casted to int!\n"); printf("Beep %u\n", (unsigned int)$2); }; temp_off: PL_OFF { printf("Turn off oven\n"); } ; clear_flags: PL_CLEAR_FLAGS { printf("Clear flags\n"); } ; digio_conf: PL_DIGIO_CONF INT_NUMBER INT_NUMBER { printf("Configure digio pin\n"); }; digio_set: PL_DIGIO_SET INT_NUMBER INT_NUMBER { printf("Configure digio pin\n"); }; digio_wait: PL_DIGIO_WAIT INT_NUMBER INT_NUMBER { printf("Configure digio pin\n"); }; /* Matches any number format that can be interpreted as float */ any_num : NUMBER | INT_NUMBER { $$ = (float)$1; }; %%