Пример #1
0
/**
 * Parses the keyword "namespace" from the given token stack
 */
int CodeParser::parseKeyword_NameSpace( Scope* scope, TokenStack* stack ) {
	const char* name;
	Token* t;

	// validate incoming scope
	if( scope->getScopeType() != NAMESPACE_SCOPE ) {
		SYNTAX_ERROR( "Namespaces cannot be defined in this scope", stack->last() );
		return -1;
	}

	// the next token must be the identifier
	if( !( name = state->getIdentifierName( stack, "namespace" ) ) ) {
		return -1;
	}

	// create the name space
	NameSpace* ns = new NameSpace( name, scope );

	// add the name space to the state
	if( !state->addNameSpace( ns ) ) {
		printf( "Namespace '%s' already exists\n", name );
		return -4;
	}

	// the next element must be a code block
	if( !stack->hasNext() || !( t = stack->peek() ) || ( t->getType() != tok::CODE_BLOCK ) ) {
		SYNTAX_ERROR( "unexpected token", t );
		return -5;
	}

	// process the code block
	return parse( ns, ((ComplexToken*)t)->getChildren() );
}
Пример #2
0
RobotInterface::Robot& RobotInterface::XMLReader::Private::readRobotFile(const std::string &fileName)
{
    filename = fileName;
#ifdef WIN32
    std::replace(filename.begin(), filename.end(), '/', '\\');
#endif

    curr_filename = fileName;
#ifdef WIN32
    path = filename.substr(0, filename.rfind("\\"));
#else // WIN32
    path = filename.substr(0, filename.rfind("/"));
#endif //WIN32

    yDebug() << "Reading file" << filename.c_str();
    TiXmlDocument *doc = new TiXmlDocument(filename.c_str());
    if (!doc->LoadFile()) {
        SYNTAX_ERROR(doc->ErrorRow()) << doc->ErrorDesc();
    }

    if (!doc->RootElement()) {
        SYNTAX_ERROR(doc->Row()) << "No root element.";
    }

    for (TiXmlNode* childNode = doc->FirstChild(); childNode != 0; childNode = childNode->NextSibling()) {
        if (childNode->Type() == TiXmlNode::TINYXML_UNKNOWN) {
            if(dtd.parse(childNode->ToUnknown(), curr_filename)) {
                break;
            }
        }
    }

    if (!dtd.valid()) {
        SYNTAX_WARNING(doc->Row()) << "No DTD found. Assuming version robotInterfaceV1.0";
        dtd.setDefault();
        dtd.type = RobotInterfaceDTD::DocTypeRobot;
    }

    if(dtd.type != RobotInterfaceDTD::DocTypeRobot) {
        SYNTAX_WARNING(doc->Row()) << "Expected document of type" << DocTypeToString(RobotInterfaceDTD::DocTypeRobot)
                                       << ". Found" << DocTypeToString(dtd.type);
    }

    if(dtd.majorVersion != 1 || dtd.minorVersion != 0) {
        SYNTAX_WARNING(doc->Row()) << "Only robotInterface DTD version 1.0 is supported";
    }

    readRobotTag(doc->RootElement());
    delete doc;

    // yDebug() << robot;

    return robot;
}
Пример #3
0
/**
 * Parses the keyword "class" from the given token stack
 */
int CodeParser::parseKeyword_Class( Scope* scope, TokenStack* stack ) {
	Class* classdef;
	const char* name;
	Token* t;

	// validate incoming scope
	if( scope->getScopeType() != NAMESPACE_SCOPE ) {
		SYNTAX_ERROR( "Classes cannot be defined in this scope", stack->last() );
		return -1;
	}

	// the next token must be the identifier
	if( !( name = state->getIdentifierName( stack, "class" ) ) ) {
		return -2;
	}

	// get the name space
	NameSpace* ns = (NameSpace*)scope;
	printf( "class '%s' in namespace '%s' modifiers = %s\n", name, ns->getName(), toBinary( modifiers ) );

	// TODO check for inheritance! multiple inheritance?
	// - class MyChild extends MyParent { ... }
	// - class StrobeLamp extends Lamp, Strobe { ... }

	// create the class
	classdef = new Class( name, ns->getName(), ns, modifiers );
	this->modifiers = 0;

	// add the name space to the state
	if( !ns->addClass( classdef ) ) {
		char* error = new char[256];
		sprintf( error, "Class '%s' already exists in namespace '%s'\n", name, ns->getName() );
		SYNTAX_ERROR( error, stack->last() );
		delete error;
		return -4;
	}

	// the next element must be a code block
	if( !stack->hasNext() || !( t = stack->peek() ) || ( t->getType() != tok::CODE_BLOCK ) ) {
		SYNTAX_ERROR( "unexpected token", t );
		return -5;
	}

	// process the code block
	int errorCode = parse( classdef, ((ComplexToken*)t)->getChildren() );

	// register the class
	state->addClass( classdef );

	// reset the class-level counters
	state->resetCounters();
	return errorCode;
}
Пример #4
0
RobotInterface::Robot& RobotInterface::XMLReader::Private::readRobotTag(TiXmlElement *robotElem)
{
    if (robotElem->ValueStr().compare("robot") != 0) {
        SYNTAX_ERROR(robotElem->Row()) << "Root element should be \"robot\". Found" << robotElem->ValueStr();
    }

    if (robotElem->QueryStringAttribute("name", &robot.name()) != TIXML_SUCCESS) {
        SYNTAX_ERROR(robotElem->Row()) << "\"robot\" element should contain the \"name\" attribute";
    }

#if TINYXML_UNSIGNED_INT_BUG
    if (robotElem->QueryUnsignedAttribute("build", &robot.build()) != TIXML_SUCCESS) {
        // No build attribute. Assuming build="0"
        SYNTAX_WARNING(robotElem->Row()) << "\"robot\" element should contain the \"build\" attribute [unsigned int]. Assuming 0";
    }
#else
    int tmp;
    if (robotElem->QueryIntAttribute("build", &tmp) != TIXML_SUCCESS || tmp < 0) {
        // No build attribute. Assuming build="0"
        SYNTAX_WARNING(robotElem->Row()) << "\"robot\" element should contain the \"build\" attribute [unsigned int]. Assuming 0";
        tmp = 0;
    }
    robot.build() = (unsigned)tmp;
#endif

    if (robotElem->QueryStringAttribute("portprefix", &robot.portprefix()) != TIXML_SUCCESS) {
        SYNTAX_WARNING(robotElem->Row()) << "\"robot\" element should contain the \"portprefix\" attribute. Using \"name\" attribute";
        robot.portprefix() = robot.name();
    }

    // yDebug() << "Found robot [" << robot.name() << "] build [" << robot.build() << "] portprefix [" << robot.portprefix() << "]";

    for (TiXmlElement* childElem = robotElem->FirstChildElement(); childElem != 0; childElem = childElem->NextSiblingElement()) {
        if (childElem->ValueStr().compare("device") == 0 || childElem->ValueStr().compare("devices") == 0) {
            DeviceList childDevices = readDevices(childElem);
            for (DeviceList::const_iterator it = childDevices.begin(); it != childDevices.end(); ++it) {
                robot.devices().push_back(*it);
            }
        } else {
            ParamList childParams = readParams(childElem);
            for (ParamList::const_iterator it = childParams.begin(); it != childParams.end(); ++it) {
                robot.params().push_back(*it);
            }
        }
    }

    return robot;
}
Пример #5
0
/**
 * Parses the text contained within the given token stack
 */
