diff --git a/tprcc/CMakeLists.txt b/tprcc/CMakeLists.txt index 99757cf..cb88bed 100644 --- a/tprcc/CMakeLists.txt +++ b/tprcc/CMakeLists.txt @@ -7,7 +7,9 @@ add_compile_options(-Wall -Wextra) aux_source_directory("src" SRC_DIR) aux_source_directory("src/tpr" SRC_TPR_DIR) -set (SRC_GENERATED "${CMAKE_CURRENT_BINARY_DIR}/tpr-parser.cpp" "${CMAKE_CURRENT_BINARY_DIR}/tpr-scanner.cpp") +set(TPR_PARSER_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated-tpr") + +set (SRC_GENERATED "${TPR_PARSER_DIR}/tpr-parser.cpp" "${TPR_PARSER_DIR}/tpr-scanner.cpp") set (SOURCES ${SRC_DIR} @@ -15,30 +17,30 @@ set (SOURCES ${SRC_GENERATED} ) + add_custom_command( DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/parser/tpr.l OUTPUT - ${CMAKE_CURRENT_BINARY_DIR}/tpr-scanner.cpp + ${TPR_PARSER_DIR}/tpr-scanner.cpp COMMAND - flex -+ -o "${CMAKE_CURRENT_BINARY_DIR}/tpr-scanner.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/parser/tpr.l" + mkdir -p "${TPR_PARSER_DIR}" && flex -+ -o "${TPR_PARSER_DIR}/tpr-scanner.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/parser/tpr.l" ) add_custom_command( DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/parser/tpr.ypp OUTPUT - ${CMAKE_CURRENT_BINARY_DIR}/tpr-parser.cpp + ${TPR_PARSER_DIR}/tpr-parser.cpp COMMAND - mkdir -p "${CMAKE_CURRENT_BINARY_DIR}/generated" && bison -o"${CMAKE_CURRENT_BINARY_DIR}/tpr-parser.cpp" --header="${CMAKE_CURRENT_BINARY_DIR}/generated/tpr-parser.hpp" "${CMAKE_CURRENT_SOURCE_DIR}/parser/tpr.ypp" + mkdir -p "${TPR_PARSER_DIR}/include/tpr-parser" && ${CMAKE_CURRENT_SOURCE_DIR}/bison-wrapper.sh "${TPR_PARSER_DIR}/tpr-parser.cpp" "${TPR_PARSER_DIR}/include/tpr-parser/tpr-parser.hpp" "${TPR_PARSER_DIR}/include/tpr-parser/location.hh" --header=tpr-parser.hpp ${CMAKE_CURRENT_SOURCE_DIR}/parser/tpr.ypp ) - - SET_SOURCE_FILES_PROPERTIES(${SRC_GENERATED} PROPERTIES GENERATED 1) add_executable(${PROJECT_NAME} ${SOURCES}) -target_include_directories(${PROJECT_NAME} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/generated") + +target_include_directories(${PROJECT_NAME} PRIVATE "${TPR_PARSER_DIR}/include" "${TPR_PARSER_DIR}/include/tpr-parser") target_include_directories(${PROJECT_NAME} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/include") # TEMPORARY FIx: -target_include_directories(${PROJECT_NAME} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}") \ No newline at end of file +#target_include_directories(${PROJECT_NAME} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}") \ No newline at end of file diff --git a/tprcc/bison-wrapper.sh b/tprcc/bison-wrapper.sh new file mode 100755 index 0000000..6857e2d --- /dev/null +++ b/tprcc/bison-wrapper.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +set -e + +# Usage: bison-wrapper.sh +if [[ $# -lt 4 ]]; then + echo "Error. Not enough parameters" + exit -1 +fi + +cfile=$1 +shift +include=$1 +shift +location=$1 +shift + +tmpdir=`mktemp -d` +cd $tmpdir +echo "Using $tmpdir" +echo cp *.tab.cpp "$cfile" +echo cp *.hpp "$include" +echo cp location.hh "$location" + +bison $@ +cp *.tab.cpp "$cfile" +cp *.hpp "$include" +cp location.hh "$location" + + +rm -rfv "$tmpdir" \ No newline at end of file diff --git a/tprcc/include/tpr/tpr-scanner.hpp b/tprcc/include/tpr/tpr-scanner.hpp index 88e7a0b..ebbc873 100644 --- a/tprcc/include/tpr/tpr-scanner.hpp +++ b/tprcc/include/tpr/tpr-scanner.hpp @@ -6,8 +6,8 @@ #include #endif -#include "tpr-parser.hpp" -#include "location.hh" +#include +#include namespace tpr { diff --git a/tprcc/include/tpr/tpr-types.hpp b/tprcc/include/tpr/tpr-types.hpp index 72b62cb..84287cc 100644 --- a/tprcc/include/tpr/tpr-types.hpp +++ b/tprcc/include/tpr/tpr-types.hpp @@ -19,26 +19,17 @@ enum class CommandType { digio_wait, }; -struct CommandSpec { - CommandType type; - std::vector param_is_whole_num; -}; class TprCommand { private: - static const CommandSpec m_specs[11]; - CommandType m_type; std::vector m_parameters; - bool is_whole_number(float num) const; public: TprCommand(CommandType type); TprCommand(CommandType type, const std::vector ¶ms); TprCommand(CommandType type, const std::vector &¶ms); - - bool check_command(bool print_status) const; }; diff --git a/tprcc/parser/tpr.l b/tprcc/parser/tpr.l index 19afde4..36f424a 100644 --- a/tprcc/parser/tpr.l +++ b/tprcc/parser/tpr.l @@ -19,7 +19,9 @@ using token = tpr::TempProfileParser::token; NEWLINE "\n"|"\r\n" COMMENT_LINE "#".*\n SPACE "\t"|" " -NUM [-+]?([0-9]*\.[0-9]+|[0-9]+) + +NUM_INT [-+]?([0-9]+) +NUM_FLOAT [-+]?([0-9]*\.[0-9]+) %% %{ @@ -29,7 +31,8 @@ NUM [-+]?([0-9]*\.[0-9]+|[0-9]+) <*>{SPACE} { /*Ignore spaces */} {COMMENT_LINE} {loc->lines(); return token::lineend;} {NEWLINE} {loc->lines(); return token::lineend;} -{NUM} {yylval->build(std::stof(std::string(yytext))); return token::number;} +{NUM_FLOAT} {yylval->build(std::stof(std::string(yytext))); return token::number_float;} +{NUM_INT} {yylval->build(std::stof(std::string(yytext))); return token::number_int;} pid_conf { return token::kw_pid_conf; } temp_set { return token::kw_temp_set; } diff --git a/tprcc/parser/tpr.ypp b/tprcc/parser/tpr.ypp index 3d4cd1a..39b2884 100644 --- a/tprcc/parser/tpr.ypp +++ b/tprcc/parser/tpr.ypp @@ -5,6 +5,7 @@ %define api.namespace {tpr} %define api.parser.class {TempProfileParser} + %define parse.error verbose %code requires{ @@ -22,6 +23,7 @@ #include #include #include + #include #undef yylex #define yylex scanner.yylex } @@ -30,7 +32,8 @@ %locations %start tpr_file -%token number +%token number_float +%token number_int %token lineend %token kw_pid_conf %token kw_temp_set @@ -45,6 +48,8 @@ %token kw_digio_wait %token unexpected_input +%typenumber number_truncated + %% tpr_file: tpr_command @@ -81,17 +86,25 @@ cmd_wait_time: kw_wait_time number; cmd_temp_ramp: kw_temp_ramp number number; -cmd_beep: kw_beep number; +cmd_beep: kw_beep number_truncated; cmd_temp_off: kw_temp_off; cmd_clear_flags: kw_clear_flags; -cmd_digio_conf: kw_digio_conf number number; +cmd_digio_conf: kw_digio_conf number_truncated number_truncated; -cmd_digio_set: kw_digio_set number number; +cmd_digio_set: kw_digio_set number_truncated number_truncated; -cmd_digio_wait: kw_digio_wait number number; +cmd_digio_wait: kw_digio_wait number_truncated number_truncated; + +number_truncated: number_float {$$ = $1; std::cerr << "[WARN] Floating point number " << $1 << " will be truncated to an integer (" << (int)$1 << ") at location (" << @1 << ")" << std::endl;} + | number_int {$$ = $1;} + ; + +number: number_float {$$ = $1;} + | number_int {$$ = $1;} + ; %% diff --git a/tprcc/src/tpr/tpr-types.cpp b/tprcc/src/tpr/tpr-types.cpp index 40b3d49..f4ee86f 100644 --- a/tprcc/src/tpr/tpr-types.cpp +++ b/tprcc/src/tpr/tpr-types.cpp @@ -1,3 +1,4 @@ +#include "tprcc/logger.hpp" #include #include #include @@ -5,19 +6,6 @@ namespace tpr { -const CommandSpec TprCommand::m_specs[11] = { - {.type = CommandType::beep, .param_is_whole_num = std::vector{true}}, - {.type = CommandType::clear_flags, .param_is_whole_num = std::vector{}}, - {.type = CommandType::digio_conf, .param_is_whole_num = std::vector{true, true}}, - {.type = CommandType::digio_set, .param_is_whole_num = std::vector{true, true}}, - {.type = CommandType::digio_wait, .param_is_whole_num = std::vector{true, true}}, - {.type = CommandType::wait_temp, .param_is_whole_num = std::vector{false}}, - {.type = CommandType::wait_time, .param_is_whole_num = std::vector{false}}, - {.type = CommandType::temp_off, .param_is_whole_num = std::vector{}}, - {.type = CommandType::temp_ramp, .param_is_whole_num = std::vector{true, true}}, - {.type = CommandType::pid_conf, .param_is_whole_num = std::vector{false, false, false, false, false, false}}, - {.type = CommandType::temp_set, .param_is_whole_num = std::vector{false}} -}; TprCommand::TprCommand(CommandType type) { @@ -34,37 +22,5 @@ TprCommand::TprCommand(CommandType type, const std::vector &¶ms) : Tp m_parameters = std::move(params); } -bool TprCommand::is_whole_number(float num) const -{ - if (floor(num) == num) - return true; - else - return false; -} - -bool TprCommand::check_command(bool print_status) const -{ - for (unsigned int i = 0; i < 11; i++) { - if (m_specs[i].type == m_type) { - /* Check size of param vector. This is just to be safe and should never fail */ - if (m_parameters.size() != m_specs[i].param_is_whole_num.size()) { - std::cerr << "[ERR] Parameter count mismatch in command. This is a compiler bug!" << std::endl; - std::abort(); - } - - for (unsigned int param_idx = 0; i < m_parameters.size(); i++) { - if (is_whole_number(m_parameters[param_idx]) ^ m_specs[i].param_is_whole_num[param_idx]) { - if (print_status) { - // TODO:::: Continue here!! - } - return false; - } - } - return true; - } - } - - return false; -} } \ No newline at end of file