NodeWrite* Parser::ParseWrite(bool isFirst, bool isWriteln) { NodeWrite* ans = NULL; t = sc.GetNextToken(); if (isFirst) t = RequireToken("(", "\"(\" expected"); if (t.GetType() == string_const) { ans = new NodeWriteStr(STR, "\""+t.GetValue().substr(1, t.GetValue().size()-2)+"\""); t = sc.GetNextToken(); } else { NodeExpression* exp = ParseComparision(); OutputType T; if (exp->GetType()->IsInt()) T = INT; else T = FLOAT; ans = new NodeWriteExp(T, exp); } if (t.GetValue() == ",") ans->SetNext(ParseWrite(false, isWriteln)); else { t = RequireToken(")", "\")\" expected"); if (isWriteln) ans->SetNext(new NodeWriteln()); } return ans; }
internal bool ParseIdentifier(tokenizer *Tokenizer, std::string *Member) { if(RequireToken(Tokenizer, Token_Equals)) { token Token = GetToken(Tokenizer); switch(Token.Type) { case Token_String: { std::string String; for(int Index = 0; Index < Token.TextLength; ++Index) String += Token.Text[Index]; *Member = String; return true; } break; default: { ReportInvalidRule("Expected token of type Token_String: '" + std::string(Token.Text, Token.TextLength) + "'"); } break; } } else { ReportInvalidRule("Expected token: '='"); } return false; }
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; }
void Parser::ParseVarDecl() { t = sc.GetNextToken(); while (true){ vector<string> names; do { Token t1 = t; t = sc.GetNextToken(); if (t1.GetType() != identifier && t1.GetValue() != "," && t1.GetValue() != ":") throw Error("incorrect variable declaration", t); if (t1.GetType() == identifier) names.push_back(t1.GetValue()); } while(t.GetValue() != ":"); SymType* Type = ParseType(false); for (vector<string>::iterator it = names.begin(); it != names.end(); ++it) { TableStack.Find((*it), t); SymVarGlobal* s = new SymVarGlobal(*it, Type); table->insert(pair<string, SymVarGlobal*>(*it, s)); s->print(os, IsExplType(Type->GetName())); os<<endl; } names.clear(); t = sc.GetNextToken(); t = RequireToken(";" , "\";\" expected"); if (t.GetValue() == "type" || t.GetValue() == "const" || t.GetValue() == "procedure" || t.GetValue() == "function" || t.GetValue() == "begin" || t.GetValue() == "EOF") return; if (t.GetValue() == "var") t = sc.GetNextToken(); } }
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; }
SymTypeArray* Parser::ParseArray() { t = sc.GetNextToken(); if (t.GetValue() != "[") throw Error ("incorrect array declaration",t); vector<pair<int, int>> range; do { t = sc.GetNextToken(); SymVarConst* l = ParseConst(); t = sc.GetNextToken(); t = RequireToken(".." , "incorrect array declaration"); SymVarConst* r = ParseConst(); if(!r->GetType()->IsInt() || !l->GetType()->IsInt()) throw Error("incorrect bounds in array declaration", t); int ll = atoi(l->GetValue().c_str()); int rr = atoi(r->GetValue().c_str()); t = sc.GetNextToken(); range.push_back(pair<int, int>(ll,rr)); } while(t.GetValue() != "]"); t =sc.GetNextToken(); if (t.GetValue() != "of") throw Error("incorrect array declaration : \"of\" exprected", t); SymType* Type = ParseType(false); SymTypeArray* arrType = NULL; for (vector<pair<int, int>>::iterator it = range.begin(); it != range.end(); ++it) { arrType = new SymTypeArray(IntToStr(NotExplType++), Type, (*it).first, (*it).second); Type = arrType; } return arrType; }
StatementAssign* Parser::ParseAssignment() { NodeExpression* left = ParseExpression(); if (!left->IsLValue()) throw Error("incorrect assign operation", t); t = RequireToken(":=" , "\":=\" expected"); NodeExpression* right = ParseComparision(); CheckTypes(left, right, true); return new StatementAssign(left, right); }
StatementWhile* Parser::ParseWhile() { NodeExpression* expr = NULL; NodeStatement* body = NULL; t = sc.GetNextToken(); expr = ParseComparision(); if (!expr->GetType()->IsInt()) throw Error("Ordinal expression expected", t); t = RequireToken("do" , "\"do\" expected"); body = ParseElement(); return new StatementWhile(expr, body); }
StatementBlock* Parser::ParseBlock() { block StmsList; t = sc.GetNextToken(); while (t.GetValue() != "end") { StmsList.push_back(ParseElement()); if (t.GetValue() != "end") t = RequireToken(";", "\";\" expected"); } t = sc.GetNextToken(); return new StatementBlock(StmsList); }
StatementIf* Parser::ParseIf() { NodeExpression* con = NULL; NodeStatement* then_block = NULL; NodeStatement* else_block = NULL; t = sc.GetNextToken(); con = ParseComparision(); if (!con->GetType()->IsInt()) throw Error("Ordinal expression expected", t); t = RequireToken("then", "\"then\" expected"); then_block = ParseElement(); if (t.GetValue() != "else") return new StatementIf(con, then_block); t = sc.GetNextToken(); else_block = ParseElement(); return new StatementIfElse(con, then_block, else_block); }
StatementRepeat* Parser::ParseRepeat() { NodeExpression* expr = NULL; NodeStatement* body = NULL; block StmsList; t = sc.GetNextToken(); while (t.GetValue() != "until") { StmsList.push_back(ParseElement()); if (t.GetValue() != "until") t = RequireToken(";", "statement error"); } body = new StatementBlock(StmsList); t = sc.GetNextToken(); expr = ParseComparision(); if (!expr->GetType()->IsInt()) throw Error("Ordinal expression expected", t); return new StatementRepeat(expr, body); }
StatementFor* Parser::ParseFor() { NodeExpression* expr; NodeStatement* body; StatementAssign* assign; bool isDownto = false; t = sc.GetNextToken(); assign = ParseAssignment(); if (!assign->GetType()->IsInt()) throw Error("Ordinal expression expected", t); if (t.GetValue() == "downto") isDownto = true; else if (t.GetValue() != "to") throw Error("\"to\" or \"downto\" expected", t); t = sc.GetNextToken(); expr = ParseComparision(); if (!expr->GetType()->IsInt()) throw Error("ordinal expression expected", t); t = RequireToken("do", "\"do\" expected"); body = ParseElement(); return new StatementFor(expr, body, assign, isDownto); }
void Parser::ParseConstDecl() { t = sc.GetNextToken(); while(true) { Token t1 = t; t = sc.GetNextToken(); if (t1.GetType() != identifier || t.GetValue() != "=") throw Error("wrong Const Decl", t); TableStack.Find(t1.GetValue(), t); t = sc.GetNextToken(); SymVarConst* Type = ParseConst(); Type->SetName(t1.GetValue()); table->insert(pair<string, SymVarConst*> (t1.GetValue(), Type)); Type->print(os,true); t = sc.GetNextToken(); t = RequireToken(";", "; expected"); if (t.GetValue() == "var" || t.GetValue() == "type" || t.GetValue() == "procedure" || t.GetValue() == "function" || t.GetValue() == "begin" || t.GetValue() == "EOF") return; if (t.GetValue() == "const") t = sc.GetNextToken(); } }
internal bool ParseProperties(tokenizer *Tokenizer, window_properties *Properties) { if(RequireToken(Tokenizer, Token_Equals)) { if(RequireToken(Tokenizer, Token_OpenBrace)) { Properties->Scratchpad = -1; Properties->Display = -1; Properties->Space = -1; Properties->Float = -1; bool ValidState = true; while(ValidState) { token Token = GetToken(Tokenizer); switch(Token.Type) { case Token_SemiColon: { continue; } break; case Token_CloseBrace: { ValidState = false; } break; case Token_Identifier: { if(TokenEquals(Token, "float")) { std::string Value; if(ParseIdentifier(Tokenizer, &Value)) { if(Value == "true") Properties->Float = 1; else if(Value == "false") Properties->Float = 0; } } else if(TokenEquals(Token, "display")) { std::string Value; if(ParseIdentifier(Tokenizer, &Value)) Properties->Display = ConvertStringToInt(Value); } else if(TokenEquals(Token, "space")) { std::string Value; if(ParseIdentifier(Tokenizer, &Value)) Properties->Space = ConvertStringToInt(Value); } else if(TokenEquals(Token, "scratchpad")) { std::string Value; if(ParseIdentifier(Tokenizer, &Value)) { if(Value == "visible") Properties->Scratchpad = 1; else if(Value == "hidden") Properties->Scratchpad = 0; } } else if(TokenEquals(Token, "role")) { std::string Value; if(ParseIdentifier(Tokenizer, &Value)) Properties->Role = Value; } } break; default: { ReportInvalidRule("Expected token of type Token_Identifier: '" + std::string(Token.Text, Token.TextLength) + "'"); } break; } } return true; } else { ReportInvalidRule("Expected token '{'"); } } else { ReportInvalidRule("Expected token '='"); } return false; }
NodeExpression* Parser::ParseFactor() { NodeExpression* r = NULL; if (t.GetValue() == "-" || t.GetValue() == "+" || t.GetValue() == "not") { string op = t.GetValue(); t = sc.GetNextToken(); NodeExpression* _r = ParseFactor(); r = new NodeUnaryOp(new Symbol(op), _r); r->SetType(_r->GetType()); } else { if (t.GetValue() != "(" && t.GetType() != identifier && t.GetType() != int_const_dec && t.GetType() != float_const) throw Error("Syntax error : unexpected \""+t.GetValue()+"\";", t); if(t.GetValue() == "(") { t = sc.GetNextToken(); r = ParseComparision(); t = RequireToken(")" , "\")\" expected"); } switch(t.GetType()){ case int_const_dec : case float_const: { SymVarConst* _const = new SymVarConst(t.GetValue(), t.GetValue(), NULL); if (t.GetType() == int_const_dec) _const->SetType((SymType*)mainTable->find("integer")->second); else _const->SetType((SymType*)mainTable->find("real")->second); t = sc.GetNextToken(); r = new NodeConst(_const); r->SetType(_const->GetType()); return r; break; } case identifier: { Token t1 = t; bool found = false; _Table::iterator it = TableStack.Find(t1.GetValue(), found); if (!found) throw Error("unknown identifier", t); t = sc.GetNextToken(); SymVar* name = (SymVar*)it->second; SymType* Type = name->GetType(); if (t.GetValue() == "(") { if (!it->second->IsFunc()) throw Error("unexpected identifier", t); if (((SymFunc*)it->second)->IsForward()) throw Error("undefined forward ("+it->second->GetName()+")", t); r = ParseSub((SymFunc*)it->second); } else if(name->GetType()->IsRec() || name->GetType()->IsArr()) { r = new NodeVar(name); r->SetType(Type); while(name->GetType()->IsRec() || name->GetType()->IsArr()) { SymVar* name2 = name; if (name->GetType()->IsRec()) r = ParseRec(r, name); if (name->GetType()->IsArr()) r = ParseArr(r,name); if (name2 == name) break; } } else { if (name->IsConst()) r = new NodeConst(it->second); else r = new NodeVar(it->second); r->SetType(Type); } break; } } } return r; }
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; }