int CodeParser::parseKeyword( Scope* scope, TokenStack* stack, const char* keyword ) {
	int errorCode = 0;

	// TODO delete, do-while, for, foreach
	// TODO if-else, try-catch, throw, while

	// handle the keyword
	switch( state->lookupKeyword( keyword ) ) {
		case KW_ABSTRACT:	errorCode = updateModifiers( ABSTRACT, stack ); break;
		case KW_CLASS:		errorCode = parseKeyword_Class( scope, stack ); break;
		case KW_FINAL:		errorCode = updateModifiers( FINAL, stack ); break;
		case KW_IMPORT:		errorCode = parseKeyword_Import( scope, stack ); break;
		case KW_NAMESPACE:	errorCode = parseKeyword_NameSpace( scope, stack ); break;
		case KW_NEW:		errorCode = parseKeyword_New( scope, stack ); break;
		case KW_PACKAGED:	errorCode = updateModifiers( PACKAGE, stack ); break;
		case KW_PRIVATE:	errorCode = updateModifiers( PRIVATE, stack ); break;
		case KW_PROTECTED:	errorCode = updateModifiers( PROTECTED, stack ); break;
		case KW_PUBLIC:		errorCode = updateModifiers( PUBLIC, stack ); break;
		case KW_RETURN:		errorCode = parseKeyword_Return( scope, stack ); break;
		case KW_STATIC:		errorCode = updateModifiers( STATIC, stack ); break;
		case KW_VIRTUAL:	errorCode = updateModifiers( VIRTUAL, stack ); break;
		default:
			char *message = new char[256];
			sprintf( message, "Keyword '%s' was not handled", keyword );
			SYNTAX_ERROR( message, stack->last() );
			delete message;
			errorCode = -1;
	}

	// success
	return errorCode;
}
Пример #6
0
extern cv_t c_eval(obj_t cont, obj_t values)
{
    assert(is_cont4(cont));
    obj_t expr = cont4_arg(cont);
    EVAL_LOG("expr=%O", expr);
    COULD_RETRY();
    if (is_self_evaluating(expr))
	return cv(cont_cont(cont), CONS(expr, values));
    else if (is_symbol(expr)) {
	obj_t env = cont_env(cont);
	obj_t val = env_lookup(env, expr);
	return cv(cont_cont(cont), CONS(val, values));
#if !OLD_ENV
    } else if (is_env_ref(expr)) {
	return cv(cont_cont(cont),
		  CONS(env_ref_lookup(cont_env(cont), expr), values));
#endif
    } else if (is_application(expr)) {
	obj_t operator = application_operator(expr);
	obj_t env = cont_env(cont);
	obj_t second = make_cont4(c_eval_operator,
				  cont_cont(cont),
				  env,
				  expr);
	obj_t first = make_cont4(c_eval, second, env, operator);
	return cv(first, values);
    }
    SYNTAX_ERROR(expr, expr, "must be expression");
}
Пример #7
0
RobotInterface::ParamList RobotInterface::XMLReader::Private::readParams(TiXmlElement* paramsElem)
{
    const std::string &valueStr = paramsElem->ValueStr();

    if (valueStr.compare("param") != 0 &&
        valueStr.compare("group") != 0 &&
        valueStr.compare("paramlist") != 0 &&
        valueStr.compare("subdevice") != 0 &&
        valueStr.compare("params") != 0)
    {
        SYNTAX_ERROR(paramsElem->Row()) << "Expected \"param\", \"group\", \"paramlist\","
                << "\"subdevice\", or \"params\". Found" << valueStr;
    }

    if (valueStr.compare("param") == 0) {
        ParamList params;
        params.push_back(readParamTag(paramsElem));
        return params;
    } else if (valueStr.compare("group") == 0) {
        ParamList params;
        params.push_back(readGroupTag(paramsElem));
        return params;
    } else if (valueStr.compare("paramlist") == 0) {
        return readParamListTag(paramsElem);
    } else if (valueStr.compare("subdevice") == 0) {
        return readSubDeviceTag(paramsElem);
    }
    // "params"
    return readParamsTag(paramsElem);
}
Пример #8
0
/**
 * Parses a type definition
 */
