Пример #1
0
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");
        }
    }
Пример #2
0
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;
}
Пример #3
0
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;
		}
	}
}
Пример #4
0
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);
	}
}
Пример #5
0
SAWYER_EXPORT std::string
Error::eval(const Grammar&, const std::vector<std::string> &args) {
    ASSERT_require(args.size() == 1);
    throw SyntaxError(args[0]);
}