// Read until the end_str is found, store all characters (not including end_str) in m_buffer. // Throw a parser exception error_msg if end of file is found before end_str. void scanner::read_until(char const * end_str, char const * error_msg) { lean_assert(end_str); lean_assert(end_str[0]); m_buffer.clear(); while (true) { check_not_eof(error_msg); char c = curr_next(); if (c == end_str[0]) { m_aux_buffer.clear(); m_aux_buffer += c; unsigned i = 1; while (true) { if (!end_str[i]) return; check_not_eof(error_msg); c = curr_next(); if (c != end_str[i]) { m_buffer += m_aux_buffer; break; } i++; } } else { m_buffer += c; } } }
void scanner::read_doc_block_core() { m_buffer.clear(); while (true) { check_not_eof("unexpected end of documentation block"); char c = curr(); next(); if (c == '-') { if (curr() == '/') { next(); return; } } m_buffer += c; } }
void scanner::read_comment_block() { unsigned nesting = 1; while (true) { char c = curr(); check_not_eof("unexpected end of comment block"); next(); if (c == '/') { if (curr() == '-') { next(); nesting++; } } else if (c == '-') { if (curr() == '/') { next(); nesting--; if (nesting == 0) return; } } } }
char scanner::read_quoted_char(char const * error_msg) { lean_assert(curr() == '\\'); next(); check_not_eof(error_msg); char c = curr(); if (c != '\\' && c != '\"' && c != 'n' && c != '\'' && c != 'x') throw_exception("invalid escape sequence"); if (c == 'n') { return '\n'; } else if (c == 'x') { next(); char c = curr(); unsigned v = hex_to_unsigned(c); next(); c = curr(); v = 16*v + hex_to_unsigned(c); return static_cast<char>(v); } else { return c; } }