TypeReference* CodeParser::parseType( Scope* scope, TokenStack* stack ) {
	const char* typeName;
	TypeReference* type;
	Token *t;

	// the next element must be alphanumeric
	if( !( t = stack->next() ) ||
		 ( t->getType() != tok::ALPHA_NUMERIC ) ||
		 !( typeName = t->getText() ) ||
		 !state->isClass( typeName ) ) {
		SYNTAX_ERROR( "type identifier expected", stack->last() );
		return NULL;
	}

	// create the type
	type = new TypeReference( typeName );

	// is the type an array? (e.g. "int[] field")
	if( stack->hasNext() &&
		( stack->peek()->getType() == tok::BRACKET_BLOCK ) &&
		( t = stack->next() ) ) {
		// TODO finish adding logic here
		type->setArray( true );
		printf( "array = '%s'\n", t->getText() );
	}

	// return the class reference
	return type;
}
Пример #9
0
static cv_t c_eval_operator(obj_t cont, obj_t values)
{
    assert(is_cont4(cont));
    obj_t appl = cont4_arg(cont);
    obj_t operator = CAR(values);
    EVAL_LOG("appl=%O operator=%O", appl, operator);
    COULD_RETRY();
    if (!is_procedure(operator))
	SYNTAX_ERROR(operator, operator, "must be procedure");
    if (!procedure_args_evaluated(operator)) {
	assert(procedure_is_C(operator) && "implement Scheme special forms");
	if (procedure_is_raw(operator)) {
	    return ((cont_proc_t)procedure_code(operator))(cont, values);
	} else {
	    // N.B., call proc after all other allocations.
	    obj_t arg_list = application_operands(appl);
	    obj_t new_values = CONS(make_uninitialized(), CDR(values));
	    pair_set_car(new_values, apply_proc(operator, arg_list));
	    return cv(cont_cont(cont), new_values);
	}
    }
    obj_t arg_list = reverse_list(application_operands(appl));
    cont = make_cont5(c_apply_proc,
		      cont_cont(cont),
		      cont_env(cont),
		      operator,
		      CDR(values));
    while (!is_null(arg_list)) {
	cont = make_cont4(c_eval, cont, cont_env(cont), CAR(arg_list));
	arg_list = CDR(arg_list);
    }
    return cv(cont, EMPTY_LIST);
}
Пример #10
0
RobotInterface::ActionList RobotInterface::XMLReader::Private::readActionsTag(TiXmlElement *actionsElem)
{
    const std::string &valueStr = actionsElem->ValueStr();

    if (valueStr.compare("actions") != 0) {
        SYNTAX_ERROR(actionsElem->Row()) << "Expected \"actions\". Found" << valueStr;
    }

    std::string filename;
    if (actionsElem->QueryStringAttribute("file", &filename) == TIXML_SUCCESS) {
        // yDebug() << "Found actions file [" << filename << "]";
#ifdef WIN32
        std::replace(filename.begin(), filename.end(), '/', '\\');
        filename = path + "\\" + filename;
#else // WIN32
        filename = path + "/" + filename;
#endif //WIN32
        return readActionsFile(filename);
    }

    std::string robotName;
    if (actionsElem->QueryStringAttribute("robot", &robotName) != TIXML_SUCCESS) {
        SYNTAX_WARNING(actionsElem->Row()) << "\"actions\" element should contain the \"robot\" attribute";
    }

    if (robotName != robot.name()) {
        SYNTAX_WARNING(actionsElem->Row()) << "Trying to import a file for the wrong robot. Found" << robotName << "instead of" << robot.name();
    }

    unsigned int build;
#if TINYXML_UNSIGNED_INT_BUG
    if (actionsElem->QueryUnsignedAttribute("build", &build()) != TIXML_SUCCESS) {
        // No build attribute. Assuming build="0"
        SYNTAX_WARNING(actionsElem->Row()) << "\"actions\" element should contain the \"build\" attribute [unsigned int]. Assuming 0";
    }
#else
    int tmp;
    if (actionsElem->QueryIntAttribute("build", &tmp) != TIXML_SUCCESS || tmp < 0) {
        // No build attribute. Assuming build="0"
        SYNTAX_WARNING(actionsElem->Row()) << "\"actions\" element should contain the \"build\" attribute [unsigned int]. Assuming 0";
        tmp = 0;
    }
    build = (unsigned)tmp;
#endif

    if (build != robot.build()) {
        SYNTAX_WARNING(actionsElem->Row()) << "Import a file for a different robot build. Found" << build << "instead of" << robot.build();
    }

    ActionList actions;
    for (TiXmlElement* childElem = actionsElem->FirstChildElement(); childElem != 0; childElem = childElem->NextSiblingElement()) {
        ActionList childActions = readActions(childElem);
        for (ActionList::const_iterator it = childActions.begin(); it != childActions.end(); ++it) {
            actions.push_back(*it);
        }
    }

    return actions;
}
Пример #11
0
AST* QueryParser::parse(std::string str,
                        AST* ast,
                        const int level)
{
    if(NULL == ast)
        ast = new AST();
 
    #ifdef DEBUG_PARSING_LEVELS
    if(level < 1)
        std::cout << "Parsing:" << std::endl << str;
    #endif
 
    if(str.size() < 2) return NULL;
    size_t beg = std::string::npos,
           end = std::string::npos;

	removeComments(str);
	str = StringUtils::trim(str);
    std::string header,
                body;
    
    header = StringUtils::extract(str,
                                  beg,
                                  end,
                                  HEADER_BEGIN,
                                  HEADER_END);
    if(header.size() < 2 || beg != 0)
    {
        SYNTAX_ERROR("No header in query", header);
        return NULL;
    }

    std::cout << "\nParsing header: " << header;
    Header* h = subParse(header, 1);
    Body* b = NULL;
    
    body = str.substr(end);
    
    if(body.size() < 2)
    {
        WARNING("Body is empty");
    }
    else
        b = subParse(body, 1);
    ASSERT(b != 0);  
    
    if(h != NULL)
    {
        ast->setHeader(h);
        ast->setBody(b);
    }
    else
        return NULL;

    return ast;

    
}
Пример #12
0
/**
 * Parses the class member (field or method) contained within the given token stack
 */
