Пример #1
0
void test_code()
{
  /*
   *
   * class Test {
   *  int a, b;
   *  int fun(int c) {
   *     a = c;
   *     b = 2*c;
   *  }
   * }
   *
   */
  SymTable global;
  Entity cls_test("Test", "class");
  SymTable *classTable = cls_test.getSymTable();
  global.insert(&cls_test);
  Entity a("a", "int");
  Entity b("b", "int");
  Entity meth_fun("fun", "meth");
  Entity c("c", "int");
  classTable->insert(&a);
  classTable->insert(&b);
  classTable->insert(&meth_fun);
  SymTable *methTable = meth_fun.getSymTable();
  methTable->find("params")->getSymTable()->insert(&c);
  assert(true);
  global.printTable();
  //TODO
}
Пример #2
0
void test_ClassSymbolTableInsertion() {
  /* class hello {} */
  SymTable global;
  Entity s("hello", "int");
  global.insert(&s);
  assert(global.find("hello")==&s);
}
Пример #3
0
NodeRecordAccess* Parser::ParseRec(NodeExpression* r, SymVar* &name)
{
	SymType* Type = name->GetType();
	if (t.GetValue() == ".")
		while (true)
		{	
			SymTable* tab = ((SymTypeRecord*)(name->GetType()))->GetFields();
			if (t.GetValue() == ".")
				t = sc.GetNextToken();
			_Table::const_iterator _it = tab->find(t.GetValue());
			if (_it == tab->end())
				throw Error("unknown identifier", t);
			name = (SymVar*)(_it->second);
			r = new NodeRecordAccess(new Symbol("."), r, new NodeVar(name));	
			t = sc.GetNextToken();
			if (t.GetValue() == ".")
			{
				Type = name->GetType();
				if (!Type->IsRec())
					throw Error("invalid record access", t);
			}
			else
			{
				Type = name->GetType();
				break;
			}
		}
	r->SetType(Type);
	return (NodeRecordAccess*)r;
}
Пример #4
0
NodeCall* Parser::ParseSub(SymProc* sym)
{
	vector<NodeExpression*> params;
	int size = sym->GetArgNames()->size();
	if (size != 0)
	{
		for (int i=0; i<size && t.GetValue() != ")"; ++i)
		{
			t = sc.GetNextToken();
			NodeExpression* p = ParseExpression();
			SymTable* st = sym->GetArgTable();
			SymVarParam* h = (SymVarParam*)(st->find((*(sym->GetArgNames()))[i])->second);
			NodeExpression* help = new NodeExpression(h);
			help->SetType(h->GetType());
			if (p->GetType()->IsScalar() && h->GetType()->IsScalar())
				CheckTypes(help, p, true);
			else
				if (GetRootType(p->GetType()) != GetRootType(help->GetType()))
					throw Error("impossible cast types", t);
			
			params.push_back(p);
		}
		t = RequireToken(")" , "\")\" expected");
	}
	if (params.size() != size)
		throw Error("incorrect number of parameters", t);
	NodeCall* func = new NodeCall(sym, params);
	if (sym->IsFunc())
		func->SetType(sym->GetType());
	return func;
}
Пример #5
0
SymTable* Parser::ParseRecDecl(vector<string>* &flds)
{
	vector<string> names;
	Token t1 = sc.GetNextToken();
	t = t1;
	SymTable* fldTable = new SymTable();
	while(t.GetValue() != "end")
	{
		do
		{
			t1 = t;
			t = sc.GetNextToken();
			if (t1.GetType() != identifier && t1.GetValue() != "," && t1.GetValue() != ":")
				throw Error("incorrect record declaration", t);
			if(t1.GetType() == identifier)
			{
				Check(t1.GetValue(), fldTable);
				names.push_back(t1.GetValue());
			}
		}
		while(t.GetValue() != ":");
		SymType* type = ParseType(false);
		for (vector<string>::iterator it = names.begin(); it != names.end(); ++it)
		{
			if (fldTable->find(*it) != fldTable->end())
				throw Error("incorrect record declaration", t);
			fldTable->insert(SymElem (*it, new SymVarLocal(*it, type)));
			flds->push_back((*it));
		}
		names.clear();
		t = sc.GetNextToken();
		t = RequireToken(";" , "\";\" expected");
	}
	return fldTable;
}
Пример #6
0
SymTable* Parser::ParseArguments(vector<string>* &arguments)
{
	SymTable* argTable = new SymTable;
	if (t.GetValue() != "(")
		return argTable;
	vector<string> argNames;
	bool isVar = false;
	do
	{
		t = sc.GetNextToken();
		if (t.GetValue() == "var")
		{
			isVar = true;
			t = sc.GetNextToken();
		}
		if (t.GetType() != identifier)
			throw Error("incorrect name of argument", t);
		argNames.push_back(t.GetValue());
		arguments->push_back(t.GetValue());
		t = sc.GetNextToken();
		if (t.GetValue() == ",")
			continue;
		if (t.GetValue() == ":")
		{
			SymType* Type = ParseType(false);
			if (IsExplType(Type->GetName()))
				throw Error("arguments type mismatch", t);
			t = sc.GetNextToken();
			for(vector<string>::iterator it= argNames.begin(); it != argNames.end(); ++it)
			{
				if (argTable->find(*it) != argTable->end())
					throw Error("identifier already declared",t);
				if (isVar)
					argTable->insert(pair<string, SymVar*> (*it, new SymVarParam_var(*it, Type)));
				else
					argTable->insert(pair<string, SymVar*> (*it, new SymVarParam(*it, Type)));
			}
			isVar = false;
			argNames.clear();
			if (t.GetValue() != ";" && t.GetValue() != ")")
				throw Error("incorrect function defenition", t);
		}
	}
	while(t.GetValue() != ")");
	t = sc.GetNextToken();
	return argTable;
}
Пример #7
0
SymProc* Parser::ProcFunc(bool isFunc)
{
	t = sc.GetNextToken();
	SymType* Type = NULL;
	SymProc* sub = NULL;
	if (t.GetType() != identifier)
		throw Error("incorrect procedure name", t);
	SymTable* argTable = NULL;
	vector<string>* argNames = new vector<string>;
	_Table::iterator it = table->find(t.GetValue());
	string name = t.GetValue();
	t = sc.GetNextToken();
	argTable = ParseArguments(argNames);
	TableStack.PushTable(argTable);
	if (isFunc)
	{
		if (t.GetValue() != ":")
			throw Error("type expected", t);
		Type = ParseType(false);
		t = sc.GetNextToken();
	}
	t = RequireToken(";", "\";\" expected");
	if (it != table->end())
	{
		if (!(it->second->IsProc()) || !(((SymProc*)it->second)->IsForward()))
			throw Error("incorrect procedure definition", t);
		SymTable* argTableF = ((SymProc*)it->second)->GetArgTable();
		vector<string>* argNamesF = ((SymProc*)it->second)->GetArgNames();
		for (size_t i=0; i<argNames->size(); ++i)
		{
			if ((*argNames)[i] != (*argNamesF)[i] ||
				!SymComp(argTable->find((*argNames)[i])->second , argTableF->find((*argNamesF)[i])->second))
				throw Error("Header does not match previouse definition", t);
		}
		if (isFunc)
			sub = ParseProcDecl(name, argNames, argTable, true, Type);
		else
			sub = ParseProcDecl(name, argNames, argTable, false, Type);
		t = RequireToken(";", "\";\" expected");
	}
	else
	{
		if (t.GetValue() == "forward")
		{
			t = sc.GetNextToken();
			if (t.GetValue() != ";")
				throw Error("\";\" expected", t);
			if (isFunc)
			{
				sub = new SymFunc(name, argNames, argTable, NULL, true, NULL);
				((SymFunc*)sub)->SetType(Type);
			}
			else
				sub = new SymProc(name, argNames, argTable, NULL, true);
			sub->print(os, false);
			table->insert(pair<string, SymProc*> (name, sub));
			TableStack.PopTable();
		}
		else
		{
			sub = ParseProcDecl(name, argNames, argTable, isFunc, Type);
			if (isFunc)
				((SymFunc*)sub)->SetType(Type);
			sub->GetBody()->print(os, 0);
		}
		t = sc.GetNextToken();
	}
	return sub;
}