// 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 ); } }
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"); } } }
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(); } }
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; }
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; }
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(); }