int CodeParser::parseClassMember( Scope* scope, TokenStack* stack ) {
	int errorCode = 0;
	TypeReference* type;
	const char* name;

	// the following types are parsed:
	// 	method layout: "[static] [final] type|[]| methodName(...) { ... }"
	//	field layout:  "[static] [final] type|[]| fieldName| = ....|"

	int step = 0;
	bool done = false;
	while( !done && stack->hasNext() ) {
		switch( ++step ) {
			// step 1: get the type of the class member (e.g. "string" or "string[]")
			case 1:
				// extract the name of the identifier
				if( !( type = parseType( scope, stack ) ) ) {
					return -1;
				}
				break;

			// step 2: get the class member name
			case 2:
				// get the type name
				if( !( name = state->getIdentifierName( stack, "class member" ) ) ) {
					return -2;
				}
				break;

			// step 3: get the class member instance (field or method)
			// 			method layout: "[static] [final] type methodName(...) { ... }"
			//			field layout:  "[static] [final] type fieldName[ = ....]"
			case 3:
				// each child should be a method (e.g. "type methodName(...)") or field (e.g. "type fieldName")
				// if there is a parenthesis block, it's likely to be a method
				errorCode = ( stack->peek()->getType() == tok::PARENTHESIS_BLOCK )
						? parseMethod( scope, name, type, stack )
						: parseField( scope, name, type, stack );

				// was there an error?
				if( errorCode ) {
					return errorCode;
				}
				done = true;
				break;
		}
	}

	// did it complete?
	if( !done ) {
		SYNTAX_ERROR( "unexpected end of statement", stack->last() );
		return -4;
	}

	// return the error code
	return 0;
}
Пример #13
0
RobotInterface::ActionList RobotInterface::XMLReader::Private::readActionsFile(const std::string &fileName)
{
    std::string old_filename = curr_filename;
    curr_filename = fileName;

    yDebug() << "Reading file" << fileName.c_str();
    TiXmlDocument *doc = new TiXmlDocument(fileName.c_str());
    if (!doc->LoadFile()) {
        SYNTAX_ERROR(doc->ErrorRow()) << doc->ErrorDesc();
    }

    if (!doc->RootElement()) {
        SYNTAX_ERROR(doc->Row()) << "No root element.";
    }

    RobotInterfaceDTD actionsFileDTD;
    for (TiXmlNode* childNode = doc->FirstChild(); childNode != 0; childNode = childNode->NextSibling()) {
        if (childNode->Type() == TiXmlNode::TINYXML_UNKNOWN) {
            if(actionsFileDTD.parse(childNode->ToUnknown(), curr_filename)) {
                break;
            }
        }
    }

    if (!actionsFileDTD.valid()) {
        SYNTAX_WARNING(doc->Row()) << "No DTD found. Assuming version robotInterfaceV1.0";
        actionsFileDTD.setDefault();
        actionsFileDTD.type = RobotInterfaceDTD::DocTypeActions;
    }

    if (actionsFileDTD.type != RobotInterfaceDTD::DocTypeActions) {
        SYNTAX_ERROR(doc->Row()) << "Expected document of type" << DocTypeToString(RobotInterfaceDTD::DocTypeActions)
                                 << ". Found" << DocTypeToString(actionsFileDTD.type);
    }

    if (actionsFileDTD.majorVersion != dtd.majorVersion) {
        SYNTAX_ERROR(doc->Row()) << "Trying to import a file with a different robotInterface DTD version";
    }

    RobotInterface::ActionList actions = readActionsTag(doc->RootElement());
    delete doc;
    curr_filename = old_filename;
    return actions;
}
Пример #14
0
RobotInterface::ParamList RobotInterface::XMLReader::Private::readParamsTag(TiXmlElement *paramsElem)
{
    const std::string &valueStr = paramsElem->ValueStr();

    if (valueStr.compare("params") != 0) {
        SYNTAX_ERROR(paramsElem->Row()) << "Expected \"params\". Found" << valueStr;
    }

    std::string filename;
    if (paramsElem->QueryStringAttribute("file", &filename) == TIXML_SUCCESS) {
        // yDebug() << "Found params file [" << filename << "]";
        filename=rf.findFileByName(filename);
        return readParamsFile(filename);
    }

    std::string robotName;
    if (paramsElem->QueryStringAttribute("robot", &robotName) != TIXML_SUCCESS) {
        SYNTAX_WARNING(paramsElem->Row()) << "\"params\" element should contain the \"robot\" attribute";
    }

    if (robotName != robot.name()) {
        SYNTAX_WARNING(paramsElem->Row()) << "Trying to import a file for the wrong robot. Found" << robotName << "instead of" << robot.name();
    }

    unsigned int build;
#if TINYXML_UNSIGNED_INT_BUG
    if (paramsElem->QueryUnsignedAttribute("build", &build()) != TIXML_SUCCESS) {
        // No build attribute. Assuming build="0"
        SYNTAX_WARNING(paramsElem->Row()) << "\"params\" element should contain the \"build\" attribute [unsigned int]. Assuming 0";
    }
#else
    int tmp;
    if (paramsElem->QueryIntAttribute("build", &tmp) != TIXML_SUCCESS || tmp < 0) {
        // No build attribute. Assuming build="0"
        SYNTAX_WARNING(paramsElem->Row()) << "\"params\" element should contain the \"build\" attribute [unsigned int]. Assuming 0";
        tmp = 0;
    }
    build = (unsigned)tmp;
#endif

    if (build != robot.build()) {
        SYNTAX_WARNING(paramsElem->Row()) << "Import a file for a different robot build. Found" << build << "instead of" << robot.build();
    }

    ParamList params;
    for (TiXmlElement* childElem = paramsElem->FirstChildElement(); childElem != 0; childElem = childElem->NextSiblingElement()) {
        ParamList childParams = readParams(childElem);
        for (ParamList::const_iterator it = childParams.begin(); it != childParams.end(); ++it) {
            params.push_back(*it);
        }
    }

    return params;
}
Пример #15
0
RobotInterface::Action RobotInterface::XMLReader::Private::readActionTag(TiXmlElement* actionElem)
{
    if (actionElem->ValueStr().compare("action") != 0) {
        SYNTAX_ERROR(actionElem->Row()) << "Expected \"action\". Found" << actionElem->ValueStr();
    }

    Action action;

    if (actionElem->QueryValueAttribute<ActionPhase>("phase", &action.phase()) != TIXML_SUCCESS || action.phase() == ActionPhaseUnknown) {
        SYNTAX_ERROR(actionElem->Row()) << "\"action\" element should contain the \"phase\" attribute [startup|interrupt{1,2,3}|shutdown]";
    }


    if (actionElem->QueryValueAttribute<ActionType>("type", &action.type()) != TIXML_SUCCESS || action.type() == ActionTypeUnknown) {
        SYNTAX_ERROR(actionElem->Row()) << "\"action\" element should contain the \"type\" attribute [configure|calibrate|attach|abort|detach|park|custom]";
    }

    // yDebug() << "Found action [ ]";

#if TINYXML_UNSIGNED_INT_BUG
    if (actionElem->QueryUnsignedAttribute("level", &action.level()) != TIXML_SUCCESS) {
        SYNTAX_ERROR(actionElem->Row()) << "\"action\" element should contain the \"level\" attribute [unsigned int]";
    }
#else
    int tmp;
    if (actionElem->QueryIntAttribute("level", &tmp) != TIXML_SUCCESS || tmp < 0) {
        SYNTAX_ERROR(actionElem->Row()) << "\"action\" element should contain the \"level\" attribute [unsigned int]";
    }
    action.level() = (unsigned)tmp;
#endif

    for (TiXmlElement* childElem = actionElem->FirstChildElement(); childElem != 0; childElem = childElem->NextSiblingElement()) {
        ParamList childParams = readParams(childElem);
        for (ParamList::const_iterator it = childParams.begin(); it != childParams.end(); ++it) {
            action.params().push_back(*it);
        }
    }

    // yDebug() << action;
    return action;
}
Пример #16
0
/**
 * Parses the expression from the given token stack
 */
