fork download
  1. bool nectar_loader::next_token(string& token,
  2. const set<char>& special_characters)
  3. {
  4. // TODO: test the *full* hell out of this function
  5. // FIXME: ugly as hell, alternatives welcome.
  6. token.clear();
  7. bool inside_quotes = false;
  8. char c;
  9. auto add_char = [&]
  10. {
  11. token.append(1, c);
  12. };
  13. while(m_stream.get(c))
  14. {
  15. debug(debug::lexer) << "nectar_loader::next_token::line number " << m_line_number << ", character: \'" << output_form(c) << "\', token so far: "
  16. << output_form(token) << "\n";
  17. if(inside_quotes)
  18. {
  19. debug(debug::lexer) << "nectar_loader::next_token::Inside quotes.\n";
  20. if('\"' == c)
  21. {
  22. break; // end of token at end of quotes
  23. }
  24. else if('\n' == c)
  25. {
  26. throw syntax_error("Quoted strings cannot span several lines.", m_filename, m_line_number);
  27. }
  28. else if(token.empty() && std::isspace(c, m_stream.getloc()))
  29. {
  30. throw syntax_error("Beginning quote must not be followed by a whitespace.", m_filename, m_line_number);
  31. }
  32. else
  33. {
  34. add_char();
  35. }
  36. }
  37. else
  38. {
  39. if(token.empty())
  40. {
  41. if('\n' == c)
  42. {
  43. ++m_line_number;
  44. }
  45.  
  46. if(contains(special_characters, c))
  47. {
  48. // special characters are tokens of their own
  49. debug(debug::lexer) << "nectar_loader::next_token::Detected special character.\n";
  50. token.append(1, c);
  51. return true;
  52. }
  53. else if('\"' == c)
  54. {
  55. debug(debug::lexer) << "nectar_loader::next_token::Quote detected.\n";
  56. inside_quotes = true;
  57. continue;
  58. }
  59. else if(std::isspace(c, m_stream.getloc()))
  60. {
  61. continue;
  62. }
  63. else if('#' == c)
  64. {
  65. // skip over comments
  66. debug(debug::lexer) << "nectar_loader::next_token::Skipping over comments.\n";
  67. string temp;
  68. std::getline(m_stream, temp);
  69. m_stream.putback('\n');
  70. }
  71. else if('\\' == c)
  72. {
  73. string temp;
  74. std::getline(m_stream, temp);
  75. ++m_line_number;
  76. }
  77. else
  78. {
  79. add_char();
  80. }
  81. }
  82. else if(std::isspace(c, m_stream.getloc()) || contains(special_characters, c))
  83. {
  84. // special characters or whitespace seperate tokens
  85. debug(debug::lexer) << "nectar_loader::next_token::Detected special character or space.\n";
  86. m_stream.putback(c);
  87. break;
  88. }
  89. else if('\"' == c)
  90. {
  91. throw syntax_error("Beginning quotes must be preceded by a whitespace or a special character.", m_filename, m_line_number);
  92. return false;
  93. }
  94. else
  95. {
  96. add_char();
  97. }
  98. }
  99. }
  100. if(!token.empty())
  101. {
  102. debug(debug::lexer) << "nectar_loader::next_token:Token extracted: \'" << output_form(token) << "\'\n";
  103. }
  104.  
  105. return !token.empty();
  106. }
  107.  
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
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
Standard output is empty