diff --git a/temp-profile-checker/parser/Makefile b/temp-profile-checker/parser/Makefile new file mode 100644 index 0000000..17e19ab --- /dev/null +++ b/temp-profile-checker/parser/Makefile @@ -0,0 +1,43 @@ +LEXER := flex +YACC := bison +CC := gcc + +YACC_FLAGS := -yd +LEXER_FLAGS := + +LANG_NAME := lang + + +ifneq ($(VERBOSE),true) +QUIET=@ +else +QUIET= +endif + +default: test + +y.tab.c: $(LANG_NAME).yacc + $(QUIET)echo "[$(YACC)] $@" + $(QUIET)$(YACC) $(YACC_FLAGS) $< + +lex.yy.c: $(LANG_NAME).lex + $(QUIET)echo "[$(LEXER)] $@" + $(QUIET)$(LEXER) $^ + +test: y.tab.c lex.yy.c + $(QUIET)echo "[CC] $@" + $(QUIET)$(CC) -o $@ $^ + + + +.PHONY: clean run + +run: test + ./test + +clean: + $(QUIET)echo "Clean up..." + $(QUIET)rm -f *.c *.o y.tab.h test + + + diff --git a/temp-profile-checker/parser/lang.lex b/temp-profile-checker/parser/lang.lex new file mode 100644 index 0000000..ea5548e --- /dev/null +++ b/temp-profile-checker/parser/lang.lex @@ -0,0 +1,45 @@ +%{ +#include +#include "y.tab.h" +%} + +/* +static const struct pl_command_list_map cmd_list_map[_PL_NUM_CMDS] = { + {PL_PID_CONF, "pid_conf", 6u}, + {PL_SET_TEMP, "temp_set", 1u}, + {PL_WAIT_FOR_TEMP, "wait_temp", 1u}, + {PL_WAIT_FOR_TIME, "wait_time", 1u}, + {PL_SET_RAMP, "temp_ramp", 2u}, + {PL_LOUDSPEAKER_SET, "beep", 1u}, + {PL_OFF, "temp_off", 0u}, + {PL_CLEAR_FLAGS, "clear_flags", 0u}, + {PL_DIGIO_CONF, "digio_conf", 2u}, + {PL_DIGIO_SET, "digio_set", 2u}, + {PL_DIGIO_WAIT, "digio_wait", 2u}, +}; +*/ + +%option yylineno + +%% + +#[^\n]* return COMMENT; +pid_conf return PL_PID_CONF; +temp_set return PL_SET_TEMP; +wait_temp return PL_WAIT_FOR_TEMP; +wait_time return PL_WAIT_FOR_TIME; +temp_ramp return PL_SET_RAMP; +beep return PL_LOUDSPEAKER_SET; +temp_off return PL_OFF; +clear_flags return PL_CLEAR_FLAGS; +digio_conf return PL_DIGIO_CONF; +digio_set return PL_DIGIO_SET; +digio_wait return PL_DIGIO_WAIT; +[+-]?[0-9]+ yylval.int_value=atoi(yytext); return INT_NUMBER; +[+-]?[0-9]+[.]?[0-9]* yylval.float_value=atof(yytext); return NUMBER; +[ \t]+ /* Ignore whitespaces */; +[\r]?\n return NEWLINE; + +[^\t\n #]+ return LITERAL; + +%% diff --git a/temp-profile-checker/parser/lang.yacc b/temp-profile-checker/parser/lang.yacc new file mode 100644 index 0000000..5747bda --- /dev/null +++ b/temp-profile-checker/parser/lang.yacc @@ -0,0 +1,137 @@ +%{ +#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; + }; +%% +