From 5190e3116bc438b8ba7d1b6158d91c862a90dbe0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Wed, 17 Jan 2024 20:28:40 +0100 Subject: [PATCH] Add C++ template for lex / yacc setup --- temp-profile-checker/.gitignore | 2 + temp-profile-checker/CMakeLists.txt | 41 ++++++ .../include/tpr/tpr-scanner.hpp | 38 +++++ temp-profile-checker/parser/Makefile | 43 ------ temp-profile-checker/parser/lang.lex | 45 ------ temp-profile-checker/parser/lang.yacc | 137 ------------------ temp-profile-checker/parser/tpr.l | 26 ++++ temp-profile-checker/parser/tpr.ypp | 48 ++++++ temp-profile-checker/src/main.cpp | 8 + 9 files changed, 163 insertions(+), 225 deletions(-) create mode 100644 temp-profile-checker/.gitignore create mode 100644 temp-profile-checker/CMakeLists.txt create mode 100644 temp-profile-checker/include/tpr/tpr-scanner.hpp delete mode 100644 temp-profile-checker/parser/Makefile delete mode 100644 temp-profile-checker/parser/lang.lex delete mode 100644 temp-profile-checker/parser/lang.yacc create mode 100644 temp-profile-checker/parser/tpr.l create mode 100644 temp-profile-checker/parser/tpr.ypp create mode 100644 temp-profile-checker/src/main.cpp diff --git a/temp-profile-checker/.gitignore b/temp-profile-checker/.gitignore new file mode 100644 index 0000000..228cff3 --- /dev/null +++ b/temp-profile-checker/.gitignore @@ -0,0 +1,2 @@ +*.o +build/* diff --git a/temp-profile-checker/CMakeLists.txt b/temp-profile-checker/CMakeLists.txt new file mode 100644 index 0000000..167ecfc --- /dev/null +++ b/temp-profile-checker/CMakeLists.txt @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 3.8) +project(tprcc LANGUAGES CXX) + +set (CMAKE_CXX_STANDARD 17) + +aux_source_directory("src" SRC_DIR) + +set (SRC_GENERATED "${CMAKE_CURRENT_BINARY_DIR}/tpr-parser.cpp" "${CMAKE_CURRENT_BINARY_DIR}/tpr-scanner.cpp") + +set (SOURCES + ${SRC_DIR} + ${SRC_GENERATED} +) + +add_custom_command( + DEPENDS + ${CMAKE_CURRENT_SOURCE_DIR}/parser/tpr.l + OUTPUT + ${CMAKE_CURRENT_BINARY_DIR}/tpr-scanner.cpp + COMMAND + flex -+ -o "${CMAKE_CURRENT_BINARY_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 + 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" +) + + + +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 "${CMAKE_CURRENT_SOURCE_DIR}/include") +# TEMPORARY FIx: +target_include_directories(${PROJECT_NAME} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}") \ No newline at end of file diff --git a/temp-profile-checker/include/tpr/tpr-scanner.hpp b/temp-profile-checker/include/tpr/tpr-scanner.hpp new file mode 100644 index 0000000..74a7446 --- /dev/null +++ b/temp-profile-checker/include/tpr/tpr-scanner.hpp @@ -0,0 +1,38 @@ +#ifndef _TPR_SCANNER_HPP_ +#define _TPR_SCANNER_HPP_ + + +#if ! defined(yyFlexLexerOnce) +#include +#endif + +#include "tpr-parser.hpp" +#include "location.hh" + +namespace tpr { + +class TempProfileScanner : public yyFlexLexer{ + public: + + TempProfileScanner(std::istream *in) : yyFlexLexer(in) { + }; + virtual ~TempProfileScanner() {}; + + //get rid of override virtual function warning + using FlexLexer::yylex; + + virtual + int yylex( tpr::TempProfileParser::semantic_type * const lval, + tpr::TempProfileParser::location_type *location ); + // YY_DECL defined in mc_lexer.l + // Method body created by flex in mc_lexer.yy.cc + + private: + /* yyval ptr */ + tpr::TempProfileParser::semantic_type *yylval = nullptr; +}; + +} /* end namespace MC */ + + +#endif /* _TPR_SCANNER_HPP_ */ \ No newline at end of file diff --git a/temp-profile-checker/parser/Makefile b/temp-profile-checker/parser/Makefile deleted file mode 100644 index 17e19ab..0000000 --- a/temp-profile-checker/parser/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -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 deleted file mode 100644 index ea5548e..0000000 --- a/temp-profile-checker/parser/lang.lex +++ /dev/null @@ -1,45 +0,0 @@ -%{ -#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 deleted file mode 100644 index 5747bda..0000000 --- a/temp-profile-checker/parser/lang.yacc +++ /dev/null @@ -1,137 +0,0 @@ -%{ -#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; - }; -%% - diff --git a/temp-profile-checker/parser/tpr.l b/temp-profile-checker/parser/tpr.l new file mode 100644 index 0000000..b4dd9dc --- /dev/null +++ b/temp-profile-checker/parser/tpr.l @@ -0,0 +1,26 @@ +%{ +#include +#undef YY_DECL +#define YY_DECL int tpr::TempProfileScanner::yylex(tpr::TempProfileParser::semantic_type * const lval, tpr::TempProfileParser::location_type *loc ) + +#define YY_USER_ACTION loc->step(); loc->columns(yyleng); + +%} + +%option yyclass="tpr::TempProgileScanner" +%option noyywrap +%option never-interactive +%option c++ + +/* Predefined rules */ +NEWLINE "\n"|"\r\n" +SPACE " "|"\t"|"\f" +COMMENT_BEGIN "/*" +COMMENT_END "*/" +COMMENT_LINE "//".*\n + +%% + +SPACE {return 0;} + +%% diff --git a/temp-profile-checker/parser/tpr.ypp b/temp-profile-checker/parser/tpr.ypp new file mode 100644 index 0000000..7406de6 --- /dev/null +++ b/temp-profile-checker/parser/tpr.ypp @@ -0,0 +1,48 @@ + +%language "c++" +%require "3.2" +%defines +%define api.namespace {tpr} +%define api.parser.class {TempProfileParser} + +%define parse.error verbose + +%code requires{ + namespace tpr { + class TempProfileScanner; +} +} + +%parse-param { TempProfileScanner &scanner } + +%code { + #include + #include + #include + #include + #include + #include + #undef yylex + #define yylex scanner.yylex +} + +%define api.value.type variant +%locations +%start tpr_file + +%token foo + +%% + +tpr_file: foo + | tpr_file foo + ; + + +%% + +void tpr::TempProfileParser::error(const location_type &l, const std::string &err_message) +{ + std::cerr << "Error " << err_message << " at " << l << std::endl; + std::abort(); +} \ No newline at end of file diff --git a/temp-profile-checker/src/main.cpp b/temp-profile-checker/src/main.cpp new file mode 100644 index 0000000..9bcdbe2 --- /dev/null +++ b/temp-profile-checker/src/main.cpp @@ -0,0 +1,8 @@ +#include + +int main(int argc, char **argv) +{ + std::cout << "Hello world" << std::endl; + + return 0; +} \ No newline at end of file