int CodeParser::parseExpression( Scope* scope, TokenStack* stack ) {
	int errorCode = 0;
	Token* t;

	// gather the arguments up to the end of the statement
	TokenStack* substack = getStackToEndOfStatement( stack );

	// get the argument list
	while( !errorCode && substack->hasNext() && ( t = substack->next() ) ) {
		printf( "CodeParser::parseExpression: '%s' [%s]\n", t->getText(), t->getTypeName() );

		// handle the token by type
		switch( t->getType() ) {
			case tok::ALPHA_NUMERIC:
				// is the argument a field?
				if( scope->lookupField( t->getText() ) ) {
					printf( "CodeParser::parseExpression: Field - [%s]\n", t->getText() );
				}

				// is it a method call?
				else if( substack->hasNext() && substack->peek()->getType() == tok::PARENTHESIS_BLOCK ) {
					errorCode = parseExpression_MethodCall( t->getText(), scope, substack );
				}
				break;

			case tok::DECIMAL:
			case tok::INTEGER:
				break;

			case tok::DQUOTE_TEXT:
				break;

			case tok::SQUOTE_TEXT:
				break;

			case tok::OPERATOR:
				break;

			case tok::PARENTHESIS_BLOCK:
				break;

			default:
				errorCode = -1;
				SYNTAX_ERROR( "unexpected token", substack->last() );
		}
	}

	// delete the stack
	delete substack;

	// return the error code
	return errorCode;
}
Пример #17
0
RobotInterface::Device RobotInterface::XMLReader::Private::readDeviceTag(TiXmlElement *deviceElem)
{
    const std::string &valueStr = deviceElem->ValueStr();

    if (valueStr.compare("device") != 0) {
        SYNTAX_ERROR(deviceElem->Row()) << "Expected \"device\". Found" << valueStr;
    }

    Device device;

    if (deviceElem->QueryStringAttribute("name", &device.name()) != TIXML_SUCCESS) {
        SYNTAX_ERROR(deviceElem->Row()) << "\"device\" element should contain the \"name\" attribute";
    }

    // yDebug() << "Found device [" << device.name() << "]";

    if (deviceElem->QueryStringAttribute("type", &device.type()) != TIXML_SUCCESS) {
        SYNTAX_ERROR(deviceElem->Row()) << "\"device\" element should contain the \"type\" attribute";
    }

    device.params().push_back(Param("robotName", robot.portprefix().c_str()));

    for (TiXmlElement* childElem = deviceElem->FirstChildElement(); childElem != 0; childElem = childElem->NextSiblingElement()) {
        if (childElem->ValueStr().compare("action") == 0 ||
            childElem->ValueStr().compare("actions") == 0) {
            ActionList childActions = readActions(childElem);
            for (ActionList::const_iterator it = childActions.begin(); it != childActions.end(); ++it) {
                device.actions().push_back(*it);
            }
        } else {
            ParamList childParams = readParams(childElem);
            for (ParamList::const_iterator it = childParams.begin(); it != childParams.end(); ++it) {
                device.params().push_back(*it);
            }
        }
    }

    // yDebug() << device;
    return device;
}
Пример #18
0
/**
 * Parses the source code
 */
