diff --git a/recursiveDescentParsers/cplusplus/interpret++/.gitignore b/recursiveDescentParsers/cplusplus/interpret++/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..c8058545a33d4bdc3c2be1d1db929b22f571edea
--- /dev/null
+++ b/recursiveDescentParsers/cplusplus/interpret++/.gitignore
@@ -0,0 +1,4 @@
+interpret++
+*.o
+.deps/
+
diff --git a/recursiveDescentParsers/cplusplus/interpret++/Makefile b/recursiveDescentParsers/cplusplus/interpret++/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..3471232ec42ff88aeacc43b54bbae9f9fe5d8f33
--- /dev/null
+++ b/recursiveDescentParsers/cplusplus/interpret++/Makefile
@@ -0,0 +1,78 @@
+# This Makefile made available to his students by 
+# Prof. Ronald Moore  
+#     https://fbi.h-da.de/personen/ronald-moore/  
+#     mailto:ronald.moore@h-da.de
+# with no warranties whatsoever
+
+
+PROGS := interpret++
+SOURCES := main.cpp lexer.cpp parser.cpp
+OBJS = $(SOURCES:.cpp=.o)
+
+# Uncomment only one of the next two lines (choose your c++ compiler)
+# CC=g++
+CC := clang++
+
+## Add your own CFLAGS if you find them necessary... such as -O3 or so... 
+##    -g for debugging
+##    -std=<whatever> to select the right C++ Version
+##    -fmessage-length=0 disallows line wrapping in error messages
+##    (helps some IDEs (still?))
+CPPFLAGS :=  -g -std=c++17 -Wall -fmessage-length=0
+
+
+## More preliminaries
+# See https://www.gnu.org/software/make/manual/html_node/Special-Targets.html
+# In this makefile, we want to keep going even if we find errors
+.IGNORE :
+
+# Tell make that the following "targets" are "phony"
+# Cf. https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html#Phony-Targets
+.PHONY : all clean tests
+
+# This absolutely needs to be the first target (so to be the default target)
+all: $(PROGS)
+
+#  Some of the "Automatic Variables" that can be used in Makefiles.
+#      Cf. https://www.gnu.org/software/make/manual/  - particularly
+# https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html#Automatic-Variables
+# $@ = The filename representing the target.
+# $< = The filename of the first prerequisite.
+# $(*F) = The stem of the filename of the target (i.e. without .o, .cpp...)
+# $^ = The names of all the prerequisites, with spaces between them.
+
+## Following magic is used to figure out which dot cpp files depend
+# on which headers (dot h files) -- automatically (so that we recompile
+# only the ncessary dot cpp files when a header is maodified).
+# Magic taken from 
+# http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/
+#  ... and then fixed, and fixed, and fixed some more.
+DEPDIR := .deps
+# Broken: DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.d
+DEPFLAGS = -MMD -MF $(DEPDIR)/$*.d
+
+# include dep files, if they exist (minus says don't complain if they don't)
+DEPS := $(OBJS:%.o=$(DEPDIR)/%.d)
+
+-include $(DEPS)
+
+%.o : %.cpp %.d
+	$(CC) -c $(CPPFLAGS) $(DEPFLAGS) -o $@ $<
+
+# Make depdir if it doesn't exist... 
+$(DEPDIR): ; @mkdir -p $@
+
+##  Now, the targets -- the things that will get made!
+
+$(PROGS): $(OBJS) 
+	$(CC) $(CPPFLAGS) $(OBJS) $(LIBS) -o $@
+
+clean: 
+	$(RM) -v *~ *.o $(PROGS) tmp.txt
+	$(RM) -fvr $(DEPDIR)
+	# starting recursive clean...
+	cd tests && $(MAKE) clean
+
+tests: $(PROGS)
+	# Going to the tests directory for testing
+	cd tests && $(MAKE) tests
diff --git a/recursiveDescentParsers/cplusplus/interpret++/README.md b/recursiveDescentParsers/cplusplus/interpret++/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..1f1c217fd727cad8a8f1da68bce0979ef52dd508
--- /dev/null
+++ b/recursiveDescentParsers/cplusplus/interpret++/README.md
@@ -0,0 +1,68 @@
+Overview
+========
+
+Everything here is taken from the slides for the "Compiler Construction"
+course, i.e. it is directly from Prof. Ronald C. Moore.
+
+Or at least, after all this time, I really don't remember having stolen
+this code from somewhere else, but if you find an older copy that looks
+similar, please let me know, so I can give credit where credit is due --
+or disavow knowledge of that source (as the case may be).
+
+You are in the following subdirectory 
+  ** `interpret++`  
+     This code take mathematical expressions and evaluates them,
+     i.e. it outputs numbers. It is the same as its sister folder `interpreter`
+     as far as recursive descent parsing goes, but uses more C++ features and
+     is set up so as to support growing up to be a larger project. 
+     
+See **Chapter 1 Front End Construction**, Slides 21 and 22 (and please let me know when the inevitable day comes that these slide numbers are no longer correct).
+
+Building and Running
+====================
+
+This version requires a C++17 compatible C++ compiler, 
+such as newer versions of `g++` or `clang`.
+
+Build the program by running `make`.
+
+In case of doubt, use the voodo command `make clean` and then repeat `make`.
+
+To test the program, run `make tests`. This also illustrates how the intepreter is used.
+
+Alternatively, just run the program with *no* parameters (i.e. simply `./intepret++`). 
+It will tell you how it wants to be run (Hint: there are two usages).
+
+Contents (Manifest)
+====================
+
+You should find here:
+
+* `lexer.cpp` and `lexer.h`   
+   Source code for the lexer.
+      
+* `parser.cpp` and `parser.h`   
+   Source code for the recursive descent parser.
+      
+* `main.cpp`    
+   Source code for `main` -- the driver.
+      
+* `Makefile`  
+  Used to run `make` (obviously?).
+      
+* `tests`  
+  A directory full of test cases. Run `make tests` 
+  (either in directory `tests` or the parent directory)
+  to run the tests. Not unit tests, rather acceptance tests, 
+  but regression tests all the same.
+      
+* `README.md`  
+  This file.
+      
+Ronald Moore  
+https://fbi.h-da.de/personen/ronald-moore/  
+ronald.moore@h-da.de
+ 
+
+1 May 2020 
+
diff --git a/recursiveDescentParsers/cplusplus/interpret++/interpreter.cpp b/recursiveDescentParsers/cplusplus/interpret++/interpreter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c481e21910b2a1b85ad5d2b14a10fe9f729df087
--- /dev/null
+++ b/recursiveDescentParsers/cplusplus/interpret++/interpreter.cpp
@@ -0,0 +1,244 @@
+// This code made available to his students by 
+// Prof. Ronald Moore  
+//     https://fbi.h-da.de/personen/ronald-moore/  
+//     mailto:ronald.moore@h-da.de
+// with no warranties whatsoever!
+
+
+#include <cassert>
+#include <cctype> // for isspace
+#include <cstdlib> // for strtod
+#include <iostream>
+#include <fstream>
+#include <string>
+// include <vector>
+
+// ===================
+// LEXICAL ANALYSIS
+// The following are taken to be tokens:
+// left and right parenthesis, the plus and minus characters,
+// as well as asterisk and forward slash -- and numbers.
+// In the script, substraction and division are not supported,
+// but it seems like time to add them.
+
+// Preliminaries and Utilities
+// ============================
+
+// Utility Types
+typedef double numberType; // feel fee to change this to something else like int or float or bigint....
+typedef enum Token { 
+	tok_number = 'n',
+	tok_lparen = '(',
+	tok_rparen = ')',
+	tok_plus   = '+',
+	tok_minus  = '-',
+	tok_times  = '*',
+	tok_div    = '/',
+	tok_eof    = 'E',
+	bad_tok    = 'X'
+} Token;
+
+// global variables -- sue me if you don't like that!
+static std::istream *input = &(std::cin); // until proven otherwise
+static std::string	currentLine( "" );
+static int	currentLineNumber = -1;
+static int	currentColumnNumber = 0;
+static int	currentTokenLength = 0;
+
+static Token next_token; // again with the global variables... 
+static numberType currentNumber; // = zero....
+
+static void printErrorMsg( const std::string Error )
+{
+	std::cout << "ERROR on line " << currentLineNumber
+	          << ", column " << currentColumnNumber << " : " 
+	          << Error << std::endl;
+	std::cout << currentLine;
+	for ( int col = 0; col < currentColumnNumber-1; col++ )
+		std::cout << '-';
+	std::cout << '^' << std::endl;
+} // end printErrorMsg
+
+// The Lexer
+// ==========
+static bool skippedWhiteSpace( ) { // return true if not at EOF, i.e. if skipped
+	while ( true ) {
+		int currentLineLength = currentLine.length();
+		while ( currentColumnNumber < currentLineLength )
+			if ( isspace( currentLine[ currentColumnNumber ] ) ) 
+				currentColumnNumber++;
+			else // if NOT isspace() 
+				return true;
+				
+		// if we're here, we're at the end of a line.
+		std::getline( *input, currentLine ); 
+		currentLineNumber++;
+		currentColumnNumber = 0;
+		if ( ! *input ) // EOF!!
+			return false;
+		// else, repeat! 
+		// Which is the same as 
+		// return skippedWhiteSpace()  -- i.e. tail recursion.
+	};
+};		
+
+static Token gettok( ) {
+	assert( input ); // we assume nullptr != input
+	if ( ! *input ) return bad_tok;
+	// else, we can read from input
+	
+	// Skip white space, going to next line as necessary
+	if ( ! skippedWhiteSpace( ) ) return tok_eof;
+	        
+	// We're have visible text in front of us.
+	char currentChar = currentLine[ currentColumnNumber ];
+	currentColumnNumber++; // usually, but see num...
+	switch (  currentChar ) {
+		case '(' : return tok_lparen;
+		case ')' : return tok_rparen;
+		case '+' : return tok_plus;
+		case '-' : return tok_minus;
+		case '*' : return tok_times;
+		case '/' : return tok_div;
+		default : 
+			// either we have a number in front of us, or we don't
+			assert( 0 < currentColumnNumber );
+			char *alpha = &(currentLine[ currentColumnNumber-1 ]);
+			// minus one because we incremented it before the switch
+			char *omega = nullptr; // until we call strtod...
+			double tmpValue = strtod( alpha, &omega );
+			if ( alpha == omega ) {
+				return bad_tok; // !!!
+			};
+			// else if strtod found a real number (or at least a double)
+			currentNumber = tmpValue; // let C++ do the converison
+			currentColumnNumber += (omega - alpha) -1;
+			// minus one because we incremented it before the switch
+			return tok_number;
+	
+	}; // end switch
+	assert( false ); // we should never get here!
+	return bad_tok;
+} // end gettok
+	
+// PARSING!!!
+// ===========
+// 
+// The grammar we are going to parse here is:
+// Grammar:
+// 	E	→ T E´
+// 	E´	→ + T E´  | - T E´ | ε
+// 	T	→ F T´
+// 	T´	→ * F T´  |  / F T´  |  ε
+// 	F	→ ( E ) | num
+// Note that the recursive descent function for (e.g.) E´ 
+// is nameded "E2ndHalf"-
+
+// Forward Declarations
+static numberType E();
+static numberType E2ndHalf();
+static numberType T();
+static numberType T2ndHalf();
+static numberType F();
+
+// 	E	→ T E´
+numberType E() { return T() + E2ndHalf(); }
+
+// 	T	→ F T´
+numberType T() { return F() * T2ndHalf(); }
+
+// 	E´	→ + T E´  | - T E´ | ε
+numberType E2ndHalf() {
+    switch ( next_token ) {
+		case tok_plus : 
+			next_token = gettok(); // eat +
+            return T() + E2ndHalf();
+
+		case tok_minus : 
+			next_token = gettok(); // eat -
+			return (-1.0 * T()) + E2ndHalf();
+
+		default : 
+			return 0.0;
+    }; 
+} // end E2ndHalf
+
+// 	T´	→ * F T´  |  / F T´  |  ε
+numberType  T2ndHalf() { 
+	numberType tmp, rhs, acc;
+    switch ( next_token ) {
+		case tok_times : 
+			next_token = gettok(); // eat *
+			return F() * T2ndHalf();
+    case tok_div : 
+		next_token = gettok(); // eat /
+		tmp = F();
+		if ( 0.0 != tmp ) 
+			return (1.0/tmp) * T2ndHalf();
+		// else if T() returned zero
+		printErrorMsg( "Division by zero!" );
+		// fall through to default return one
+        
+    default : 
+		return 1.0;
+    }; 
+} // end T2ndHalf
+
+// 	F	→ ( E ) | num
+numberType  F() {
+	numberType result = 0; 
+    switch ( next_token ) {
+		case tok_lparen : 
+			next_token = gettok(); // eat lparen
+            result = E();
+            if ( tok_rparen == next_token ) {
+				next_token = gettok(); // eat rparen
+                return result;
+			}; 
+			// else if rparen not found
+            printErrorMsg( "Expected Right Parenthesis" );
+            return 0.0;
+
+		case tok_number : 
+			result = currentNumber; // side-effect of last gettok() 
+            next_token = gettok(); // eat id
+            return result;
+
+		default : 
+			printErrorMsg( "Expected Left Parenthesis or number" );
+            return 0.0;
+    }; 
+}
+
+
+// main (!)
+// =========
+
+int main( int argc, char **argv ) {
+
+	if (2 != argc) {
+		std::cerr << "Usage: " << argv[0] << " <fileName>.\n" 
+		          << "You provided " << argc-1 << " arguments, we take exactly one (only).\n";
+		return( -1 );
+	};
+	// else if 1 == argc ....
+	std::string	fileName( argv[1] );
+	if ( "-" != fileName ) {
+		static std::ifstream ifs( fileName );
+		input = &ifs;
+	}
+
+	// Prime the pump!
+	next_token = gettok( );
+	
+	// get tokens and dump them... 
+	while ( tok_eof != next_token ) {
+		std::cout << currentLineNumber << ":" 
+		          << currentLine << std::endl;
+		numberType value = E( );
+		std::cout << "INTERPRETER: " << value << std::endl;
+	};
+	std::cout << "End Of File!" << std::endl;
+	
+	return 0; // Alles klar!!!
+}
diff --git a/recursiveDescentParsers/cplusplus/interpret++/lexer.cpp b/recursiveDescentParsers/cplusplus/interpret++/lexer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f09c5715285c145cd768084b4165b3738f34cf61
--- /dev/null
+++ b/recursiveDescentParsers/cplusplus/interpret++/lexer.cpp
@@ -0,0 +1,141 @@
+// This code made available to his students by 
+// Prof. Ronald Moore  
+//     https://fbi.h-da.de/personen/ronald-moore/  
+//     mailto:ronald.moore@h-da.de
+// with no warranties whatsoever!
+
+#include "lexer.h"
+
+#include <cassert>
+#include <cctype> // for isspace
+#include <cstdlib> // for strtod
+#include <iostream>
+#include <fstream>
+
+namespace lex {  // continue to define things in lex::
+	
+// instantiate here... 
+lex::Token next_token; // again with the global variables... 
+
+// global variables -- sue me if you don't like that!
+static std::string		inputSourceName( "standard input" ); 
+static std::istream 	*input = &(std::cin); // until proven otherwise
+
+static std::string		currentLine( "" );
+static int				currentLineNumber = -1;
+static int				currentColumnNumber = 0;
+
+// Namespace "member functions"
+// ============================
+
+void printInputLocation( ) {
+	std::cout << inputSourceName 
+			  << " (" << currentLineNumber
+	          << ',' << currentColumnNumber 
+	          << "):" << std::endl;
+	std::cout << currentLine << std::endl;
+	for ( int col = 0; col < currentColumnNumber; col++ )
+		std::cout << '-';
+	std::cout << '^' << std::endl;
+} // end printInputLocation
+
+void printErrorMsg( const std::string Error )
+{
+	printInputLocation( );
+	std::cout << "ERROR : " << Error << std::endl;
+	advance_token( ); // Don't want to get stuck here.
+} // end printErrorMsg
+
+// Utility skippedWhiteSpace... 
+static bool skippedWhiteSpace( ) { // return true if not at EOF, i.e. if skipped
+	while ( true ) {
+		int currentLineLength = currentLine.length();
+		while ( currentColumnNumber < currentLineLength )
+			if ( isspace( currentLine[ currentColumnNumber ] ) ) 
+				currentColumnNumber++;
+			else // if NOT isspace() 
+				return true;
+				
+		// if we're here, we're at the end of a line.
+		std::getline( *input, currentLine ); 
+		currentLineNumber++;
+		currentColumnNumber = 0;
+		if ( ! *input ) // EOF!!
+			return false;
+		// else, repeat! 
+		// Which is the same as 
+		// return skippedWhiteSpace()  -- i.e. tail recursion.
+	};
+};		
+
+Token gettok( ) {
+	assert( input ); // we assume nullptr != input
+	
+	Token result( bad_tok, '\0' ); // default 
+	
+	if ( ! *input ) return result; // i.e. bad_tok
+	// else, we can read from input
+	
+	// Skip white space, going to next line as necessary
+	if ( ! skippedWhiteSpace( ) ) {
+		result.first = lex::tok_eof;
+		return result;
+	};
+	        
+	// else -- not eof, d.h. we have visible text in front of us.
+	char currentChar = currentLine[ currentColumnNumber ];
+	result.second = currentChar; // unless it's a number, etc.
+	currentColumnNumber++; // usually, but see num...
+	switch (  currentChar ) {
+		case '(' :	result.first = tok_lparen;
+					break;
+		case ')' :	result.first = tok_rparen;
+					break;
+		case '+' :	result.first = tok_plus;
+					break;
+		case '-' :	result.first = tok_minus;
+					break;
+		case '*' :	result.first = tok_times;
+					break;
+		case '/' :	result.first = tok_div;
+					break;
+		default : 
+			// either we have a number in front of us, or we don't
+			assert( 0 < currentColumnNumber ); // remember, incremented!
+			char *alpha = &(currentLine[ currentColumnNumber-1 ]);
+			// minus one because we incremented it before the switch
+			char *omega = nullptr; // until we call strtod...
+			double tmpValue = strtod( alpha, &omega );
+			// strtod sets omega to the first char after the number
+			if ( alpha == omega ) {
+				result.second = *omega; // or *alpha, they're the same...
+				return result; // i.e. bad_tok !!!
+			};
+			// else if strtod found a real number (or at least a double)
+			result.first = tok_number;
+			result.second = tmpValue;  // let C++ do any converisons
+			currentColumnNumber += (omega - alpha) -1;
+			// minus one because we incremented it before the switch
+	
+	}; // end switch
+	return result;
+} // end gettok
+
+void openInputSource( std::string filename ) {
+	assert( ! filename.empty() ); // caller should check that
+	inputSourceName = filename;
+	if ( "-" == filename ) 
+		input = &(std::cin);
+	else { // if fileName is not "-" (a dash)
+		static std::ifstream ifs( filename, std::ifstream::in );
+		if ( ! ifs.good( ) ) {
+			std::cerr << "ERROR opening file name " << filename
+			          << " -- could not open.\n";
+			exit( -2 );
+		}; 
+		// else if ifs is good
+		input = &ifs;
+	};
+} // end of openInputFile
+
+} // end namespace lex
diff --git a/recursiveDescentParsers/cplusplus/interpret++/lexer.d b/recursiveDescentParsers/cplusplus/interpret++/lexer.d
new file mode 100644
index 0000000000000000000000000000000000000000..0ad102ac4d6147955d9722e444693a2e72479e2a
--- /dev/null
+++ b/recursiveDescentParsers/cplusplus/interpret++/lexer.d
@@ -0,0 +1 @@
+lexer.o: lexer.cpp lexer.h
diff --git a/recursiveDescentParsers/cplusplus/interpret++/lexer.h b/recursiveDescentParsers/cplusplus/interpret++/lexer.h
new file mode 100644
index 0000000000000000000000000000000000000000..cd3182302c0d6e64e5b891a4f6407b3c4b50bbab
--- /dev/null
+++ b/recursiveDescentParsers/cplusplus/interpret++/lexer.h
@@ -0,0 +1,65 @@
+// This code made available to his students by 
+// Prof. Ronald Moore  
+//     https://fbi.h-da.de/personen/ronald-moore/  
+//     mailto:ronald.moore@h-da.de
+// with no warranties whatsoever!
+
+#pragma once 
+
+#include <cctype> // for isspace
+#include <cstdlib> // for strtod
+#include <string>
+#include <utility> // for std::pair
+#include <variant> // new C++17 feature! Like unions, only better!
+
+// ===================
+// LEXICAL ANALYSIS
+// The following are taken to be tokens:
+// left and right parenthesis, the plus and minus characters,
+// as well as asterisk and forward slash -- and numbers.
+// In the script, substraction and division are not supported,
+// but it seems like time to add them.
+
+// Preliminaries and Utilities
+// ============================
+
+namespace lex {
+	
+// Utility Types
+typedef double numberType; // feel fee to change this to something else like int or float or bigint....
+
+// Tokens -- are a pair of a tag and a value, where the value can be 
+// various things - a char or a numberType at present, but names and 
+// multicharacter operators could be added later
+typedef enum { 
+	tok_number = 'n',
+	tok_lparen = '(',
+	tok_rparen = ')',
+	tok_plus   = '+',
+	tok_minus  = '-',
+	tok_times  = '*',
+	tok_div    = '/',
+	tok_eof    = 'E',
+	bad_tok    = 'X'
+} TokenTag;
+
+typedef std::variant< char, numberType > TokenValue;
+
+typedef std::pair< TokenTag, TokenValue > Token;
+
+extern Token next_token; // again with the global variables... { 
+
+// Functons (or methods, if you prefer)
+
+void printInputLocation( );
+
+void printErrorMsg( const std::string Error );
+
+Token gettok( ); // 
+
+// DRY -- this line is repeated so often, it deserves its own function
+inline void advance_token( ) { next_token = gettok(); } // eats current token!
+
+void openInputSource( std::string filename );
+
+} // end namespace lex
diff --git a/recursiveDescentParsers/cplusplus/interpret++/main.cpp b/recursiveDescentParsers/cplusplus/interpret++/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..bfa4f0d620945def8bd8b25d28651ba837870522
--- /dev/null
+++ b/recursiveDescentParsers/cplusplus/interpret++/main.cpp
@@ -0,0 +1,42 @@
+// This code made available to his students by 
+// Prof. Ronald Moore  
+//     https://fbi.h-da.de/personen/ronald-moore/  
+//     mailto:ronald.moore@h-da.de
+// with no warranties whatsoever!
+
+#include <iostream>
+
+#include "parser.h" // this chain-includes lexer.h
+
+// main (!)
+// =========
+
+int main( int argc, char **argv ) {
+
+	if (2 != argc) {
+		std::cerr << "Usage: " << argv[0] << " <fileName> \n"
+				  << "       " << argv[0] << "- (to read from standard input) \n"
+		          << "You provided " << argc-1 << " arguments, we take exactly one (only).\n";
+		return( -1 );
+	};
+	// else if 1 == argc ....
+	lex::openInputSource( argv[1] );
+
+	// Prime the pump!
+	lex::advance_token( );
+	
+	// get tokens and dump them... 
+	while ( lex::tok_eof != lex::next_token.first ) {
+		lex::printInputLocation( );
+		lex::numberType value = parse::E( );
+		std::cout << "INTERPRETER: " << value << std::endl;
+		if ( lex::bad_tok == lex::next_token.first ) {
+			std::string errorMsg( "Unrecognized character(s)=" );
+			errorMsg.push_back( std::get< char >( lex::next_token.second ) );
+			lex::printErrorMsg( errorMsg );
+		}; // end if bad token
+	}; // end while not eof
+	std::cout << "End Of File!" << std::endl;
+	
+	return 0; // Alles klar!!!
+}
diff --git a/recursiveDescentParsers/cplusplus/interpret++/main.d b/recursiveDescentParsers/cplusplus/interpret++/main.d
new file mode 100644
index 0000000000000000000000000000000000000000..e1e4c9197aa3f2ff876de194daed1c9fd1bbc71a
--- /dev/null
+++ b/recursiveDescentParsers/cplusplus/interpret++/main.d
@@ -0,0 +1 @@
+main.o: main.cpp parser.h lexer.h
diff --git a/recursiveDescentParsers/cplusplus/interpret++/parser.cpp b/recursiveDescentParsers/cplusplus/interpret++/parser.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d699dc0049379bf68cca75ae4e95d1e3025b2dac
--- /dev/null
+++ b/recursiveDescentParsers/cplusplus/interpret++/parser.cpp
@@ -0,0 +1,100 @@
+// This code made available to his students by 
+// Prof. Ronald Moore  
+//     https://fbi.h-da.de/personen/ronald-moore/  
+//     mailto:ronald.moore@h-da.de
+// with no warranties whatsoever!
+
+
+#include <cassert>
+
+#include "parser.h"
+
+namespace parse {
+
+
+// PARSING!!!
+// ===========
+// 
+// The grammar we are going to parse here is:
+// Grammar:
+// 	E	→ T E´
+// 	E´	→ + T E´  | - T E´ | ε
+// 	T	→ F T´
+// 	T´	→ * F T´  |  / F T´  |  ε
+// 	F	→ ( E ) | num
+// Note that the recursive descent function for (e.g.) E´ 
+// is nameded "E2ndHalf"-
+
+// For every non-terminal (E, E2ndHalf, T, etc.) there is one function:
+
+// 	E	→ T E´
+lex::numberType E() { return T() + E2ndHalf(); }
+
+// 	T	→ F T´
+lex::numberType T() { return F() * T2ndHalf(); }
+
+// 	E´	→ + T E´  | - T E´ | ε
+lex::numberType E2ndHalf() {
+    switch ( lex::next_token.first ) {
+		case lex::tok_plus : 
+			lex::advance_token( ); // eat +
+            return T() + E2ndHalf();
+
+		case lex::tok_minus : 
+			lex::next_token = lex::gettok(); // eat -
+			return (-1.0 * T()) + E2ndHalf();
+
+		default : 
+			return 0.0;
+    }; 
+} // end E2ndHalf
+
+// 	T´	→ * F T´  |  / F T´  |  ε
+lex::numberType  T2ndHalf() { 
+	lex::numberType tmp;
+    switch ( lex::next_token.first ) {
+		case lex::tok_times : 
+			lex::advance_token( ); // eat *
+			return F() * T2ndHalf();
+		case lex::tok_div : 
+			lex::advance_token( ); // eat /
+			tmp = F();
+			if ( 0.0 != tmp ) 
+				return (1.0/tmp) * T2ndHalf();
+			// else if T() returned zero
+			lex::printErrorMsg( "Division by zero!" );
+			// fall through to default return one
+        
+		default : 
+			return 1.0;
+    }; 
+} // end T2ndHalf
+
+// 	F	→ ( E ) | num
+lex::numberType  F() {
+	lex::numberType result = 0; 
+    switch ( lex::next_token.first ) {
+		case lex::tok_lparen : 
+			lex::advance_token( ); // eat lparen
+            result = E();
+            if ( lex::tok_rparen == lex::next_token.first ) {
+				lex::advance_token( ); // eat rparen
+                return result;
+			}; 
+			// else if rparen not found
+            lex::printErrorMsg( "Expected Right Parenthesis" );
+            return 0.0;
+
+		case lex::tok_number : 
+			result = std::get< lex::numberType >( lex::next_token.second );
+            lex::advance_token( ); // eat id
+            return result;
+
+		default : 
+			lex::printErrorMsg( "Expected Left Parenthesis or number" );
+            return 0.0;
+    }; 
+}
+
+
+} // end namespace parse
diff --git a/recursiveDescentParsers/cplusplus/interpret++/parser.d b/recursiveDescentParsers/cplusplus/interpret++/parser.d
new file mode 100644
index 0000000000000000000000000000000000000000..2fb708bf31118a18c5449e73e29954b42def6e33
--- /dev/null
+++ b/recursiveDescentParsers/cplusplus/interpret++/parser.d
@@ -0,0 +1 @@
+parser.o: parser.cpp parser.h lexer.h
diff --git a/recursiveDescentParsers/cplusplus/interpret++/parser.h b/recursiveDescentParsers/cplusplus/interpret++/parser.h
new file mode 100644
index 0000000000000000000000000000000000000000..2fb9f955ff6f8d55a8d4388a046f0ad15b9764bd
--- /dev/null
+++ b/recursiveDescentParsers/cplusplus/interpret++/parser.h
@@ -0,0 +1,33 @@
+// This code made available to his students by 
+// Prof. Ronald Moore  
+//     https://fbi.h-da.de/personen/ronald-moore/  
+//     mailto:ronald.moore@h-da.de
+// with no warranties whatsoever!
+
+#pragma once
+
+#include "lexer.h"
+
+namespace parse {
+
+// PARSING!!!
+// ===========
+// 
+// The grammar we are going to parse here is:
+// Grammar:
+// 	E	→ T E´
+// 	E´	→ + T E´  | - T E´ | ε
+// 	T	→ F T´
+// 	T´	→ * F T´  |  / F T´  |  ε
+// 	F	→ ( E ) | num
+// Note that the recursive descent function for (e.g.) E´ 
+// is nameded "E2ndHalf"-
+
+// Forward Declarations
+lex::numberType E();
+lex::numberType E2ndHalf();
+lex::numberType T();
+lex::numberType T2ndHalf();
+lex::numberType F();
+
+} // end namespace parse
diff --git a/recursiveDescentParsers/cplusplus/interpret++/tests/Makefile b/recursiveDescentParsers/cplusplus/interpret++/tests/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..5bbf7245755453667f425ef63e833da99d1dcced
--- /dev/null
+++ b/recursiveDescentParsers/cplusplus/interpret++/tests/Makefile
@@ -0,0 +1,106 @@
+# This Makefile made available to his students by 
+# Prof. Ronald Moore  
+#     https://fbi.h-da.de/personen/ronald-moore/  
+#     mailto:ronald.moore@h-da.de
+# with no warranties whatsoever
+
+
+## More preliminaries
+# See https://www.gnu.org/software/make/manual/html_node/Special-Targets.html
+# In this makefile, we want to keep going even if we find errors
+.IGNORE :
+
+.NOTPARALLEL :
+
+## Define test collections - each line should contain one or more filenames
+GOOD-INPUTS := goodTest.input
+BAD-INPUTS := badTest.input
+
+# the sum of all tests
+INPUTS := $(GOOD-INPUTS) $(BAD-INPUTS)
+
+# reference files ("correct" output)
+REFERENCES := $(INPUTS:.input=.reference)
+
+# output files
+OUTPUTS := $(INPUTS:.input=.output)
+
+# Program we'll be testing
+PROGRAM := ../interpret++
+
+# Tell make that the following "targets" are "phony"
+# Cf. https://www.gnu.org/software/make/manual/html_node/Phony-Targets.html#Phony-Targets
+.PHONY : all clean tests goodtests badtests
+
+##  Now, the targets -- the things that will get made!
+
+all: tests
+
+# For convenience, "make check" == "make test"
+check: tests
+
+# TESTING
+# Calling "make test" should
+# (1) make the programs (if necessary)
+# (2) erase all the test outputs
+# (3) create them again (see rules, below).
+# (4) run the special case "bigtest" (see below)
+tests: $(PROGRAM)
+	cd .. && $(MAKE)
+	$(MAKE) clean
+	$(MAKE) updatetests
+
+updatetests: $(OUTPUTS)
+
+$(PROGRAM) :
+	cd ..
+	$(MAKE)
+	
+# "make clean" or equivalently  "make testclean" deletes all files created by testing
+clean: testclean
+
+testclean:
+	$(RM) -fv *.output *~ 
+
+# By the way, for more information about calling make from make, see
+# https://www.gnu.org/software/make/manual/html_node/Recursion.html#Recursion
+
+# User-defined function (Cf. http://oreilly.com/catalog/make3/book/ch04.pdf)
+# Takes two arguments - an output file and a reference output file
+# (the two files should be the same). Function  prints "success" or "failure",
+# depending on whether the two files are equal.
+#define testReferenceOutput
+#    @cmp -s $1 $2                                        \
+#    && /bin/echo -e "Test against $2 successful" \
+#    || /bin/echo -e "\n\tTest against $2 FAILED!!!\n"
+#endef
+
+#### If your terminal supports colors, comment out the version above,
+# and use this version instead - good tests have a green background,
+# failed tests have a red background. See
+#    <http://misc.flogisoft.com/bash/tip_colors_and_formatting>
+# for information about output formatting (colors, bold, etc.)).
+
+define testReferenceOutput
+#    @cmp -s $1 $2
+    @diff -qs $1 $2                                        \
+    && /bin/echo -e "\e[1;42mTest against $2 successful.\e[0m" \
+    || /bin/echo -e "\e[1;41mTest against $2 FAILED!!!  \e[0m"
+endef
+
+#  Reminder...
+# $@ = The filename representing the target.
+# $< = The filename of the first prerequisite.
+# $* = The stem of the target (i.e. without .o, .cpp...)
+# $(*F) = The stem of the target (i.e. without .o, .cpp... AND without directory)
+# $^ = The names of all the prerequisites, with spaces between them.
+
+
+################ Assembler Tests ###################
+# For some files x.job, we have stored the "correct" (expected) output in x.ref
+# (where "ref" is short for "reference").
+$(OUTPUTS): %.output: %.input %.reference
+	../interpret++ $<  >$@  2>&1 
+	$(call testReferenceOutput,$@, $*.reference)
+
+# Finished!
diff --git a/recursiveDescentParsers/cplusplus/interpret++/tests/badTest.input b/recursiveDescentParsers/cplusplus/interpret++/tests/badTest.input
new file mode 100644
index 0000000000000000000000000000000000000000..99faffe929d271a664703888821ac01a3bf91828
--- /dev/null
+++ b/recursiveDescentParsers/cplusplus/interpret++/tests/badTest.input
@@ -0,0 +1,8 @@
+42?
+42^2
+(42))
+((42
+(42 / 0)
+(42 / (1-1))
+42 +/- 3.14159
+
diff --git a/recursiveDescentParsers/cplusplus/interpret++/tests/badTest.reference b/recursiveDescentParsers/cplusplus/interpret++/tests/badTest.reference
new file mode 100644
index 0000000000000000000000000000000000000000..7e3895c10067b5714af2b4eadee85568d6f24768
--- /dev/null
+++ b/recursiveDescentParsers/cplusplus/interpret++/tests/badTest.reference
@@ -0,0 +1,65 @@
+badTest.input (0,2):
+42?
+--^
+INTERPRETER: 42
+badTest.input (0,3):
+42?
+---^
+ERROR : Unrecognized character(s)=?
+badTest.input (1,2):
+42^2
+--^
+INTERPRETER: 42
+badTest.input (1,3):
+42^2
+---^
+ERROR : Unrecognized character(s)=^
+badTest.input (1,4):
+42^2
+----^
+INTERPRETER: 2
+badTest.input (2,1):
+(42))
+-^
+INTERPRETER: 42
+badTest.input (2,5):
+(42))
+-----^
+badTest.input (2,5):
+(42))
+-----^
+ERROR : Expected Left Parenthesis or number
+INTERPRETER: 0
+badTest.input (3,1):
+((42
+-^
+badTest.input (4,1):
+(42 / 0)
+-^
+ERROR : Expected Right Parenthesis
+badTest.input (4,3):
+(42 / 0)
+---^
+ERROR : Expected Right Parenthesis
+badTest.input (4,8):
+(42 / 0)
+--------^
+ERROR : Division by zero!
+INTERPRETER: 0
+badTest.input (5,1):
+(42 / (1-1))
+-^
+badTest.input (5,12):
+(42 / (1-1))
+------------^
+ERROR : Division by zero!
+badTest.input (6,2):
+42 +/- 3.14159
+--^
+ERROR : Expected Right Parenthesis
+badTest.input (6,5):
+42 +/- 3.14159
+-----^
+ERROR : Expected Left Parenthesis or number
+INTERPRETER: -3.14159
+End Of File!
diff --git a/recursiveDescentParsers/cplusplus/interpret++/tests/goodTest.input b/recursiveDescentParsers/cplusplus/interpret++/tests/goodTest.input
new file mode 100644
index 0000000000000000000000000000000000000000..7c49594be4b299e555ffbe7865109c33dcbf9497
--- /dev/null
+++ b/recursiveDescentParsers/cplusplus/interpret++/tests/goodTest.input
@@ -0,0 +1,11 @@
+42
+40 + 2
+(44.44 - 2.44)
+(21 * 2.0)
+(84.0 / (3-1))
+88 / 2 - 2
+88 / (8 / 4) - 2
+44.0 - 2
+(4 * 11.0) - 2
+(8 * 11.0) / 2 - 2
+(8 * 11.0) / (8 / 4) - 2
diff --git a/recursiveDescentParsers/cplusplus/interpret++/tests/goodTest.reference b/recursiveDescentParsers/cplusplus/interpret++/tests/goodTest.reference
new file mode 100644
index 0000000000000000000000000000000000000000..828a2999e3f5b7f8448a9b2f1de890a83ff3a25d
--- /dev/null
+++ b/recursiveDescentParsers/cplusplus/interpret++/tests/goodTest.reference
@@ -0,0 +1,45 @@
+goodTest.input (0,2):
+42
+--^
+INTERPRETER: 42
+goodTest.input (1,2):
+40 + 2
+--^
+INTERPRETER: 42
+goodTest.input (2,1):
+(44.44 - 2.44)
+-^
+INTERPRETER: 42
+goodTest.input (3,1):
+(21 * 2.0)
+-^
+INTERPRETER: 42
+goodTest.input (4,1):
+(84.0 / (3-1))
+-^
+INTERPRETER: 42
+goodTest.input (5,2):
+88 / 2 - 2
+--^
+INTERPRETER: 42
+goodTest.input (6,2):
+88 / (8 / 4) - 2
+--^
+INTERPRETER: 42
+goodTest.input (7,4):
+44.0 - 2
+----^
+INTERPRETER: 42
+goodTest.input (8,1):
+(4 * 11.0) - 2
+-^
+INTERPRETER: 42
+goodTest.input (9,1):
+(8 * 11.0) / 2 - 2
+-^
+INTERPRETER: 42
+goodTest.input (10,1):
+(8 * 11.0) / (8 / 4) - 2
+-^
+INTERPRETER: 42
+End Of File!