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