int CodeParser::parse( Scope* scope, TokenStack* stack ) {
	int errorCode = 0;
	Token *t;

	// get the command arguments
	while( !errorCode && stack->hasNext() && ( t = stack->peek() ) ) {
		//printf( "t = %s[%s]\n", t->getTypeName(), t->getText() );

		// check situationally
		switch( t->getType() ) {
			case tok::CODE_BLOCK:
				errorCode = parseAnonymuousCodeBlock( scope, ( t = stack->next() ) );
				break;

			case tok::ASSEMBLY_BLOCK:
				errorCode = assemblyParser->parse( scope, stack );
				break;

			case tok::END_OF_STATEMENT:
				t = stack->next();
				this->modifiers = 0;
				break;

			case tok::ALPHA_NUMERIC:
				// is the token a keyword?
				if( state->isKeyword( t->getText() ) ) {
					const char *keyword = stack->next()->getText();
					errorCode = parseKeyword( scope, stack, keyword );
				}

				// is it a field/method declaration?
				else if( state->isClass( t->getText() ) ) {
					errorCode = parseClassMember( scope, stack );
				}

				// must be an assignment or method invocation ...
				else {
					errorCode = parseExpression( scope, stack );
				}
				break;

			// anything else ...
			default:
				SYNTAX_ERROR( "unrecognized command", t );
				errorCode = -1;
				break;
		}
	}

	return errorCode;
}
Пример #19
0
struct Statement* parse_statement(const struct Symbol** symbols, int symbolCount, int* symbolsConsumed)
{
    struct Statement* statement;
    
    // Make sure there are symbols left
    if (symbolCount <= 0)
    {
        SYNTAX_ERROR("Unexpected EOF when looking for statement");
    }
    
    // First try to identify a print statement
    if (symbols[0]->type == SYMBOL_PRINT)
    {
        struct PrintStatement* printstatement = (struct PrintStatement*)calloc(1, sizeof(struct PrintStatement));
        statement = &printstatement->base;
        
        PRINTF_AST("PRINTSTATEMENT");
        PRINTF_AST_ENTER();
    
        printstatement->base.type = STATEMENT_TYPE_PRINT;
        printstatement->expression = parse_expression(symbols + 1, symbolCount - 1, symbolsConsumed);
        *symbolsConsumed += 1; // add print keyword
        
        PRINTF_AST_LEAVE();
    }
    
    // Second try to identify an assignment statement
    else if (symbols[0]->type == SYMBOL_IDENTIFIER && symbols[1]->type == SYMBOL_EQUALS)
    {
        struct AssignmentStatement* assignmentstatement = (struct AssignmentStatement*)calloc(1, sizeof(struct AssignmentStatement));
        statement = &assignmentstatement->base;
        
        PRINTF_AST("ASSIGNSTATEMENT");
        PRINTF_AST_ENTER();
    
        assignmentstatement->base.type = STATEMENT_TYPE_ASSIGNMENT;
        assignmentstatement->identifier = ((struct IdentifierSymbol*)symbols[0])->name;
        assignmentstatement->expression = parse_expression(symbols + 2, symbolCount - 2, symbolsConsumed);
        *symbolsConsumed += 2; // add identifier and equals
        
        PRINTF_AST_LEAVE();
    }
    
    // parse error otherwise
    else
    {
        SYNTAX_ERROR_AT(symbols[0], "Invalid beginning of statement");
    }
    
