-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from sillydan1/feature/basic-initial-impl
Feature/basic initial impl
- Loading branch information
Showing
25 changed files
with
813 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
name: CMake Pipeline | ||
|
||
on: | ||
pull_request: | ||
branches: | ||
- master | ||
push: | ||
branches: | ||
- master | ||
|
||
env: | ||
BUILD_TYPE: Release | ||
GIT_SUBMODULE_STRATEGY: recursive | ||
|
||
jobs: | ||
build-linux: | ||
if: ${{ github.event.pull_request.draft == false }} | ||
name: Build For Linux Systems | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout Repository | ||
uses: actions/checkout@v2 | ||
- name: Initialize Submodules | ||
uses: snickerbockers/submodules-init@v4 | ||
- name: Install dependencies | ||
run: sudo apt-get install -y flex bison make | ||
- name: Create Build Environment | ||
run: cmake -E make_directory ${{github.workspace}}/build | ||
- name: Configure CMake | ||
shell: bash | ||
working-directory: ${{github.workspace}}/build | ||
run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE | ||
- name: Build | ||
working-directory: ${{github.workspace}}/build | ||
shell: bash | ||
# Execute the build. You can specify a specific target with "--target <NAME>" | ||
run: cmake --build . --config $BUILD_TYPE -j$(nproc) | ||
- name: Upload Artifact | ||
uses: actions/upload-artifact@v2 | ||
with: | ||
name: library | ||
path: ${{ github.workspace }}/build/expr | ||
build-windows: | ||
if: ${{ github.event.pull_request.draft == false }} | ||
name: Build For MS Windows Systems | ||
runs-on: windows-latest | ||
env: | ||
CC: x86_64-w64-mingw32-gcc | ||
CXX: x86_64-w64-mingw32-g++ | ||
LD: x86_64-w64-mingw32-ld | ||
AR: x86_64-w64-mingw32-ar | ||
AS: x86_64-w64-mingw32-as | ||
NM: x86_64-w64-mingw32-nm | ||
STRIP: x86_64-w64-mingw32-strip | ||
RANLIB: x86_64-w64-mingw32-ranlib | ||
DLLTOOL: x86_64-w64-mingw32-dlltool | ||
OBJDUMP: x86_64-w64-mingw32-objdump | ||
RESCOMP: x86_64-w64-mingw32-windres | ||
steps: | ||
- name: Setup CygWin | ||
uses: egor-tensin/setup-cygwin@v3 | ||
with: | ||
packages: flex bison mingw-w64-gcc | ||
- name: Install MinGW | ||
uses: egor-tensin/setup-mingw@v2 | ||
with: | ||
cygwin: 1 | ||
- name: Checkout Repository | ||
uses: actions/checkout@v2 | ||
- name: Initialize Submodules | ||
uses: snickerbockers/submodules-init@v4 | ||
- name: Create Build Environment | ||
run: cmake -E make_directory ${{github.workspace}}/build | ||
- name: Configure CMake | ||
shell: bash | ||
working-directory: ${{github.workspace}}/build | ||
run: cmake $GITHUB_WORKSPACE -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-g++ -DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc | ||
- name: Build | ||
working-directory: ${{github.workspace}}/build | ||
shell: bash | ||
# Execute the build. You can specify a specific target with "--target <NAME>" | ||
run: cmake --build . --config $BUILD_TYPE -j 8 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,3 +30,9 @@ | |
*.exe | ||
*.out | ||
*.app | ||
|
||
# build folders | ||
cmake-build-* | ||
.idea | ||
build | ||
bin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
cmake_minimum_required(VERSION 3.0) | ||
project(expr VERSION 1.0.0) | ||
include(cmake/CPM.cmake) | ||
configure_file(src/config.h.in config.h) | ||
set(CMAKE_CXX_STANDARD 20) | ||
set(CXX_STANDARD_REQUIRED ON) | ||
|
||
find_package(FLEX REQUIRED) | ||
find_package(BISON REQUIRED) | ||
CPMAddPackage("gh:sillydan1/overload#1.0.0") | ||
BISON_TARGET(expr_parser src/parser/parser.y ${CMAKE_CURRENT_BINARY_DIR}/parser.cpp) | ||
FLEX_TARGET(expr_scanner src/parser/scanner.l ${CMAKE_CURRENT_BINARY_DIR}/scanner.cpp) | ||
ADD_FLEX_BISON_DEPENDENCY(expr_scanner expr_parser) | ||
|
||
include_directories( | ||
${CMAKE_CURRENT_BINARY_DIR}/_deps/overload-src/include | ||
${CMAKE_CURRENT_BINARY_DIR} | ||
include | ||
src | ||
) | ||
add_library(${PROJECT_NAME} | ||
${BISON_expr_parser_OUTPUTS} | ||
${FLEX_expr_scanner_OUTPUTS} | ||
src/parser/driver.cpp | ||
src/symbol_table.cpp | ||
src/operations/add.cpp | ||
src/operations/subtract.cpp | ||
src/operations/multiply.cpp | ||
src/operations/divide.cpp | ||
src/operations/boolean.cpp | ||
) | ||
add_executable(${PROJECT_NAME}_demo | ||
src/main.cpp | ||
) | ||
target_link_libraries(${PROJECT_NAME}_demo ${PROJECT_NAME}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,34 @@ | ||
# expr | ||
An expression parser for C++ | ||
A variable environment manipulation expression parser written in C++20 with flex and bison. | ||
|
||
## Examples | ||
This project comes with an demo example command line interface called `expr_demo` so that you | ||
can test if the project supports your expression syntax. This example cli can | ||
``` | ||
./expr_demo - | ||
a := (1 + 2 + 3 + 4); | ||
b := one + two; | ||
^D | ||
a :-> 6 i | ||
b :-> 3 i | ||
``` | ||
|
||
You can also use the project directly in code like so: | ||
```c++ | ||
try { // Errors are handled with exceptions | ||
symbol_map_t env{}; // Initialize an environment | ||
driver drv{env}; // Initialize the expr driver with the environment | ||
if (!drv.parse("a := 32 + 2")) // Parse your expressions | ||
std::cout << drv.result; // Print the result | ||
} catch(const std::exception& e) { // Parsing went wrong. Maybe bad syntax, type error or identifier not in environment | ||
std::cout << e.what(); // Print what went wrong | ||
} | ||
``` | ||
|
||
## Compile | ||
You should be able to compile with cmake like so: | ||
``` | ||
mkdir bin && cd bin | ||
cmake .. | ||
make | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
set(CPM_DOWNLOAD_VERSION 0.35.0) | ||
|
||
if(CPM_SOURCE_CACHE) | ||
# Expand relative path. This is important if the provided path contains a tilde (~) | ||
get_filename_component(CPM_SOURCE_CACHE ${CPM_SOURCE_CACHE} ABSOLUTE) | ||
set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") | ||
elseif(DEFINED ENV{CPM_SOURCE_CACHE}) | ||
set(CPM_DOWNLOAD_LOCATION "$ENV{CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake") | ||
else() | ||
set(CPM_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/cmake/CPM_${CPM_DOWNLOAD_VERSION}.cmake") | ||
endif() | ||
|
||
if(NOT (EXISTS ${CPM_DOWNLOAD_LOCATION})) | ||
message(STATUS "Downloading CPM.cmake to ${CPM_DOWNLOAD_LOCATION}") | ||
file(DOWNLOAD | ||
https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake | ||
${CPM_DOWNLOAD_LOCATION} | ||
) | ||
endif() | ||
|
||
include(${CPM_DOWNLOAD_LOCATION}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#ifndef EXPR_OPERATIONS_H | ||
#define EXPR_OPERATIONS_H | ||
#include "operations/add.h" | ||
#include "operations/subtract.h" | ||
#include "operations/multiply.h" | ||
#include "operations/divide.h" | ||
#include "operations/boolean.h" | ||
#endif //EXPR_OPERATIONS_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#ifndef EXPR_ADD_H | ||
#define EXPR_ADD_H | ||
#include "symbol_table.h" | ||
symbol_value_t add(const symbol_value_t& a, const symbol_value_t& b); | ||
symbol_value_t operator+(const symbol_value_t& a, const symbol_value_t& b); | ||
#endif //EXPR_ADD_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#ifndef EXPR_BOOLEAN_H | ||
#define EXPR_BOOLEAN_H | ||
#include "symbol_table.h" | ||
symbol_value_t and_(const symbol_value_t& a, const symbol_value_t& b); | ||
symbol_value_t or_(const symbol_value_t& a, const symbol_value_t& b); | ||
symbol_value_t not_(const symbol_value_t& a); | ||
symbol_value_t operator&&(const symbol_value_t& a, const symbol_value_t& b); | ||
symbol_value_t operator||(const symbol_value_t& a, const symbol_value_t& b); | ||
symbol_value_t operator!(const symbol_value_t& a); | ||
#endif //EXPR_BOOLEAN_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#ifndef EXPR_DIVIDE_H | ||
#define EXPR_DIVIDE_H | ||
#include "symbol_table.h" | ||
symbol_value_t divide(const symbol_value_t& a, const symbol_value_t& b); | ||
symbol_value_t operator/(const symbol_value_t& a, const symbol_value_t& b); | ||
#endif //EXPR_DIVIDE_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#ifndef EXPR_MULTIPLY_H | ||
#define EXPR_MULTIPLY_H | ||
#include "symbol_table.h" | ||
symbol_value_t multiply(const symbol_value_t& a, const symbol_value_t& b); | ||
symbol_value_t operator*(const symbol_value_t& a, const symbol_value_t& b); | ||
#endif //EXPR_MULTIPLY_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
#ifndef EXPR_SUBTRACT_H | ||
#define EXPR_SUBTRACT_H | ||
#include "symbol_table.h" | ||
symbol_value_t subtract(const symbol_value_t& a, const symbol_value_t& b); | ||
symbol_value_t operator-(const symbol_value_t& a, const symbol_value_t& b); | ||
#endif //EXPR_SUBTRACT_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
#ifndef EXPR_DRIVER_H | ||
#define EXPR_DRIVER_H | ||
#include <string> | ||
#include "symbol_table.h" | ||
#include "parser.hpp" | ||
#define YY_DECL yy::parser::symbol_type yylex (driver& drv) | ||
YY_DECL; | ||
|
||
struct driver { | ||
explicit driver(const symbol_map_t& env); | ||
const symbol_map_t& environment{}; | ||
symbol_map_t result{}; | ||
|
||
int parse(const std::string& f); | ||
std::string file; | ||
bool trace_parsing; | ||
|
||
void scan_begin(); | ||
void scan_end(); | ||
bool trace_scanning; | ||
yy::location location; | ||
}; | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
#ifndef EXPR_SYMBOL_TABLE_H | ||
#define EXPR_SYMBOL_TABLE_H | ||
#include <variant> | ||
#include <map> | ||
#include <functional> | ||
#include <iostream> | ||
|
||
using underlying_symbol_value_t = std::variant<int,float,bool,std::string>; | ||
struct symbol_value_t : public underlying_symbol_value_t { | ||
symbol_value_t() = default; | ||
template<typename T> | ||
symbol_value_t(const T& x) : underlying_symbol_value_t(x) {} | ||
template<typename T> | ||
symbol_value_t& operator=(const T& t) { | ||
this->underlying_symbol_value_t::operator=(t); | ||
return *this; | ||
} | ||
}; | ||
using symbol_map_t = std::map<std::string, symbol_value_t>; | ||
std::ostream& operator<<(std::ostream& os, const symbol_value_t& v); | ||
std::ostream& operator<<(std::ostream& os, const symbol_map_t& m); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#ifndef EXPR_CONFIG_H_IN_H | ||
#define EXPR_CONFIG_H_IN_H | ||
#define PROJECT_NAME "@PROJECT_NAME@" | ||
#define PROJECT_VER "@PROJECT_VERSION@" | ||
#define PROJECT_VER_MAJOR @PROJECT_VERSION_MAJOR@ | ||
#define PROJECT_VER_MINOR @PROJECT_VERSION_MINOR@ | ||
#define PROJECT_VER_PATCH @PROJECT_VERSION_PATCH@ | ||
#endif //EXPR_CONFIG_H_IN_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
#include <iostream> | ||
#include "parser/driver.h" | ||
#include "config.h" | ||
|
||
int main (int argc, char *argv[]) { | ||
symbol_map_t env{}; | ||
env["false_b"] = false; | ||
env["one_i"] = 1; | ||
env["two_f"] = 2.0f; | ||
env["hello_s"] = "Hello"; | ||
std::cout | ||
<< "=================== Welcome to the " << PROJECT_NAME << " v" << PROJECT_VER << " demo ==================\n" | ||
<< "USAGE: " << argv[0] << " [OPTIONS] EXPR_STR or '-' for using stdin\n" | ||
<< "OPTIONS:\n" | ||
<< " -p\t| enable tracing for the parser\n" | ||
<< " -s\t| enable tracing for the scanner\n" | ||
<< "\n" | ||
<< "For this demo, a simple environment has been provided. (see below)\n" | ||
<< "You can use these variables on the right-hand-side of your expressions\n" | ||
<< "like so: 'a := one + 30'. Variable assignments are done atomically, so\n" | ||
<< "statements like these: 'a := 2 ; b := a + 1' will not compile, because\n" | ||
<< "the variable 'a' is not defined before AFTER all assignments have been\n" | ||
<< "evaluated and performed.\n" | ||
<< "PROVIDED ENVIRONMENT:\n" | ||
<< env | ||
<< "======================================================================\n" << std::endl; | ||
try { | ||
int res = 0; | ||
driver drv{env}; | ||
for (int i = 1; i < argc; ++i) { | ||
if (argv[i] == std::string("-p")) | ||
drv.trace_parsing = true; | ||
else if (argv[i] == std::string("-s")) | ||
drv.trace_scanning = true; | ||
else if (!drv.parse(argv[i])) | ||
std::cout << drv.result; | ||
else | ||
res = 1; | ||
} | ||
return res; | ||
} catch(const std::exception& e) { | ||
std::cout << e.what() << std::endl; | ||
return 1; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#include "operations/add.h" | ||
#include "util.h" | ||
#include <sstream> | ||
|
||
template<typename T1, typename T2> | ||
auto t_add(const T1&, const T2&) { | ||
throw std::domain_error((std::ostringstream{} << "Unable to add type " << typeid(T1).name() << " and " << typeid(T2).name()).str()); | ||
return nullptr; // Must return something | ||
} | ||
template<> auto t_add(const int& x, const int& y) { | ||
return x + y; | ||
} | ||
template<> auto t_add(const float& x, const int& y) { | ||
return x + y; | ||
} | ||
template<> auto t_add(const int& x, const float& y) { | ||
return x + y; | ||
} | ||
template<> auto t_add(const float& x, const float& y) { | ||
return x + y; | ||
} | ||
template<> auto t_add(const std::string& x, const std::string& y) { | ||
return x + y; | ||
} | ||
|
||
symbol_value_t add(const symbol_value_t& a, const symbol_value_t& b) { | ||
symbol_value_t res{}; | ||
FUNC_IMPL(a, t_add, b, res); | ||
return res; | ||
} | ||
symbol_value_t operator+(const symbol_value_t& a, const symbol_value_t& b) { | ||
return add(a,b); | ||
} |
Oops, something went wrong.