/* * funcbody starts with the current symbol being either * the first parameter id or the begin for the local * block. If begin is the current symbol then funcbody * assumes that the function has no parameters. */ int ParseFunction(SYM *sp) { int i; SYM *sp1, *sp2, *pl, *osp; Statement *stmt; int nump; __int16 *ta; int nn; std::string name; dfs.puts("<ParseFunction>\n"); isFuncBody = true; if (sp==NULL) { fatal("Compiler error: ParseFunction: SYM is NULL\r\n"); } dfs.printf("***********************************\n"); dfs.printf("***********************************\n"); dfs.printf("***********************************\n"); if (sp->parent) dfs.printf("Parent: %s\n", (char *)sp->GetParentPtr()->name->c_str()); dfs.printf("Parsing function: %s\n", (char *)sp->name->c_str()); dfs.printf("***********************************\n"); dfs.printf("***********************************\n"); dfs.printf("***********************************\n"); sp->stkname = stkname; if (verbose) printf("Parsing function: %s\r\n", (char *)sp->name->c_str()); nump = nparms; iflevel = 0; // There could be unnamed parameters in a function prototype. dfs.printf("A"); // declare parameters // Building a parameter list here allows both styles of parameter // declarations. the original 'C' style is parsed here. Originally the // parameter types appeared as list after the parenthesis and before the // function body. sp->BuildParameterList(&nump); dfs.printf("B"); sp->mangledName = sp->BuildSignature(1); // build against parameters // If the symbol has a parent then it must be a class // method. Search the parent table(s) for matching // signatures. osp = sp; name = *sp->name; if (sp->parent) { SYM *sp2; dfs.printf("PArent Class:%s|",(char *)sp->GetParentPtr()->name->c_str()); sp2 = sp->GetParentPtr()->Find(name); if (sp2) { dfs.printf("Found at least inexact match"); sp2 = sp->FindExactMatch(TABLE::matchno); } if (sp2 == nullptr) error(ERR_METHOD_NOTFOUND); else sp = sp2; sp->PrintParameterTypes(); } else { if (gsyms[0].Find(name)) { sp = TABLE::match[TABLE::matchno-1]; } } dfs.printf("C"); if (sp != osp) { dfs.printf("ParseFunction: sp changed\n"); osp->params.CopyTo(&sp->params); osp->proto.CopyTo(&sp->proto); sp->derivitives = osp->derivitives; sp->mangledName = osp->mangledName; // Should free osp here. It's not needed anymore } if (lastst == closepa) { NextToken(); } dfs.printf("D"); if (sp->tp->type == bt_pointer) { if (lastst==assign) { doinit(sp); } sp->IsNocall = isNocall; sp->IsPascal = isPascal; sp->IsKernel = isKernel; sp->IsInterrupt = isInterrupt; sp->IsTask = isTask; sp->NumParms = nump; sp->IsVirtual = isVirtual; isPascal = FALSE; isKernel = FALSE; isOscall = FALSE; isInterrupt = FALSE; isTask = FALSE; isNocall = FALSE; // ReleaseLocalMemory(); /* release local symbols (parameters)*/ return 1; } dfs.printf("E"); if (lastst == semicolon) { // Function prototype dfs.printf("e"); sp->IsPrototype = 1; sp->IsNocall = isNocall; sp->IsPascal = isPascal; sp->IsKernel = isKernel; sp->IsInterrupt = isInterrupt; sp->IsTask = isTask; sp->IsVirtual = isVirtual; sp->NumParms = nump; sp->params.MoveTo(&sp->proto); isPascal = FALSE; isKernel = FALSE; isOscall = FALSE; isInterrupt = FALSE; isTask = FALSE; isNocall = FALSE; // ReleaseLocalMemory(); /* release local symbols (parameters)*/ goto j1; } else if(lastst != begin) { dfs.printf("F"); // NextToken(); ParameterDeclaration::Parse(2); // for old-style parameter list //needpunc(closepa); if (lastst==semicolon) { sp->IsPrototype = 1; sp->IsNocall = isNocall; sp->IsPascal = isPascal; sp->IsKernel = isKernel; sp->IsInterrupt = isInterrupt; sp->IsTask = isTask; sp->IsVirtual = isVirtual; sp->NumParms = nump; isPascal = FALSE; isKernel = FALSE; isOscall = FALSE; isInterrupt = FALSE; isTask = FALSE; isNocall = FALSE; // ReleaseLocalMemory(); /* release local symbols (parameters)*/ } // Check for end of function parameter list. else if (funcdecl==2 && lastst==closepa) { ; } else { sp->IsNocall = isNocall; sp->IsPascal = isPascal; sp->IsKernel = isKernel; sp->IsInterrupt = isInterrupt; sp->IsTask = isTask; sp->IsVirtual = isVirtual; isPascal = FALSE; isKernel = FALSE; isOscall = FALSE; isInterrupt = FALSE; isTask = FALSE; isNocall = FALSE; sp->NumParms = nump; stmt = ParseFunctionBody(sp); funcbottom(stmt); } } // error(ERR_BLOCK); else { dfs.printf("G"); sp->IsNocall = isNocall; sp->IsPascal = isPascal; sp->IsKernel = isKernel; sp->IsInterrupt = isInterrupt; sp->IsTask = isTask; sp->IsVirtual = isVirtual; isPascal = FALSE; isKernel = FALSE; isOscall = FALSE; isInterrupt = FALSE; isTask = FALSE; isNocall = FALSE; sp->NumParms = nump; stmt = ParseFunctionBody(sp); funcbottom(stmt); } j1: dfs.printf("F"); dfs.puts("</ParseFunction>\n"); return 0; }
/* * funcbody starts with the current symbol being either * the first parameter id or the begin for the local * block. If begin is the current symbol then funcbody * assumes that the function has no parameters. */ int ParseFunction(SYM *sp) { int poffset, i; int oldglobal; SYM *sp1, *sp2; Statement *stmt; if (sp==NULL) { fatal("Compiler error: ParseFunction: SYM is NULL\r\n"); } sp->stkname = stkname; if (verbose) printf("Parsing function: %s\r\n", sp->name); oldglobal = global_flag; global_flag = 0; poffset = 24; /* size of return block */ nparms = 0; iflevel = 0; // There could be unnamed parameters in a function prototype. if(lastst == id || 1) { /* declare parameters */ //while(lastst == id) { // names[nparms++] = litlate(lastid); // NextToken(); // if( lastst == comma) // NextToken(); // else // break; // } //needpunc(closepa); // dodecl(sc_member); /* declare parameters */ sp->parms = (SYM *)NULL; ParseParameterDeclarations(1); for(i = 0;i < nparms;++i) { if( (sp1 = search(names[i],&lsyms)) == NULL) sp1 = makeint(names[i]); //if( sp1->tp->size < 8 ) //{ // sp1->value.i = poffset;// + (8 - sp1->tp->size); // poffset += 8; //} //else //{ // sp1->value.i = poffset; // poffset += sp1->tp->size; //} sp1->value.i = poffset; // Check for aggregate types passed as parameters. Structs // and unions use the type size. // if (sp1->tp->type==bt_struct || sp1->tp->type==bt_union) { poffset += round8(sp1->tp->size); if (round8(sp1->tp->size) > 8) sp->IsLeaf = FALSE; // } // else // poffset += 8; //sp1->value.i = poffset; //poffset += 8; sp1->storage_class = sc_auto; sp1->nextparm = (SYM *)NULL; // record parameter list if (sp->parms == (SYM *)NULL) { sp->parms = sp1; } else { sp1->nextparm = sp->parms; sp->parms = sp1; } } // Process extra hidden parameter if (sp->tp->btp->type==bt_struct || sp->tp->btp->type==bt_union) { sp1 = makeint(litlate("_pHiddenStructPtr")); sp1->value.i = poffset; poffset += 8; sp1->storage_class = sc_auto; sp1->nextparm = (SYM *)NULL; // record parameter list if (sp->parms == (SYM *)NULL) { sp->parms = sp1; } else { sp1->nextparm = sp->parms; sp->parms = sp1; } nparms++; } } if (lastst == closepa) NextToken(); if (sp->tp->type == bt_pointer) { if (lastst==assign) { doinit(sp); } sp->IsNocall = isNocall; sp->IsPascal = isPascal; sp->IsKernel = isKernel; sp->IsInterrupt = isInterrupt; sp->IsTask = isTask; sp->NumParms = nparms; isPascal = FALSE; isKernel = FALSE; isOscall = FALSE; isInterrupt = FALSE; isTask = FALSE; isNocall = FALSE; ReleaseLocalMemory(); /* release local symbols (parameters)*/ global_flag = oldglobal; return 1; } if (lastst == semicolon) { // Function prototype sp->IsPrototype = 1; sp->IsNocall = isNocall; sp->IsPascal = isPascal; sp->IsKernel = isKernel; sp->IsInterrupt = isInterrupt; sp->IsTask = isTask; sp->NumParms = nparms; isPascal = FALSE; isKernel = FALSE; isOscall = FALSE; isInterrupt = FALSE; isTask = FALSE; isNocall = FALSE; ReleaseLocalMemory(); /* release local symbols (parameters)*/ goto j1; } else if(lastst != begin) { // NextToken(); ParseParameterDeclarations(2); // for old-style parameter list //needpunc(closepa); if (lastst==semicolon) { sp->IsPrototype = 1; sp->IsNocall = isNocall; sp->IsPascal = isPascal; sp->IsKernel = isKernel; sp->IsInterrupt = isInterrupt; sp->IsTask = isTask; sp->NumParms = nparms; isPascal = FALSE; isKernel = FALSE; isOscall = FALSE; isInterrupt = FALSE; isTask = FALSE; isNocall = FALSE; ReleaseLocalMemory(); /* release local symbols (parameters)*/ } // Check for end of function parameter list. else if (funcdecl==2 && lastst==closepa) { ; } else { sp->IsNocall = isNocall; sp->IsPascal = isPascal; sp->IsKernel = isKernel; sp->IsInterrupt = isInterrupt; sp->IsTask = isTask; isPascal = FALSE; isKernel = FALSE; isOscall = FALSE; isInterrupt = FALSE; isTask = FALSE; isNocall = FALSE; sp->NumParms = nparms; stmt = ParseFunctionBody(sp); funcbottom(stmt); } } // error(ERR_BLOCK); else { sp->IsNocall = isNocall; sp->IsPascal = isPascal; sp->IsKernel = isKernel; sp->IsInterrupt = isInterrupt; sp->IsTask = isTask; isPascal = FALSE; isKernel = FALSE; isOscall = FALSE; isInterrupt = FALSE; isTask = FALSE; isNocall = FALSE; sp->NumParms = nparms; stmt = ParseFunctionBody(sp); funcbottom(stmt); } j1: global_flag = oldglobal; return 0; }
void PHPSourceFile::OnFunction() { // read the next token phpLexerToken token; if(!NextToken(token)) { return; } bool funcReturnRef = false; if(token.type == '&') { funcReturnRef = true; if(!NextToken(token)) { return; } } PHPEntityFunction* func(NULL); int funcDepth(0); if(token.type == kPHP_T_IDENTIFIER) { // the function name func = new PHPEntityFunction(); func->SetFullName(token.text); func->SetLine(token.lineNumber); } else if(token.type == '(') { funcDepth = 1; // Since we already consumed the open brace // anonymous function func = new PHPEntityFunction(); func->SetLine(token.lineNumber); } if(!func) return; PHPEntityBase::Ptr_t funcPtr(func); if(funcReturnRef) { funcPtr->SetFlag(kFunc_ReturnReference); } // add the function to the current scope CurrentScope()->AddChild(funcPtr); // Set the function as the current scope m_scopes.push_back(funcPtr); // update function attributes ParseFunctionSignature(funcDepth); func->SetFlags(LookBackForFunctionFlags()); if(LookBackTokensContains(kPHP_T_ABSTRACT) || // The 'abstract modifier was found for this this function (funcPtr->Parent() && funcPtr->Parent()->Is(kEntityTypeClass) && funcPtr->Parent()->Cast<PHPEntityClass>()->IsInterface())) // We are inside an interface { // Mark this function as an abstract function func->SetFlags(func->GetFlags() | kFunc_Abstract); } if(func->HasFlag(kFunc_Abstract)) { // an abstract function - it has no body if(!ConsumeUntil(';')) { // could not locate the function delimiter, remove it from the stack // we probably reached EOF here m_scopes.pop_back(); } } else { if(!NextToken(token)) return; if(token.type == ':') { // PHP 7 signature type // function foobar(...) : RETURN_TYPE wxString returnValuetype = ReadType(); if(returnValuetype.IsEmpty()) return; // parse error func->SetReturnValue(returnValuetype); } else { // untake the token and place it back on the "unget" list UngetToken(token); } if(ReadUntilFound('{', token)) { // found the function body starting point if(IsParseFunctionBody()) { ParseFunctionBody(); } else { // Consume the function body ConsumeFunctionBody(); } } else { // could not locate the open brace! // remove this function from the stack m_scopes.pop_back(); } } // Remove the current function from the scope list if(!m_reachedEOF) { m_scopes.pop_back(); } m_lookBackTokens.clear(); }
/* * funcbody starts with the current symbol being either * the first parameter id or the begin for the local * block. If begin is the current symbol then funcbody * assumes that the function has no parameters. */ void ParseFunction(SYM *sp) { int poffset, i; int oldglobal; SYM *sp1, *sp2, *makeint(); oldglobal = global_flag; global_flag = 0; poffset = 24; /* size of return block */ nparms = 0; if(lastst == id || 1) { /* declare parameters */ //while(lastst == id) { // names[nparms++] = litlate(lastid); // NextToken(); // if( lastst == comma) // NextToken(); // else // break; // } //needpunc(closepa); // dodecl(sc_member); /* declare parameters */ sp->parms = NULL; ParseParameterDeclarations(1); for(i = 0;i < nparms;++i) { if( (sp1 = search(names[i],&lsyms)) == NULL) sp1 = makeint(names[i]); //if( sp1->tp->size < 8 ) //{ // sp1->value.i = poffset;// + (8 - sp1->tp->size); // poffset += 8; //} //else //{ // sp1->value.i = poffset; // poffset += sp1->tp->size; //} sp1->value.i = poffset; poffset += 8; sp1->storage_class = sc_auto; sp1->nextparm = NULL; // record parameter list if (sp->parms == NULL) { sp->parms = sp1; } else { sp1->nextparm = sp->parms; sp->parms = sp1; } } } if (lastst == closepa) NextToken(); if (lastst == semicolon) { // Function prototype sp->IsPrototype = 1; sp->IsNocall = isNocall; sp->IsPascal = isPascal; sp->IsInterrupt = isInterrupt; sp->NumParms = nparms; isPascal = FALSE; isOscall = FALSE; isInterrupt = FALSE; isNocall = FALSE; ReleaseLocalMemory(); /* release local symbols (parameters)*/ } else if(lastst != begin) { NextToken(); ParseParameterDeclarations(2); sp->IsNocall = isNocall; sp->IsPascal = isPascal; sp->IsInterrupt = isInterrupt; sp->NumParms = nparms; ParseFunctionBody(sp); funcbottom(); } // error(ERR_BLOCK); else { sp->IsNocall = isNocall; sp->IsPascal = isPascal; sp->IsInterrupt = isInterrupt; sp->NumParms = nparms; ParseFunctionBody(sp); funcbottom(); } global_flag = oldglobal; }
void CFormulaParser::ParseSingleFormula(CString function_text, int starting_line) { _tokenizer.SetInput(function_text); // Check for empty function int token_ID = _tokenizer.GetToken(); if ((token_ID == kTokenEndOfFile) || (token_ID == kTokenEndOfFunction)) { // Parsing finished (for this function or altogether) return; } else { _tokenizer.PushBack(); } if (isdigit(_function_name[0])) { // Date like ##2014-02-09 23:16:55## // To be completely ignored // We don't need it and on saving we create a new one write_log(preferences.debug_parser(), "[FormulaParser] Found a ##number(##). Probably date. To be ignored.\n"); return; } else if (!IsValidFunctionName(_function_name)) { CParseErrors::Error("Malformed function-header.\n" "Expecting a ##f$function## here.\n"); return; } if (_function_name == "f$debug") { ParseDebugTab(function_text); p_function_collection->Add((COHScriptObject*)p_debug_tab); return; } TPParseTreeNode function_body = NULL; if (COHScriptObject::IsFunction(_function_name) || COHScriptObject::IsOpenPPLSymbol(_function_name)) { if (_memicmp(_function_name, "f$nrpf", 6) == 0) vali_err = true;if (_memicmp(_function_name, "f$AA_KK_QQ_E", 12) == 0) vali_err = true; if (_memicmp(_function_name, "f$aggpf_nbof_reraised", 21) == 0) vali_err = true; // 4nt1 5+inky w3bb3r 84nd1+ ;-) // ##f$functionXYZ## // ##OpenPPL## write_log(preferences.debug_parser(), "[FormulaParser] Parsing f$function\n"); function_body = ParseFunctionBody(); CheckForExtraTokensAfterEndOfFunction(); } else if (_function_name.Left(4) == "list") { // ##listXYZ## write_log(preferences.debug_parser(), "[FormulaParser] Parsing list\n"); COHScriptList *new_list = new COHScriptList(&_function_name, &function_text, starting_line); ParseListBody(new_list); p_function_collection->Add((COHScriptObject*)new_list); return; } else if (_function_name.MakeLower() == "dll") { // ##DLL## write_log(preferences.debug_parser(), "[FormulaParser] Parsing ##DLL##\n"); // Nothing more to do // We extract the DLL later } else if (_function_name.MakeLower() == "notes") { // ##Notes## write_log(preferences.debug_parser(), "[FormulaParser] Found ##Notes##. Nothing to parse\n"); // Don't do anything. // This is just a special type of global comment. } else { CParseErrors::Error("Found unknown function type.\n" "Did you forget \"f$\"?\n"); return; } CFunction *p_new_function = new CFunction(&_function_name, &function_text, starting_line); p_new_function->SetParseTree(function_body); p_function_collection->Add((COHScriptObject*)p_new_function); // Care about operator precendence _parse_tree_rotator.Rotate(p_new_function); #ifdef DEBUG_PARSER p_new_function->Serialize(); #endif }