    return statement;
}
Пример #20
0
RobotInterface::Param RobotInterface::XMLReader::Private::readParamTag(TiXmlElement *paramElem)
{
    if (paramElem->ValueStr().compare("param") != 0) {
        SYNTAX_ERROR(paramElem->Row()) << "Expected \"param\". Found" << paramElem->ValueStr();
    }

    Param param;

    if (paramElem->QueryStringAttribute("name", &param.name()) != TIXML_SUCCESS) {
        SYNTAX_ERROR(paramElem->Row()) << "\"param\" element should contain the \"name\" attribute";
    }

    // yDebug() << "Found param [" << param.name() << "]";

    const char *valueText = paramElem->GetText();
    if (!valueText) {
        SYNTAX_ERROR(paramElem->Row()) << "\"param\" element should have a value [ \"name\" = " << param.name() << "]";
    }
    param.value() = valueText;

    // yDebug() << param;
    return param;
}
Пример #21
0
RobotInterface::Param RobotInterface::XMLReader::Private::readGroupTag(TiXmlElement* groupElem)
{
    if (groupElem->ValueStr().compare("group") != 0) {
        SYNTAX_ERROR(groupElem->Row()) << "Expected \"group\". Found" << groupElem->ValueStr();
    }

    Param group(true);

    if (groupElem->QueryStringAttribute("name", &group.name()) != TIXML_SUCCESS) {
        SYNTAX_ERROR(groupElem->Row()) << "\"group\" element should contain the \"name\" attribute";
    }

    // yDebug() << "Found group [" << group.name() << "]";

    ParamList params;
    for (TiXmlElement* childElem = groupElem->FirstChildElement(); childElem != 0; childElem = childElem->NextSiblingElement()) {
        ParamList childParams = readParams(childElem);
        for (ParamList::const_iterator it = childParams.begin(); it != childParams.end(); ++it) {
            params.push_back(*it);
        }
    }
    if (params.empty()) {
        SYNTAX_ERROR(groupElem->Row()) << "\"group\" cannot be empty";
    }

    std::string groupString;
    for (ParamList::iterator it = params.begin(); it != params.end(); ++it) {
        if (!groupString.empty()) {
            groupString += " ";
        }
        groupString += "(" + it->name() + " " + it->value() + ")";
    }

    group.value() = groupString;

    return group;
}
Пример #22
0
RobotInterface::ParamList RobotInterface::XMLReader::Private::readSubDeviceTag(TiXmlElement *subDeviceElem)
{
    if (subDeviceElem->ValueStr().compare("subdevice") != 0) {
        SYNTAX_ERROR(subDeviceElem->Row()) << "Expected \"subdevice\". Found" << subDeviceElem->ValueStr();
    }

    ParamList params;

//FIXME    Param featIdParam;
    Param subDeviceParam;

//FIXME    featIdParam.name() = "FeatId";
    subDeviceParam.name() = "subdevice";

//FIXME    if (subDeviceElem->QueryStringAttribute("name", &featIdParam.value()) != TIXML_SUCCESS) {
//        SYNTAX_ERROR(subDeviceElem->Row()) << "\"subdevice\" element should contain the \"name\" attribute";
//    }

    if (subDeviceElem->QueryStringAttribute("type", &subDeviceParam.value()) != TIXML_SUCCESS) {
        SYNTAX_ERROR(subDeviceElem->Row()) << "\"subdevice\" element should contain the \"type\" attribute";
    }

//FIXME    params.push_back(featIdParam);
    params.push_back(subDeviceParam);

    // yDebug() << "Found subdevice [" << params.at(0).value() << "]";

    for (TiXmlElement* childElem = subDeviceElem->FirstChildElement(); childElem != 0; childElem = childElem->NextSiblingElement()) {
        ParamList childParams = readParams(childElem);
        for (ParamList::const_iterator it = childParams.begin(); it != childParams.end(); ++it) {
            params.push_back(Param(it->name(), it->value()));
        }
    }

    // yDebug() << params;
    return params;
}
Пример #23
0
/**
 * Updates the current access modifier
 */
int CodeParser::updateModifiers( char newModifier, TokenStack* stack ) {
	// capture the unmodified state
	const char oldModifier = modifiers;

	// update the modifiers
	modifiers |= newModifier;

	// error if no change
	if( ( newModifier != 0 ) && ( modifiers == oldModifier ) ) {
		SYNTAX_ERROR( "duplicate modifier", stack->last() );
		return -1;
	}

	return 0;
}
Пример #24
0
struct StatementList* parse_statementlist(const struct Symbol** symbols, int symbolCount, int* symbolsConsumed)
{
    struct StatementList* statementlist = (struct StatementList*)calloc(1, sizeof(struct StatementList));
    
    // Make sure there are symbols left
    if (symbolCount <= 0)
    {
        SYNTAX_ERROR("Unexpected EOF when looking for statement list");
    }
    
    PRINTF_AST("STATEMENTLIST");
    PRINTF_AST_ENTER();
    
    // Start by pulling out the next statement
    int symbolsInStatement = 0;
    statementlist->statement = parse_statement(symbols, symbolCount, &symbolsInStatement);
    
    // If that is not the end of the symbols, parse more statements
    if (symbols[symbolsInStatement]->type != SYMBOL_EOF)
    {
        if (symbols[symbolsInStatement]->type == SYMBOL_EOL)
        {
            int symbolsInStatementList = 0;
            statementlist->statementlist =
                parse_statementlist(
                    &symbols[symbolsInStatement+1],
                    (symbolCount - 1) - symbolsInStatement,
                    &symbolsInStatementList);
            *symbolsConsumed = symbolsInStatement + 1 /* newline */ + symbolsInStatementList;
        }
        else
        {
            SYNTAX_ERROR_AT(symbols[symbolCount-1], "Expected newline or EOF at end of statement");
        }
    }
    
    // If that is the end of the symbols, the list is complete
    else
    {
        *symbolsConsumed = symbolsInStatement;
    }
    
    PRINTF_AST_LEAVE();
    
    return statementlist;
}
Пример #25
0
/**
 * Parses the method call within an expression
 */
int CodeParser::parseExpression_MethodCall( const char* methodName, Scope* scope, TokenStack* stack ) {
	int errorCode = 0;
	list<Parameter*> params;

	// parse the method parameters
	if( ( errorCode = parseMethodParameters( scope, stack, params ) ) ) {
		return errorCode;
	}

	// generate the method signature
	const char* signature = generateSignature( methodName, params );

	// lookup the method
	Method* method = lookupMethod( scope, signature );
	if( method == NULL ) {
		// generate the error message
		char* errorMessage = new char[256];
		sprintf( errorMessage, "Method '%s' could not be found", signature );

		// display the error message
		SYNTAX_ERROR( errorMessage, stack->last() );
		delete errorMessage;
		return -1;
	}
	else {
		printf( "CodeParser::parseExpression: Method call - [%s]\n", signature );

		// get the code buffer
		CodeBuffer* cb = scope->getCodeBuffer();

		// parse the method parameter


		// setup the method call
		// instruction: PARAMS methodParams
		// instruction: INVOKE methodSig
		OFFSET_T offset1 = cb->putInstruction( PARAMS << A_OP );
		OFFSET_T offset2 = cb->putInstruction( INVOKE << A_OP );

		// add the parameter and reference data
		scope->addParameterData( new ParameterData( state->nextParamId(), params, offset1 ) );
		scope->addReferenceData( new ReferenceData( state->nextDataRefId(), signature, offset2 ) );
		return 0;
	}
}
Пример #26
0
/**
 * Parses the keyword "return" from the given token stack
 */
