/** * Function representing the <st_factor_ident> prods */ void RecursiveDescentParser::st_factor_ident(TableEntry* te) { if(errorCondition) return; if(token == TK_LEFT_PARENTHESES) { #if DEBUG_PARSER std::cout << "<st_factor_ident> --> (<o_list>);\n"; #endif Token leftParen = token; token = scanner->getToken(); ParamList* pList = o_list(); if(te) { if(te->getEntryType()!=TableEntry::FUNCTION) { std::stringstream errorMsg; errorMsg << "'" << te->getName() << "' is not a function"; errorHandler(errorMsg.str(), leftParen); } else { // now makes sure the lists match FunctionEntry* fe = (FunctionEntry*)te; if(pList) matchParameters(fe, pList, leftParen); iCode.threeAddressCode(TAC_PARAM, pList); iCode.threeAddressCode( symTab.getNextAddress(), // throw away temporary TAC_CALL, fe->getLabel(), fe->getParamCount() ); } } else { std::stringstream errorMsg; errorMsg << "Undeclared function"; errorHandler(errorMsg.str(), leftParen); } match(TK_RIGHT_PARENTHESES); match(TK_SEMICOLON); } else if(token == TK_LEFT_BRACKET || token == TK_ASSIGNMENT) { #if DEBUG_PARSER std::cout << "<st_factor_ident> --> <var_prime>=<exp>;\n"; #endif VariableEntry* vEntry = (VariableEntry*)te; Token startToken = token; attr varAttr = var_prime(vEntry); match(TK_ASSIGNMENT); attr expAttr = exp(); if(expAttr.type != varAttr.type) { std::stringstream errorMsg; errorMsg << "Type mismatch variable '" << vEntry->getName() << "'"; errorHandler(errorMsg.str(), startToken); } if(varAttr.attrib == VA_ARRAY) { std::stringstream errorMsg; errorMsg << "Assignment error, array '" << vEntry->getName() << "' must be indexed."; errorHandler( errorMsg.str(), startToken ); } if(vEntry->getAttribute() == VA_ARRAY) { // array addr value to assign index iCode.threeAddressCode(vEntry->getAttr(), TAC_ASSIGN_TO_ADDRESS_AT, expAttr, varAttr); } else { iCode.threeAddressCode(vEntry->getAttr(), TAC_ASSIGN, expAttr); } match(TK_SEMICOLON); } else { errorHandler(); } }
/*--------------------------------------------------------------------------------------*\ * UApm : process() * * The APM/2 main function, throws a ERROR_* in case of errors * \*--------------------------------------------------------------------------------------*/ UApm &UApm::process(void) { char *pcOption=0; COUNTRYCODE countrycode={ 0 }; COUNTRYINFO countryinfo={ 0 }; ULONG ulInfoLength=0; int iTemp=0; char *pcTemp; UCountryTranslate ucountrytranslate[]= { { 01L, "Us" }, { 02L, "Fr" }, { 07L, "Ru" }, { 31L, "Nl" }, { 32L, "Be" }, { 33L, "Fr" }, { 34L, "Es" }, { 39L, "It" }, { 41L, "Gr" }, { 44L, "Us" }, { 45L, "Dk" }, { 46L, "Se" }, { 47L, "No" }, { 49L, "Gr" }, { 61L, "Us" }, { 81L, "Jp" }, { 99L, "Us" }, { 358L, "Fi" }, }; FILESTATUS3 filestatus3; /* Query country settings, to try to load NLS message file even if no /Language commandline option has been specified */ DosQueryCtryInfo(sizeof(countryinfo), &countrycode, &countryinfo, &ulInfoLength); for(iTemp=0; iTemp<(sizeof(ucountrytranslate)/sizeof(ucountrytranslate[0])); iTemp++) { if(countryinfo.country==ucountrytranslate[iTemp].ulCountry) { pcTemp=strrchr(acMessageFileNls, '.'); if(strlen(acMessageFileNls) && (pcTemp!=0)) { pcTemp-=2; /* Skip "Us" backwards to append "Xx.msg" */ strcpy(pcTemp, ucountrytranslate[iTemp].acCountry); strcat(pcTemp, ".msg"); } break; } } /* First, try to find the NLS message file, which of course can override our assumptions */ if((pcOption=checkCommandlineOption("Language", TRUE))!=0) { if(pcOption==(char *)0xFFFFFFFF) { displayMessage(MSG_LOGO); displayMessage(MSG_PARAMETERS_MISSING); throw((int)ERROR_PARAMETERS_MISSING); } /* If language was specified, use it */ iStatusFlag|=FLAG_NLS_MESSAGES_REQUESTED; pcTemp=strrchr(acMessageFileNls, '.'); if(strlen(acMessageFileNls) && (pcTemp!=0)) { pcTemp-=2; /* Skip "Us" backwards to append "Xx.msg" */ strcpy(pcTemp, pcOption); strcat(pcTemp, ".msg"); } } /* Now that we might have a NLS message file that is not Us, verify that it exists */ if(strcmp(acMessageFileNls, acMessageFileUs)) { if(DosQueryPathInfo(acMessageFileNls, FIL_STANDARD, &filestatus3, sizeof(filestatus3))!=NO_ERROR) { /* The NLS message file specified does not exists, so use Us English one, but inform the user if he has requested it (compared to when we found it in the ucountrytranslate[] table) */ if(iStatusFlag & FLAG_NLS_MESSAGES_REQUESTED) displayMessage(ERROR_NLSMSG_NOT_EXIST, 1, (int)acMessageFileNls); strcpy(acMessageFileNls, acMessageFileUs); } else /* The NLS message file does exist, so any problem retrieving messages is caused by invalid contents of that file, which we should inform the user for */ iStatusFlag|=FLAG_NLS_MESSAGES_FOUND; } /* Process further depending on the arguments specified */ if(iArgc==1) { /* If no argument is specified, display simple help */ displayMessage(MSG_LOGO); displayMessage(MSG_DESCRIPTION); displayMessage(MSG_PARAMETERS_MISSING); iReturnCode=ERROR_PARAMETERS_MISSING; } else { /* At least one option was specified */ displayMessage(MSG_LOGO); /* If the language was the only (two) arguments, display simple help */ if((iArgc==3) && (iStatusFlag & FLAG_NLS_MESSAGES_REQUESTED)) { displayMessage(MSG_DESCRIPTION); displayMessage(MSG_PARAMETERS_MISSING); iReturnCode=ERROR_PARAMETERS_MISSING; throw(iReturnCode); } if(checkCommandlineOption("?")!=0) { displayMessage(MSG_PARAMETERS_INVALID); displayMessage(MSG_PARAMETERS_TEXT); iReturnCode=ERROR_PARAMETERS_INVALID; } else { /* Now just find all commandline parameters and trow an error if an invalid combination was found */ try { matchParameters(); } catch(int iErrorCode) { displayMessage(iErrorCode); displayMessage(MSG_PARAMETERS_TEXT); iReturnCode=iErrorCode; throw(iReturnCode); } /* Now that we have found valid commandline parameters, process them */ try { processParameters(); } catch(int iErrorCode) { displayMessage(iErrorCode); iReturnCode=iErrorCode; throw(iReturnCode); } } } return(*this); }
/** * Function representing the <prim_prime> productions */ attr RecursiveDescentParser::prim_prime(TableEntry* pTabEntry) { attr retval; retval.type = T_ERROR; if(errorCondition) return retval; if(token == TK_LEFT_BRACKET) { #if DEBUG_PARSER std::cout << "<prim_prime> --> [<exp>]\n"; #endif token = scanner->getToken(); retval = exp(); retval.attrib = VA_SIMPLE; match(TK_RIGHT_BRACKET); } else if(token == TK_LEFT_PARENTHESES) { #if DEBUG_PARSER std::cout << "<prim_prime> --> (<o_list>)\n"; #endif Token sToken = token; token = scanner->getToken(); ParamList* pList = o_list(); match(TK_RIGHT_PARENTHESES); if(pTabEntry && pTabEntry->getEntryType()==TableEntry::FUNCTION) { FunctionEntry* fe = (FunctionEntry*)pTabEntry; if(pList) { matchParameters(fe, pList, sToken); } retval.type = fe->getReturnType(); retval.addr = symTab.getNextAddress(); iCode.threeAddressCode(TAC_PARAM, pList); iCode.threeAddressCode(retval, TAC_CALL, fe->getLabel(), fe->getParamCount()); } else { std::stringstream errorMsg; errorMsg << "'" << pTabEntry->getName() << "' is not a function"; errorHandler(errorMsg.str(), sToken); } } else if( token == TK_ASTERISK || token == TK_SLASH || token == TK_PERCENT || token == TK_PLUS || token == TK_MINUS || token == TK_RIGHT_PARENTHESES || token == TK_RIGHT_BRACKET || token == TK_SEMICOLON || token == TK_LT || token == TK_GT || token == TK_LTE || token == TK_GTE || token == TK_EQUAL || token == TK_NOT_EQ ) { #if DEBUG_PARSER std::cout << "<prim_prime> --> e\n"; #endif retval = pTabEntry->getAttr(); } else { errorHandler(); } return retval; }