ConfBlock& ConfParser::parse( string configFileName ) throw( BadSyntax ) { // Open configuration file ifstream configFile( configFileName.c_str(), ios::out ); if ( !configFile ) throw BadSyntax( configFileName, 0, "Specified configuration file does not exist" ); #ifdef DEBUG cout << "Parsing configuration file " << configFileName << endl; #endif parse_rec( &outermost_, 0, 0, configFile, configFileName ); return outermost_; }
decision_proceduret::resultt smt2_dect::read_result(std::istream &in) { std::string line; decision_proceduret::resultt res=resultt::D_ERROR; boolean_assignment.clear(); boolean_assignment.resize(no_boolean_variables, false); typedef std::unordered_map<irep_idt, irept, irep_id_hash> valuest; valuest values; while(in) { irept parsed=smt2irep(in); if(parsed.id()=="sat") res=resultt::D_SATISFIABLE; else if(parsed.id()=="unsat") res=resultt::D_UNSATISFIABLE; else if(parsed.id()=="" && parsed.get_sub().size()==1 && parsed.get_sub().front().get_sub().size()==2) { const irept &s0=parsed.get_sub().front().get_sub()[0]; const irept &s1=parsed.get_sub().front().get_sub()[1]; // Examples: // ( (B0 true) ) // ( (|__CPROVER_pipe_count#1| (_ bv0 32)) ) values[s0.id()]=s1; } else if(parsed.id()=="" && parsed.get_sub().size()==2 && parsed.get_sub().front().id()=="error") { // We ignore errors after UNSAT because get-value after check-sat // returns unsat will give an error. if(res!=resultt::D_UNSATISFIABLE) { error() << "SMT2 solver returned error message:\n" << "\t\"" << parsed.get_sub()[1].id() <<"\"" << eom; return decision_proceduret::resultt::D_ERROR; } } } for(identifier_mapt::iterator it=identifier_map.begin(); it!=identifier_map.end(); it++) { std::string conv_id=convert_identifier(it->first); const irept &value=values[conv_id]; it->second.value=parse_rec(value, it->second.type); } // Booleans for(unsigned v=0; v<no_boolean_variables; v++) { const irept &value=values["B"+std::to_string(v)]; boolean_assignment[v]=(value.id()==ID_true); } return res; }
int ConfParser::parse_rec( ConfBlock* currBlock, int level, int nLine, ifstream& configFile, const string& configFileName ) { // Read in config file linewise string l; while ( getline( configFile, l ) ) { ++nLine; // Remove leading and trailing whitespace trim( l ); // If the line contained only whitspace we can skip it if ( l.empty() ) continue; // Ignore lines beginning with # or // as comments if ( starts_with( l, "#") || starts_with( l, "//" ) ) continue; // Check whether it is the end of a block if ( l.length() == 1 && l[0] == '}' ) { // Syntax error if we are at level 0 if ( level == 0 ) { throw BadSyntax( configFileName, nLine, "Found closing block at outermost level" ); } return nLine; } cmatch m; regex blockBegin( "^(\\w+)\\s*\\{$" ); regex keyVal( "^(\\w+)\\s+(.*);" ); // Check whether it is the beginning of a new block if ( regex_match( l.c_str(), m, blockBegin ) ) { #ifdef DEBUG cout << "Adding Block " << m[1] << " at level " << level << " (line " << nLine << ")" << endl; #endif nLine = parse_rec( &currBlock->addChild( m[1] ), level + 1, nLine, configFile, configFileName ); // Check whether it is a key / value pair } else if ( regex_match( l.c_str(), m, keyVal ) ) { currBlock->addParam( m[1], m[2] ); // Else we have a malformed expression and throw an exception } else { throw BadSyntax( configFileName, nLine, "Malformed expression" ); } } // check if we are at outermost level again at the end if ( level != 0 ) throw BadSyntax( configFileName, nLine, "Unexpected end of configuration file" ); return nLine; }