Exemple #1
0
// Generate appropriate signals following a comparison of an input value
void QELink::sendValue( bool match )
{
    // If input comparison matched, emit the appropriate value if required
    if( match )
    {
        if( signalTrue )
            emitValue( outTrueValue );
    }

    // If input comparison did not match, emit the appropriate value if required
    else
    {
        if( signalFalse )
            emitValue( outFalseValue );
    }
}
Exemple #2
0
void CodeEmitter::emitInstruction(AstNode node) {
    std::string name = node.sValue;
    Word word;
    word.data = 0;
    word.instruction.code = _opcodes[name];

    if(name == "null" || name == "halt" || name == "dump") {
        emitWord(word);
    } else if(name[0] == 'j') {
        if(node.children.size() == 1 && node.children.front().type == AstNode::ReferenceNode) {
            markReference(node.children.front().sValue);
            word.instruction.adr = -1;
            emitWord(word);
        } else {
            emitterError("wrong jump arguments");
        }
    } else if(name == "print") {
        if(node.children.size() == 1) {
            if(node.children.front().type == AstNode::RegisterNode) {
                word.instruction.acu = node.children.front().sValue == "B" ? 1 : 0;
                word.instruction.usr = 0;
                emitWord(word);
            } else {
                word.instruction.usr = 1;
                emitValue(node.children.front(), word);
            }
        } else {
            emitterError("too many print arguments");
        }
    } else {
        if(node.children.size() == 2 && node.children.front().type == AstNode::RegisterNode) {
            AstNode registerNode = node.children.front();

            if (registerNode.sValue != "A" && registerNode.sValue != "B") {
                emitterError("wrong register name");
            }

            word.instruction.acu = registerNode.sValue == "B" ? 1 : 0;

            AstNode valueNode = node.children.back();

            emitValue(valueNode, word);
        } else {
            emitterError("wrong instruction arguments");
        }
    }
}
Exemple #3
0
void
ZDriver::writeAcceptFunc( std::ostream &out )
{
	const std::string &extraArg = getValue( "extra_argument" ).first;

	if ( isValueSet( "parse_accept" ) )
	{
		emitFuncBreak( out );
		if ( extraArg.empty() )
			out << "void " << myPimplName << "::accept( void )" << endl();
		else
			out << "void " << myPimplName << "::accept( "
				<< extraArg << " )" << endl();
		out << "{" << endl();

		emitValue( getValue( "parse_accept" ), out );

		out << "}" << endl();
	}
}
Exemple #4
0
bool
ZDriver::writeSource( void )
{
	std::ofstream out;
	bool isOk = false;

	getFileName( myFileName, ".cpp" );
	out.open( myFileName.c_str() );

	if ( out.is_open() )
	{
		myCurLineNum = 1;
		myPimplName = "priv";
		myPimplName.append( getParserName() );
		myPimplName.append( "Impl" );

		out << "// This file auto-generated from " << getParserName()
			<< ".lem by " << VersionInfo::appName() << " version "
			<< VersionInfo::appVersion() << endl();
		out << "// Editing of this file strongly discouraged." << endl();

		emitValue( getValue( "include" ), out );
		
		out << endl() << "#include <Core.h>" << endl();
		
		std::string incName;
		Util::getFileName( incName, std::string(), getSourceFile(), ".h" );
		out << endl() << "#include \"" << incName << "\"" << endl();

		out << endl() << "#include <utility>" << endl();
		out << "#include <stack>" << endl();
		out << "#include <map>" << endl();
		out << "#include <vector>" << endl();
		out << "#include <iostream>" << endl();
		out << "#include <Util/Any.h>" << endl();

		if ( ! myNameSpace.empty() )
		{
			emitFuncBreak( out );
			out << "using " << myNameSpace;
			if ( *(myNameSpace.end()-1) != ':' )
				out << "::";
			out << getParserName() << ";" << endl();
		}
		writeImplClassDecl( out );
		writeParserCtorDtor( out );
		writeMainParserFunc( out );
		writeImplClassCtorDtor( out );
		writeShiftFunc( out );
		writeReduceFunc( out );
		writeAcceptFunc( out );
		writeDestructorHandler( out );
		writeParserUtil( out );
		writeErrorRoutines( out );
		emitValue( getValue( "code" ), out );

		isOk = true;
	}

	return isOk;
}
Exemple #5
0
bool
ZDriver::writeHeader( void )
{
	const std::string &tokenType = getValue( "token_type" ).first;
	const std::string &prefix = getValue( "token_prefix" ).first;
	std::string fileName = getOutputDir();
	std::ofstream out;
	bool isOk = false;

	getFileName( fileName, ".h" );

	out.open( fileName.c_str() );
	if ( out.is_open() )
	{
		size_t i, nSym;

		myCurLineNum = 0;
		myPimplName = "priv";
		myPimplName.append( getParserName() );
		myPimplName.append( "Impl" );


		std::string nsStart, nsEnd;
		std::string poundDef = "_";

		if ( ! myNameSpace.empty() )
		{
			std::string::size_type nsPos, oldPos;

			nsStart = myNameSpace;

			// Cheat so we get the proper number of :: replacements...
			if ( *(nsStart.end() - 1) != ':' )
				nsStart.append( "::" );

			oldPos = 0;
			nsPos = nsStart.find( "::" );
			while ( nsPos != std::string::npos )
			{
				poundDef.append( nsStart.begin() + oldPos,
								 nsStart.begin() + nsPos );
				poundDef.push_back( '_' );
				nsStart.replace( nsPos, 2, "\n{\n" );
				nsStart.insert( oldPos, "namespace " );
				nsEnd.append( "\n} // namespace\n" );
				oldPos = nsPos + 13; // len("namespace ") + len("\n{\n")
				nsPos = nsStart.find( "::", nsPos );
			}
		}

		poundDef.append( getParserName() );
		poundDef.append( "_h_" );

		out << "// This file auto-generated from " << getParserName()
			<< ".lem by " << VersionInfo::appName() << " version "
			<< VersionInfo::appVersion() << endl();
		out << "// Editing of this file strongly discouraged." << endl();

		out << endl() << "#ifndef " << poundDef << endl();
		out << "#define " << poundDef << endl();

		emitValue( getValue( "header_include" ), out );
		out << endl() << "class " << myPimplName << ";" << endl();

		out << endl() << endl() << nsStart << endl();
		myCurLineNum += std::count_if( nsStart.begin(), nsStart.end(),
									   std::bind2nd( std::equal_to<char>(), '\n' ) );

		out << "class " << getParserName() << endl() << "{" << endl()
			<< "public:" << endl();

		// Generate the terminal tokens that the lexer will feed us
		int idx = 1;

		nSym = SymbolTable::get()->getNumSymbols();
		out << endl() << "    enum Terminal" << endl() << "    {" << endl();
		out << "        " << prefix << "EOF = 0";
		for ( i = 0; i < nSym; ++i )
		{
			Symbol *sp = SymbolTable::get()->getNthSymbol( i );

			if ( Symbol::TERMINAL == sp->getType() )
			{
				out << "," << endl();
				out << "        " << prefix << sp->getName() << " = " << idx;
				++idx;
			}
		}
		out << endl() << "    };";

		// Finish out the file
		out << endl() << endl() << "    " << getParserName() << "( void );"
			<< endl();
		out << "    ~" << getParserName() << "( void );" << endl();
		out << endl() << endl();
		out << "    void parse( " << getParserName() << "::Terminal tok, ";

		if ( tokenType.empty() )
			out << "void *value";
		else
		{
			out << tokenType;
			if ( *(tokenType.end() - 1) != '*' && *(tokenType.end() - 1) != '&' )
				out << " value";
			else
				out << "value";
		}
		out << myExtraArg;
		out << " );" << endl();

		out << endl() << "private:" << endl();
		out << "	// No copying of this class" << endl();
		out << "	" << getParserName() << "( const " << getParserName()
			<< " & );" << endl();
		out << "	" << getParserName() << " &operator=( const "
			<< getParserName() << " & );" << endl();
		out << "    ValuePtr<" << myPimplName << "> myImplementation;" << endl();
		out << endl() << endl() << "};" << endl();
		out << endl() << nsEnd << endl() << endl();
		myCurLineNum += std::count_if( nsEnd.begin(), nsEnd.end(),
									   std::bind2nd( std::equal_to<char>(), '\n' ) );
		out << "#endif /* " << poundDef << " */ " << endl();
		out.close();
		isOk = true;
	}

	return isOk;
}
Exemple #6
0
void
ZDriver::writeErrorRoutines( std::ostream &out )
{
	const std::string &tokenType = getValue( "token_type" ).first;
	const std::string &extraArg = getValue( "extra_argument" ).first;

	emitFuncBreak( out );
	out << "void " << myPimplName << "::syntaxError( "
		<< getParserName()
		<< "::Terminal tok, const Util::Any &data"
		<< myExtraArg << " )" << endl();
	out << "{" << endl();
	const std::string &seStr = getValue( "syntax_error" ).first;

	if ( isDebugOutput() )
	{
		out << "    std::cout << \"SYNTAX ERROR with token \" << tok << std::endl;"
			<< endl();
	}

	if ( ! seStr.empty() )
	{
		if ( seStr.find( "TOKEN" ) != std::string::npos )
		{
			out << "    const ";
			if ( tokenType.empty() )
				out << "void *";
			else
			{
				out << tokenType;
				if ( *(tokenType.end() - 1) != '*' &&
					 *(tokenType.end() - 1) != '&' )
					out << " ";
			}
			out << "TOKEN = Util::any_cast< const ";
			if ( tokenType.empty() )
				out << "void *";
			else
				out << tokenType;
			out << " >( data );" << endl();
		}
		emitValue( getValue( "syntax_error" ), out );
	}
	else
		std::cout << "WARNING: missing syntax_error directive" << std::endl;

	out << "}" << endl();

	emitFuncBreak( out );
	out << "void " << myPimplName << "::parseFailed( ";
	if ( extraArg.empty() )
		out << "void";
	else
		out << extraArg;
	out << " )" << endl();
	out << "{" << endl();

	if ( isDebugOutput() )
	{
		out << "    std::cout << \"PARSE FAILURE\" << std::endl;"
			<< endl();
	}

	if (getValue( "parse_failure" ).first.empty())
		std::cout << "WARNING: missing parse_failure directive" << std::endl;

	emitValue( getValue( "parse_failure" ), out );
	out << "}" << endl();
}