int CodeParser::parseKeyword_Return( Scope* scope, TokenStack* stack ) {
	// get the scope type
	ScopeType type = scope->getScopeType();
	if( type != METHOD_SCOPE ) {
		SYNTAX_ERROR( "Statement is only permissible within a method block", stack->last() );
		return -1;
	}

	// get the method instance
	Method* method = (Method*)scope;

	// TODO support "return value" syntax

	// add the instruction
	INSTRUCTION_T instruction = RET << A_OP;
	method->getCodeBuffer()->putInstruction( instruction );
	return 0;
}
Пример #27
0
RobotInterface::ActionList RobotInterface::XMLReader::Private::readActions(TiXmlElement *actionsElem)
{
    const std::string &valueStr = actionsElem->ValueStr();

    if (valueStr.compare("action") != 0 &&
        valueStr.compare("actions") != 0)
    {
        SYNTAX_ERROR(actionsElem->Row()) << "Expected \"action\" or \"actions\". Found" << valueStr;
    }

    if (valueStr.compare("action") == 0) {
        ActionList actionList;
        actionList.push_back(readActionTag(actionsElem));
        return actionList;
    }
    // "actions"
    return readActionsTag(actionsElem);
}
Пример #28
0
RobotInterface::ParamList RobotInterface::XMLReader::Private::readParamListTag(TiXmlElement* paramListElem)
{
    if (paramListElem->ValueStr().compare("paramlist") != 0) {
        SYNTAX_ERROR(paramListElem->Row()) << "Expected \"paramlist\". Found" << paramListElem->ValueStr();
    }

    ParamList params;
    Param mainparam;

    if (paramListElem->QueryStringAttribute("name", &mainparam.name()) != TIXML_SUCCESS) {
        SYNTAX_ERROR(paramListElem->Row()) << "\"paramlist\" element should contain the \"name\" attribute";
    }

    params.push_back(mainparam);

    // yDebug() << "Found paramlist [" << params.at(0).name() << "]";

    for (TiXmlElement* childElem = paramListElem->FirstChildElement(); childElem != 0; childElem = childElem->NextSiblingElement()) {
        if (childElem->ValueStr().compare("elem") != 0) {
            SYNTAX_ERROR(childElem->Row()) << "Expected \"elem\". Found" << childElem->ValueStr();
        }

        Param childParam;

        if (childElem->QueryStringAttribute("name", &childParam.name()) != TIXML_SUCCESS) {
            SYNTAX_ERROR(childElem->Row()) << "\"elem\" element should contain the \"name\" attribute";
        }

        const char *valueText = childElem->GetText();
        if (!valueText) {
            SYNTAX_ERROR(childElem->Row()) << "\"elem\" element should have a value [ \"name\" = " << childParam.name() << "]";
        }
        childParam.value() = valueText;

        params.push_back(childParam);
    }

    if (params.empty()) {
        SYNTAX_ERROR(paramListElem->Row()) << "\"paramlist\" cannot be empty";
    }

    // +1 skips the first element, that is the main param
    for (ParamList::iterator it = params.begin() + 1; it != params.end(); ++it) {
        Param &param = *it;
        params.at(0).value() += (params.at(0).value().empty() ? "(" : " ") + param.name();
    }
    params.at(0).value() += ")";

    // yDebug() << params;
    return params;
}
Пример #29
0
/**
 * Compiles a field declaration
 */
int CodeParser::parseField( Scope* scope, const char* name, TypeReference* type, TokenStack* stack ) {
	int errorCode = 0;
	Token *t1, *t2;
	const char* data;

	// create the field, and attach it to the class
	Field* field = new Field( name, type, this->modifiers );
	printf( "field '%s' type='%s' modifiers = %s\n", name, type->getName(), toBinary( this->modifiers ) );

	// reset the modifier for the current scope
	this->modifiers = 0;

	// is there also an assignment?
	if( stack->hasNext() && !strcmp( stack->peek()->getText(), "=" ) ) {
		// capture the
		t1 = stack->next();

		// there must be another token
		if( !( t2 = stack->next() ) ) {
			SYNTAX_ERROR( "Unexpected end of statement", t1 );
			return NULL;
		}

		switch( t2->getType() ) {
			case tok::SQUOTE_TEXT:;
			case tok::DQUOTE_TEXT:
				data = t2->getText();
				setupAssignment( scope, field, data );
				break;

			default:
				parseExpression( scope, stack );
		}
	}

	// add the field to the scope
	if( !errorCode ) {
		scope->addField( field );
	}

	// TODO there may be an expression: int x = 5 * y + 1;
	return errorCode;
}
Пример #30
0
RobotInterface::DeviceList RobotInterface::XMLReader::Private::readDevices(TiXmlElement *devicesElem)
{
    const std::string &valueStr = devicesElem->ValueStr();

    if (valueStr.compare("device") != 0 &&
        valueStr.compare("devices") != 0)
    {
        SYNTAX_ERROR(devicesElem->Row()) << "Expected \"device\" or \"devices\". Found" << valueStr;
    }

    if (valueStr.compare("device") == 0) {
        // yDebug() << valueStr;
        DeviceList deviceList;
        deviceList.push_back(readDeviceTag(devicesElem));
        return deviceList;
    }
    // "devices"
    return readDevicesTag(devicesElem);
}