void ExtSourceProperties::interpretProperties(RegistryPtr reg, const ExternalAtom& atom, const std::vector<std::vector<std::string> >& props) { DBGLOG(DBG, "Interpreting external source properties"); typedef std::vector<std::string> Prop; BOOST_FOREACH (Prop p, props) { // parameter interpretation ID param1 = ID_FAIL; ID param2 = ID_FAIL; if (p.size() > 1) { try { param1 = ID::termFromInteger(boost::lexical_cast<int>(p[1])); } catch(boost::bad_lexical_cast&) { param1 = reg->storeConstantTerm(p[1]); } } if (p.size() > 2) { try { param2 = ID::termFromInteger(boost::lexical_cast<int>(p[2])); } catch(boost::bad_lexical_cast&) { param2 = reg->storeConstantTerm(p[2]); } } // property interpretation std::string name = p[0]; if (name == "functional") { if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"functional\" expects no parameters"); DBGLOG(DBG, "External Atom is functional"); functional = true; } else if (name == "monotonic") { if (param2 != ID_FAIL) throw GeneralError("Property \"monotonic\" expects less than two parameters"); if (param1 == ID_FAIL) { DBGLOG(DBG, "External Atom is monotonic in all input parameters"); for (uint32_t i = 0; i < atom.inputs.size(); ++i) { monotonicInputPredicates.insert(i); } } else { bool found = false; for (uint32_t i = 0; i < atom.inputs.size(); ++i) { if (atom.inputs[i] == param1) { DBGLOG(DBG, "External Atom is monotonic in parameter " << i); monotonicInputPredicates.insert(i); found = true; break; } } if (!found) throw SyntaxError("Property refers to invalid input parameter"); } } else if (name == "antimonotonic") { if (param2 != ID_FAIL) throw GeneralError("Property \"antimonotonic\" expects less than two parameters"); if (param1 == ID_FAIL) { DBGLOG(DBG, "External Atom is antimonotonic in all input parameters"); for (uint32_t i = 0; i < atom.inputs.size(); ++i) { antimonotonicInputPredicates.insert(i); } } else { bool found = false; for (uint32_t i = 0; i < atom.inputs.size(); ++i) { if (atom.inputs[i] == param1) { DBGLOG(DBG, "External Atom is antimonotonic in parameter " << i); antimonotonicInputPredicates.insert(i); found = true; break; } } if (!found) throw SyntaxError("Property refers to invalid input parameter"); } } else if (name == "atomlevellinear" || name == "fullylinear") { if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"atomlevellinear\" expects no parameters"); DBGLOG(DBG, "External Atom is linear on atom level"); atomlevellinear = true; } else if (name == "tuplelevellinear") { if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"tuplelevellinear\" expects no parameters"); DBGLOG(DBG, "External Atom is linear on tuple level"); tuplelevellinear = true; } else if (name == "usesenvironment") { if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"usesenvironment\" expects no parameters"); DBGLOG(DBG, "External Atom uses environment"); usesEnvironment = true; } else if (name == "finitedomain") { if (param2 != ID_FAIL) throw GeneralError("Property \"finitedomain\" expects less than two parameters"); if (param1 == ID_FAIL) { DBGLOG(DBG, "External Atom has a finite domain in all output positions"); for (uint32_t i = 0; i < atom.tuple.size(); ++i) { finiteOutputDomain.insert(i); } } else { bool found = false; if (!param1.isIntegerTerm()) throw GeneralError("The parameter of property \"finitedomain\" must be an integer"); finiteOutputDomain.insert(param1.address); } } else if (name == "relativefinitedomain") { if (param1 == ID_FAIL || param2 == ID_FAIL) throw GeneralError("Property \"relativefinitedomain\" expects two parameters"); int wrt; bool found = false; for (uint32_t i = 0; i < atom.inputs.size(); ++i) { if (atom.inputs[i] == param2) { wrt = i; found = true; break; } } if (!found) throw SyntaxError("Property refers to invalid input parameter"); if (!param1.isIntegerTerm()) throw GeneralError("The first parameter of property \"relativefinitedomain\" must be an integer"); relativeFiniteOutputDomain.insert(std::pair<int, int>(param1.address, wrt)); } else if (name == "finitefiber") { if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"finitefiber\" expects no parameters"); DBGLOG(DBG, "External Atom has a finite fiber"); finiteFiber = true; } else if (name == "wellorderingstrlen") { if (param1 == ID_FAIL || param2 == ID_FAIL) throw GeneralError("Property \"wellordering\" expects two parameters"); DBGLOG(DBG, "External Atom has a wellordering using strlen"); wellorderingStrlen.insert(std::pair<int, int>(param1.address, param2.address)); } else if (name == "wellordering") { if (param1 == ID_FAIL || param2 == ID_FAIL) throw GeneralError("Property \"wellordering\" expects two parameters"); DBGLOG(DBG, "External Atom has a wellordering using natural"); wellorderingNatural.insert(std::pair<int, int>(param1.address, param2.address)); } else if (name == "supportsets") { if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"supportsets\" expects no parameters"); DBGLOG(DBG, "External Atom provides support sets"); supportSets = true; } else if (name == "completepositivesupportsets") { if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"completepositivesupportsets\" expects no parameters"); DBGLOG(DBG, "External Atom provides complete positive support sets"); supportSets = true; completePositiveSupportSets = true; } else if (name == "completenegativesupportsets") { if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"completepositivesupportsets\" expects no parameters"); DBGLOG(DBG, "External Atom provides complete negative support sets"); supportSets = true; completeNegativeSupportSets = true; } else if (name == "variableoutputarity") { if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"variableoutputarity\" expects no parameters"); DBGLOG(DBG, "External Atom has a variable output arity"); variableOutputArity = true; } else if (name == "caresaboutassigned") { if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"caresaboutassigned\" expects no parameters"); DBGLOG(DBG, "External Atom cares about assigned atoms"); caresAboutAssigned = true; } else if (name == "caresaboutchanged") { if (param1 != ID_FAIL || param2 != ID_FAIL) throw GeneralError("Property \"caresaboutchanged\" expects no parameters"); DBGLOG(DBG, "External Atom has a variable output arity"); caresAboutChanged = true; } else { throw SyntaxError("Property \"" + name + "\" unrecognized"); } }
void Lexer::read_token(bool allow_glob) { tok_.str = cur_; while (isspace(*tok_.str)) ++tok_.str; const char* ptr = tok_.str; switch (*ptr) { case '\0': case '#': tok_.type = kTokenNop; break; case '\'': { tok_.type = kTokenString; const char* end = strchr(ptr + 1, '\''); if (end == NULL) throw SyntaxError("unfinished string"); ptr = end + 1; break; } case '>': ++ptr; if (*ptr == '=') { tok_.type = kTokenGE; ++ptr; } else if (*ptr == '>') { tok_.type = kTokenAppend; ++ptr; } else tok_.type = kTokenGT; break; case '<': ++ptr; if (*ptr == '=') { tok_.type = kTokenLE; ++ptr; } else if (*ptr == '>') { tok_.type = kTokenNE; ++ptr; } else tok_.type = kTokenLT; break; case '=': ++ptr; if (*ptr == '=') { tok_.type = kTokenEQ; ++ptr; } else tok_.type = kTokenAssign; break; case '+': ++ptr; if (*ptr == '-') { tok_.type = kTokenPlusMinus; ++ptr; } else if (*ptr == '=') { tok_.type = kTokenAddAssign; ++ptr; } else tok_.type = kTokenPlus; break; case '-': ++ptr; if (*ptr == '=') { tok_.type = kTokenSubAssign; ++ptr; } else tok_.type = kTokenMinus; break; case '!': ++ptr; if (*ptr == '=') { tok_.type = kTokenNE; ++ptr; } else tok_.type = kTokenBang; break; case '.': ++ptr; if (isdigit(*ptr)) { char* endptr; tok_.value.d = strtod(ptr-1, &endptr); ptr = endptr; tok_.type = kTokenNumber; } else if (*ptr == '.') { ++ptr; if (*ptr == '.') // 3rd dot ++ptr; tok_.type = kTokenDots; } else tok_.type = kTokenDot; break; case '@': ++ptr; tok_.type = kTokenDataset; if (*ptr == '*') { tok_.value.i = kAll; ++ptr; } else if (*ptr == '+') { tok_.value.i = kNew; ++ptr; } else if (isdigit(*ptr)) { char *endptr; tok_.value.i = strtol(ptr, &endptr, 10); ptr = endptr; } else throw SyntaxError("unexpected character after '@'"); break; case '$': ++ptr; // allow_glob decides if the '*' is read ("delete $p*") // or not ("$c=$a*$b"). Always read "$*" (it's not ambigous and // we do't want error when peeking) if (! (isalpha(*ptr) || *ptr == '_' || *ptr == '*')) throw SyntaxError("unexpected character after '$'"); tok_.type = kTokenVarname; while (isalnum(*ptr) || *ptr == '_' || (allow_glob && *ptr == '*')) ++ptr; break; case '%': ++ptr; // the same rules as in the case of '$' if (! (isalpha(*ptr) || *ptr == '_' || *ptr == '*')) throw SyntaxError("unexpected character after '%'"); tok_.type = kTokenFuncname; while (isalnum(*ptr) || *ptr == '_' || (allow_glob && *ptr == '*')) ++ptr; break; case '(': tok_.type = kTokenOpen; ++ptr; break; case ')': tok_.type = kTokenClose; ++ptr; break; case '[': tok_.type = kTokenLSquare; ++ptr; break; case ']': tok_.type = kTokenRSquare; ++ptr; break; case '{': tok_.type = kTokenLCurly; ++ptr; break; case '}': tok_.type = kTokenRCurly; ++ptr; break; case '*': tok_.type = kTokenMult; ++ptr; break; case '/': tok_.type = kTokenDiv; ++ptr; break; case '^': tok_.type = kTokenPower; ++ptr; break; case ',': tok_.type = kTokenComma; ++ptr; break; case ';': tok_.type = kTokenSemicolon; ++ptr; break; case ':': tok_.type = kTokenColon; ++ptr; break; case '~': tok_.type = kTokenTilde; ++ptr; break; case '?': tok_.type = kTokenQMark; ++ptr; break; default: if (isdigit(*ptr)) { char* endptr; tok_.value.d = strtod(ptr, &endptr); ptr = endptr; tok_.type = kTokenNumber; } else if (isupper(*ptr)) { ++ptr; if (isalnum(*ptr)) { while (isalnum(*ptr)) ++ptr; tok_.type = kTokenCname; } else tok_.type = kTokenUletter; } else if (isalpha(*ptr) || *ptr == '_') { while (isalnum(*ptr) || *ptr == '_') ++ptr; tok_.type = kTokenLname; } else throw SyntaxError("unexpected character: " + string(ptr, 1)); } tok_.length = ptr - tok_.str; cur_ = ptr; }
void ParserDriver::parse( std::fstream& programFile, bool printOutput ){ Scanner scanner( &programFile ); Token currentInputToken; Symbol topStackSymbol; // Formatting for output int fileWidth = scanner.getProgramFileLength(); std::string currentStackValues = ""; //Push(S); � � Push the Start Symbol onto an empty stack parseStack.push_front( grammar.getStartSymbol() ); // let a be the current input token currentInputToken = scanner.peekNextToken(); if( printOutput ){ std::cout << "\n\n RemainingInput" << std::string( fileWidth - (fileWidth - 11), ' ' ) << "\t Action\t" << "ParseStack\n" << " --------------------------------------------------------------------------------"; } while( !parseStack.empty() ){ if( printOutput ){ std::cout << "\n"; scanner.printRemainingFile(); std::cout << std::string( fileWidth - (fileWidth - scanner.getScannerBufferPosition()), ' ' ) << "\t "; currentStackValues = ""; for( int indexStack = parseStack.size() -1; indexStack > -1 ; indexStack -- ){ currentStackValues += parseStack[indexStack] + " "; } } // let X be the top stack symbol; let a be the current input token topStackSymbol = parseStack.front(); //if X in nonterminals if( grammar.nonterminalSet.contains( topStackSymbol ) ){ // if T(X, a) = X �> Y1Y2. . .Ym try{ Production production = parseTable->getPredictProduction( topStackSymbol, (tokenEnumsValues[currentInputToken.getTokenType()] != "" ) ? tokenEnumsValues[currentInputToken.getTokenType()] : currentInputToken.getTokenTypeString() ); //Expand nonterminal, replace X with Y1Y2. . .Ym on the stack parseStack.pop_front(); for( int indexRHS = production.getRHS().size() - 1; indexRHS > -1; indexRHS -- ){ if( production.getRHS()[indexRHS] != "" && production.getRHS()[indexRHS][0] != '#' ) parseStack.push_front( production.getRHS()[indexRHS] ); } if( printOutput ){ std::cout << parseTable->getPredictIndex( topStackSymbol, (tokenEnumsValues[currentInputToken.getTokenType()] != "" ) ? tokenEnumsValues[currentInputToken.getTokenType()] : currentInputToken.getTokenTypeString() ); } } catch ( IndexOutOfBounds e ) { throw SyntaxError("Syntax error at: " + currentInputToken.getTokenValue()); } } // X in terminals else { // Match of X worked parseStack.pop_front(); scanner.scannerDriver(); if( !scanner.isDoneScanning() ) currentInputToken = scanner.peekNextToken(); if( printOutput ){ std::cout << "MATCH"; } } if( printOutput ){ std::cout << "\t\t" << currentStackValues; } } }
void DOS_Shell::CMD_IF(char * args) { HELP("IF"); StripSpaces(args,'='); bool has_not=false; while (strncasecmp(args,"NOT",3) == 0) { if (!isspace(*reinterpret_cast<unsigned char*>(&args[3])) && (args[3] != '=')) break; args += 3; //skip text //skip more spaces StripSpaces(args,'='); has_not = !has_not; } if(strncasecmp(args,"ERRORLEVEL",10) == 0) { args += 10; //skip text //Strip spaces and == StripSpaces(args,'='); char* word = StripWord(args); if(!isdigit(*word)) { WriteOut(MSG_Get("SHELL_CMD_IF_ERRORLEVEL_MISSING_NUMBER")); return; } Bit8u n = 0; do n = n * 10 + (*word - '0'); while (isdigit(*++word)); if(*word && !isspace(*word)) { WriteOut(MSG_Get("SHELL_CMD_IF_ERRORLEVEL_INVALID_NUMBER")); return; } /* Read the error code from DOS */ if ((dos.return_code>=n) ==(!has_not)) DoCommand(args); return; } if(strncasecmp(args,"EXIST ",6) == 0) { args += 6; //Skip text StripSpaces(args); char* word = StripArg(args); if (!*word) { WriteOut(MSG_Get("SHELL_CMD_IF_EXIST_MISSING_FILENAME")); return; } { /* DOS_FindFirst uses dta so set it to our internal dta */ RealPt save_dta=dos.dta(); dos.dta(dos.tables.tempdta); bool ret=DOS_FindFirst(word,0xffff & ~DOS_ATTR_VOLUME); dos.dta(save_dta); if (ret==(!has_not)) DoCommand(args); } return; } /* Normal if string compare */ char* word1 = args; // first word is until space or = while (*args && !isspace(*reinterpret_cast<unsigned char*>(args)) && (*args != '=')) args++; char* end_word1 = args; // scan for = while (*args && (*args != '=')) args++; // check for == if ((*args==0) || (args[1] != '=')) { SyntaxError(); return; } args += 2; StripSpaces(args,'='); char* word2 = args; // second word is until space or = while (*args && !isspace(*reinterpret_cast<unsigned char*>(args)) && (*args != '=')) args++; if (*args) { *end_word1 = 0; // mark end of first word *args++ = 0; // mark end of second word StripSpaces(args,'='); if ((strcmp(word1,word2)==0)==(!has_not)) DoCommand(args); } }
SAWYER_EXPORT std::string Error::eval(const Grammar&, const std::vector<std::string> &args) { ASSERT_require(args.size() == 1); throw SyntaxError(args[0]); }