I am trying to write an Interpreter but are not really sure about the methods that are used for this.
What I think I have understood is for the example below, I will have to parse out 3 things from the string.
"Number1", "==" and "2" and associate these to maps in some way ?

Though I dont know much more than this and are not sure where to begin how to do this ?
What could be the first step.

int Number1 = 2;
std::string Criteria = "Number1 == 2";

if ( Criteria )
{
    MessageBox::Show("Number1 has a Value of 2");
}

Recommended Answers

All 11 Replies

Infix notation is relatively difficult to parse. If you're doing this to learn how interpreters work, I'd recommend starting with a simpler syntax. For example, instead of "Number1 == 2", you could more easily parse "Number1 2 ==" (ie. postfix notation) with a simple stack.

Thank you.. I am not sure but if there could be any Tutoriouls about how interpreters is written.. Perheps this could be a good start also.
I have googled "Interpreters C++" but cant really find this. If there is any links anywhere I would be more than interested to read them.

Infix notation is relatively difficult to parse. If you're doing this to learn how interpreters work, I'd recommend starting with a simpler syntax. For example, instead of "Number1 == 2", you could more easily parse "Number1 2 ==" (ie. postfix notation) with a simple stack.

>I am not sure but if there could be any Tutoriouls about how interpreters is written..
Not that I know of off the top of my head, but I'm sure they exist. If you want an example, I wrote an extremely simple interpreter a while ago and posted it on Daniweb. You can find it here.

That would be really nice to read but when I press the link, the page is not showing and I get:
"404 File Not Found"

Perheps I can search for the Title if you remember what this was called.

>I am not sure but if there could be any Tutoriouls about how interpreters is written..
Not that I know of off the top of my head, but I'm sure they exist. If you want an example, I wrote an extremely simple interpreter a while ago and posted it on Daniweb. You can find it here.

howdy

Is this problem not roaring for herd of lex, yacc, flex, gnus, bison?
Also Aho and Sethi might be involved

krs,
tesu

I have an Interpreter example below that looks if "Number1 == 1".
I have put the code below in the places I have them in my CodeView for my Form.
When putting it in these places the code compiles but my problem is that when running the program that should show a MessageBox if Number1 == 1, I will have an Error that says:

"Expression: map/set iterator not dereferencable"

So my question is. I beleive I haven´t put the code in the correct places.
What I do is to press button1 that calls the eventhandler "Help" and inside this function I have declared the maps. I think this is the problem. I think these 5 first lines here that declare the maps should be put outside the Form Class but if I do this, the compiler complains that I mix native and managed. (Though I am not sure if that is the problem)

So I am struggling with what code I could have put in right and wrong places..

namespace Interpreter {

public ref class Form1 : public System::Windows::Forms::Form
{

public: System::Void Help(System::Object^  sender, System::EventArgs^  e) 
{
			
bool ParseIf(const std::string& strToParse);
bool OperationEqual(const std::string& strToParse, const std::string& strVariable);
std::map<std::string, bool (*)(const std::string&)> ParseMap;
std::map<std::string, bool (*)(const std::string&, const std::string&)> ParseMap2;
std::map<std::string, long> VariablesMap;


ParseMap["if"] = &ParseIf;
ParseMap2["=="] = &OperationEqual;
VariablesMap["Number1"] = 1;

std::string strToParse = "if (Number1 == 1)";
std::string::size_type index = strToParse.find(" ");
std::string strKeyword = strToParse.substr(0, index);
if ( ParseMap.find( strKeyword.c_str() )->second( strToParse.substr(index + 1) ) )
MessageBox::Show("Number1 is 1"); 
// The if evaluated to true; execute action underneath the if
else
; 
// The if evaluated to false; skip everything underneath the if
}



private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) 
{
     Help(this, EventArgs::Empty);
}

};
}


bool ParseIf(const std::string& strToParse)
{
std::map<std::string, bool (*)(const std::string&, const std::string&)> ParseMap2;

if (strToParse[0] != '(') throw "ERROR: IF MUST BEGIN WITH (";
std::string::size_type index = strToParse.find(" ");
std::string strVariable = strToParse.substr(1, index - 1);
std::string::size_type index2 = strToParse.find(" ", index + 1);
std::string strOperation = strToParse.substr(index + 1, index2 - index - 1);
return ParseMap2.find( strOperation.c_str() )->second(strToParse.substr(index2 + 1), strVariable);
}

bool OperationEqual(const std::string& strToParse, const std::string& strVariable)
{
std::map<std::string, long> VariablesMap;

std::string::size_type index = strToParse.find(")");
std::string strNumber = strToParse.substr(0, index);
long nNumber = strtol(strNumber.c_str(), NULL, 10);
return (VariablesMap.find( strVariable.c_str() )->second == nNumber);
}

If I put the code in the previous post in a native project like this, the interpreter example works without any problem at all like below.

What I want to do is in any way "transform" this code so it will work within a managed project.
What will work within the managed area is if I put the first 3 functions below in Red Outside the Form Class.

void Help() {}
bool ParseIf(const std::string& strToParse) {}
bool OperationEqual(const std::string& strToParse, const std::string& strVariable) {}

The problem what I can understand is that I also need to put these declarations in Green outside any buttoncontrol because it is Global Variables that need to be reached by the functions in Red:

bool ParseIf(const std::string& strToParse);
bool OperationEqual(const std::string& strToParse, const std::string& strVariable);
std::map<std::string, bool (*)(const std::string&)> ParseMap;
std::map<std::string, bool (*)(const std::string&, const std::string&)> ParseMap2;
std::map<std::string, long> VariablesMap;


So my question is if this is possible to use within a managed area. Where will the code be put in a Form.
My problem is the Green lines. These lines must be reached by the functions.
Thanks...

#include <map>

bool ParseIf(const std::string& strToParse);
bool OperationEqual(const std::string& strToParse, const std::string& strVariable);
std::map<std::string, bool (*)(const std::string&)> ParseMap;
std::map<std::string, bool (*)(const std::string&, const std::string&)> ParseMap2;
std::map<std::string, long> VariablesMap;


void Help()
{
ParseMap["if"] = &ParseIf;
ParseMap2["=="] = &OperationEqual;
VariablesMap["Number1"] = 1;

std::string strToParse = "if (Number1 == 1)";
std::string::size_type index = strToParse.find(" ");
std::string strKeyword = strToParse.substr(0, index);
if ( ParseMap.find( strKeyword.c_str() )->second( strToParse.substr(index + 1) ) )

	for( int i = 0; i < 200000000; i++)
	{ int is = 0;}
	else
	; // The if evaluated to false; skip everything underneath the if
}

bool ParseIf(const std::string& strToParse)
{
if (strToParse[0] != '(') throw "ERROR: IF MUST BEGIN WITH (";
std::string::size_type index = strToParse.find(" ");
std::string strVariable = strToParse.substr(1, index - 1);
std::string::size_type index2 = strToParse.find(" ", index + 1);
std::string strOperation = strToParse.substr(index + 1, index2 - index - 1);
return ParseMap2.find( strOperation.c_str() )->second(strToParse.substr(index2 + 1), strVariable);
}

bool OperationEqual(const std::string& strToParse, const std::string& strVariable)
{
std::string::size_type index = strToParse.find(")");
std::string strNumber = strToParse.substr(0, index);
long nNumber = strtol(strNumber.c_str(), NULL, 10);
return (VariablesMap.find( strVariable.c_str() )->second == nNumber);
}

int _tmain(int argc, _TCHAR* argv[])
{

Help();

	return 0;
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.