0

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");
}
5
Contributors
11
Replies
12
Views
8 Years
Discussion Span
Last Post by Jennifer84
0

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.

0

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.

0

>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.

0

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.

0

howdy

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

krs,
tesu

0

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);
}
0

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;
}
This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.