bool nectar_loader:: next_token ( string& token,
const set< char > & special_characters)
{
// TODO: test the *full* hell out of this function
// FIXME: ugly as hell, alternatives welcome.
token.clear ( ) ;
bool inside_quotes = false ;
char c;
auto add_char = [ & ]
{
token.append ( 1 , c) ;
} ;
while ( m_stream.get ( c) )
{
debug( debug:: lexer ) << "nectar_loader::next_token::line number " << m_line_number << ", character: \' " << output_form( c) << "\' , token so far: "
<< output_form( token) << "\n " ;
if ( inside_quotes)
{
debug( debug:: lexer ) << "nectar_loader::next_token::Inside quotes.\n " ;
if ( '\" ' == c)
{
break ; // end of token at end of quotes
}
else if ( '\n ' == c)
{
throw syntax_error( "Quoted strings cannot span several lines." , m_filename, m_line_number) ;
}
else if ( token.empty ( ) && std:: isspace ( c, m_stream.getloc ( ) ) )
{
throw syntax_error( "Beginning quote must not be followed by a whitespace." , m_filename, m_line_number) ;
}
else
{
add_char( ) ;
}
}
else
{
if ( token.empty ( ) )
{
if ( '\n ' == c)
{
++ m_line_number;
}
if ( contains( special_characters, c) )
{
// special characters are tokens of their own
debug( debug:: lexer ) << "nectar_loader::next_token::Detected special character.\n " ;
token.append ( 1 , c) ;
return true ;
}
else if ( '\" ' == c)
{
debug( debug:: lexer ) << "nectar_loader::next_token::Quote detected.\n " ;
inside_quotes = true ;
continue ;
}
else if ( std:: isspace ( c, m_stream.getloc ( ) ) )
{
continue ;
}
else if ( '#' == c)
{
// skip over comments
debug( debug:: lexer ) << "nectar_loader::next_token::Skipping over comments.\n " ;
string temp;
std:: getline ( m_stream, temp) ;
m_stream.putback ( '\n ' ) ;
}
else if ( '\\ ' == c)
{
string temp;
std:: getline ( m_stream, temp) ;
++ m_line_number;
}
else
{
add_char( ) ;
}
}
else if ( std:: isspace ( c, m_stream.getloc ( ) ) || contains( special_characters, c) )
{
// special characters or whitespace seperate tokens
debug( debug:: lexer ) << "nectar_loader::next_token::Detected special character or space.\n " ;
m_stream.putback ( c) ;
break ;
}
else if ( '\" ' == c)
{
throw syntax_error( "Beginning quotes must be preceded by a whitespace or a special character." , m_filename, m_line_number) ;
return false ;
}
else
{
add_char( ) ;
}
}
}
if ( ! token.empty ( ) )
{
debug( debug:: lexer ) << "nectar_loader::next_token:Token extracted: \' " << output_form( token) << "\' \n " ;
}
return ! token.empty ( ) ;
}
Ym9vbCBuZWN0YXJfbG9hZGVyOjpuZXh0X3Rva2VuKHN0cmluZyYgdG9rZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzZXQ8Y2hhcj4mIHNwZWNpYWxfY2hhcmFjdGVycykKewogICAgLy8gVE9ETzogdGVzdCB0aGUgKmZ1bGwqIGhlbGwgb3V0IG9mIHRoaXMgZnVuY3Rpb24KICAgIC8vIEZJWE1FOiB1Z2x5IGFzIGhlbGwsIGFsdGVybmF0aXZlcyB3ZWxjb21lLgogICAgdG9rZW4uY2xlYXIoKTsKICAgIGJvb2wgaW5zaWRlX3F1b3RlcyA9IGZhbHNlOwogICAgY2hhciBjOwogICAgYXV0byBhZGRfY2hhciA9IFsmXQogICAgewogICAgICAgIHRva2VuLmFwcGVuZCgxLCBjKTsKICAgIH07CiAgICB3aGlsZShtX3N0cmVhbS5nZXQoYykpCiAgICB7CiAgICAgICAgZGVidWcoZGVidWc6OmxleGVyKSA8PCAibmVjdGFyX2xvYWRlcjo6bmV4dF90b2tlbjo6bGluZSBudW1iZXIgIiA8PCBtX2xpbmVfbnVtYmVyIDw8ICIsIGNoYXJhY3RlcjogXCciIDw8IG91dHB1dF9mb3JtKGMpIDw8ICJcJywgdG9rZW4gc28gZmFyOiAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8PCBvdXRwdXRfZm9ybSh0b2tlbikgPDwgIlxuIjsKICAgICAgICBpZihpbnNpZGVfcXVvdGVzKQogICAgICAgIHsKICAgICAgICAgICAgZGVidWcoZGVidWc6OmxleGVyKSA8PCAibmVjdGFyX2xvYWRlcjo6bmV4dF90b2tlbjo6SW5zaWRlIHF1b3Rlcy5cbiI7CiAgICAgICAgICAgIGlmKCdcIicgPT0gYykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgYnJlYWs7ICAgIC8vIGVuZCBvZiB0b2tlbiBhdCBlbmQgb2YgcXVvdGVzCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZignXG4nID09IGMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IHN5bnRheF9lcnJvcigiUXVvdGVkIHN0cmluZ3MgY2Fubm90IHNwYW4gc2V2ZXJhbCBsaW5lcy4iLCBtX2ZpbGVuYW1lLCBtX2xpbmVfbnVtYmVyKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmKHRva2VuLmVtcHR5KCkgJiYgc3RkOjppc3NwYWNlKGMsIG1fc3RyZWFtLmdldGxvYygpKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgdGhyb3cgc3ludGF4X2Vycm9yKCJCZWdpbm5pbmcgcXVvdGUgbXVzdCBub3QgYmUgZm9sbG93ZWQgYnkgYSB3aGl0ZXNwYWNlLiIsIG1fZmlsZW5hbWUsIG1fbGluZV9udW1iZXIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgYWRkX2NoYXIoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBpZih0b2tlbi5lbXB0eSgpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZignXG4nID09IGMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgKyttX2xpbmVfbnVtYmVyOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmKGNvbnRhaW5zKHNwZWNpYWxfY2hhcmFjdGVycywgYykpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLy8gc3BlY2lhbCBjaGFyYWN0ZXJzIGFyZSB0b2tlbnMgb2YgdGhlaXIgb3duCiAgICAgICAgICAgICAgICAgICAgZGVidWcoZGVidWc6OmxleGVyKSA8PCAibmVjdGFyX2xvYWRlcjo6bmV4dF90b2tlbjo6RGV0ZWN0ZWQgc3BlY2lhbCBjaGFyYWN0ZXIuXG4iOwogICAgICAgICAgICAgICAgICAgIHRva2VuLmFwcGVuZCgxLCBjKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYoJ1wiJyA9PSBjKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGRlYnVnKGRlYnVnOjpsZXhlcikgPDwgIm5lY3Rhcl9sb2FkZXI6Om5leHRfdG9rZW46OlF1b3RlIGRldGVjdGVkLlxuIjsKICAgICAgICAgICAgICAgICAgICBpbnNpZGVfcXVvdGVzID0gdHJ1ZTsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYoc3RkOjppc3NwYWNlKGMsIG1fc3RyZWFtLmdldGxvYygpKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYoJyMnID09IGMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLy8gc2tpcCBvdmVyIGNvbW1lbnRzCiAgICAgICAgICAgICAgICAgICAgZGVidWcoZGVidWc6OmxleGVyKSA8PCAibmVjdGFyX2xvYWRlcjo6bmV4dF90b2tlbjo6U2tpcHBpbmcgb3ZlciBjb21tZW50cy5cbiI7CiAgICAgICAgICAgICAgICAgICAgc3RyaW5nIHRlbXA7CiAgICAgICAgICAgICAgICAgICAgc3RkOjpnZXRsaW5lKG1fc3RyZWFtLCB0ZW1wKTsKICAgICAgICAgICAgICAgICAgICBtX3N0cmVhbS5wdXRiYWNrKCdcbicpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZignXFwnID09IGMpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgc3RyaW5nIHRlbXA7CiAgICAgICAgICAgICAgICAgICAgc3RkOjpnZXRsaW5lKG1fc3RyZWFtLCB0ZW1wKTsKICAgICAgICAgICAgICAgICAgICArK21fbGluZV9udW1iZXI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgYWRkX2NoYXIoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmKHN0ZDo6aXNzcGFjZShjLCBtX3N0cmVhbS5nZXRsb2MoKSkgfHwgY29udGFpbnMoc3BlY2lhbF9jaGFyYWN0ZXJzLCBjKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gc3BlY2lhbCBjaGFyYWN0ZXJzIG9yIHdoaXRlc3BhY2Ugc2VwZXJhdGUgdG9rZW5zCiAgICAgICAgICAgICAgICBkZWJ1ZyhkZWJ1Zzo6bGV4ZXIpIDw8ICJuZWN0YXJfbG9hZGVyOjpuZXh0X3Rva2VuOjpEZXRlY3RlZCBzcGVjaWFsIGNoYXJhY3RlciBvciBzcGFjZS5cbiI7CiAgICAgICAgICAgICAgICBtX3N0cmVhbS5wdXRiYWNrKGMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZignXCInID09IGMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHRocm93IHN5bnRheF9lcnJvcigiQmVnaW5uaW5nIHF1b3RlcyBtdXN0IGJlIHByZWNlZGVkIGJ5IGEgd2hpdGVzcGFjZSBvciBhIHNwZWNpYWwgY2hhcmFjdGVyLiIsIG1fZmlsZW5hbWUsIG1fbGluZV9udW1iZXIpOwogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgYWRkX2NoYXIoKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIGlmKCF0b2tlbi5lbXB0eSgpKQogICAgewogICAgICAgIGRlYnVnKGRlYnVnOjpsZXhlcikgPDwgIm5lY3Rhcl9sb2FkZXI6Om5leHRfdG9rZW46VG9rZW4gZXh0cmFjdGVkOiBcJyIgPDwgb3V0cHV0X2Zvcm0odG9rZW4pIDw8ICJcJ1xuIjsKICAgIH0KCiAgICByZXR1cm4gIXRva2VuLmVtcHR5KCk7Cn0K
compilation info
prog.cpp:1: error: ‘nectar_loader’ has not been declared
prog.cpp:1: error: ‘string’ was not declared in this scope
prog.cpp:1: error: ‘token’ was not declared in this scope
prog.cpp:2: error: expected primary-expression before ‘const’
prog.cpp:2: error: initializer expression list treated as compound expression
prog.cpp:3: error: expected ‘,’ or ‘;’ before ‘{’ token
stdout