Update docs, formatting for Parser.

This commit is contained in:
Jesse Beder 2016-05-12 23:13:55 -05:00
parent 148da47114
commit 6c569e58b0
2 changed files with 65 additions and 26 deletions

View File

@ -20,23 +20,61 @@ class Scanner;
struct Directives;
struct Token;
/**
* A parser turns a stream of bytes into one stream of "events" per YAML
* document in the input stream.
*/
class YAML_CPP_API Parser : private noncopyable {
public:
/** Constructs an empty parser (with no input. */
Parser();
Parser(std::istream& in);
/**
* Constructs a parser from the given input stream. The input stream must
* live as long as the parser.
*/
explicit Parser(std::istream& in);
~Parser();
operator bool() const;
/** Evaluates to true if the parser has some valid input to be read. */
explicit operator bool() const;
/**
* Resets the parser with the given input stream. Any existing state is
* erased.
*/
void Load(std::istream& in);
/**
* Handles the next document by calling events on the {@param eventHandler}.
*
* @throw a ParserException on error.
* @return false if there are no more documents
*/
bool HandleNextDocument(EventHandler& eventHandler);
void PrintTokens(std::ostream& out);
private:
/**
* Reads any directives that are next in the queue, setting the internal
* {@code m_pDirectives} state.
*/
void ParseDirectives();
void HandleDirective(const Token& token);
/**
* Handles a "YAML" directive, which should be of the form 'major.minor' (like
* a version number).
*/
void HandleYamlDirective(const Token& token);
/**
* Handles a "TAG" directive, which should be of the form 'handle prefix',
* where 'handle' is converted to 'prefix' in the file.
*/
void HandleTagDirective(const Token& token);
private:

View File

@ -26,40 +26,38 @@ void Parser::Load(std::istream& in) {
m_pDirectives.reset(new Directives);
}
// HandleNextDocument
// . Handles the next document
// . Throws a ParserException on error.
// . Returns false if there are no more documents
bool Parser::HandleNextDocument(EventHandler& eventHandler) {
if (!m_pScanner.get())
return false;
ParseDirectives();
if (m_pScanner->empty())
if (m_pScanner->empty()) {
return false;
}
SingleDocParser sdp(*m_pScanner, *m_pDirectives);
sdp.HandleDocument(eventHandler);
return true;
}
// ParseDirectives
// . Reads any directives that are next in the queue.
void Parser::ParseDirectives() {
bool readDirective = false;
while (1) {
if (m_pScanner->empty())
if (m_pScanner->empty()) {
break;
}
Token& token = m_pScanner->peek();
if (token.type != Token::DIRECTIVE)
if (token.type != Token::DIRECTIVE) {
break;
}
// we keep the directives from the last document if none are specified;
// but if any directives are specific, then we reset them
if (!readDirective)
if (!readDirective) {
m_pDirectives.reset(new Directives);
}
readDirective = true;
HandleDirective(token);
@ -68,58 +66,61 @@ void Parser::ParseDirectives() {
}
void Parser::HandleDirective(const Token& token) {
if (token.value == "YAML")
if (token.value == "YAML") {
HandleYamlDirective(token);
else if (token.value == "TAG")
} else if (token.value == "TAG") {
HandleTagDirective(token);
}
}
// HandleYamlDirective
// . Should be of the form 'major.minor' (like a version number)
void Parser::HandleYamlDirective(const Token& token) {
if (token.params.size() != 1)
if (token.params.size() != 1) {
throw ParserException(token.mark, ErrorMsg::YAML_DIRECTIVE_ARGS);
}
if (!m_pDirectives->version.isDefault)
if (!m_pDirectives->version.isDefault) {
throw ParserException(token.mark, ErrorMsg::REPEATED_YAML_DIRECTIVE);
}
std::stringstream str(token.params[0]);
str >> m_pDirectives->version.major;
str.get();
str >> m_pDirectives->version.minor;
if (!str || str.peek() != EOF)
if (!str || str.peek() != EOF) {
throw ParserException(
token.mark, std::string(ErrorMsg::YAML_VERSION) + token.params[0]);
}
if (m_pDirectives->version.major > 1)
if (m_pDirectives->version.major > 1) {
throw ParserException(token.mark, ErrorMsg::YAML_MAJOR_VERSION);
}
m_pDirectives->version.isDefault = false;
// TODO: warning on major == 1, minor > 2?
}
// HandleTagDirective
// . Should be of the form 'handle prefix', where 'handle' is converted to
// 'prefix' in the file.
void Parser::HandleTagDirective(const Token& token) {
if (token.params.size() != 2)
throw ParserException(token.mark, ErrorMsg::TAG_DIRECTIVE_ARGS);
const std::string& handle = token.params[0];
const std::string& prefix = token.params[1];
if (m_pDirectives->tags.find(handle) != m_pDirectives->tags.end())
if (m_pDirectives->tags.find(handle) != m_pDirectives->tags.end()) {
throw ParserException(token.mark, ErrorMsg::REPEATED_TAG_DIRECTIVE);
}
m_pDirectives->tags[handle] = prefix;
}
void Parser::PrintTokens(std::ostream& out) {
if (!m_pScanner.get())
if (!m_pScanner.get()) {
return;
}
while (1) {
if (m_pScanner->empty())
if (m_pScanner->empty()) {
break;
}
out << m_pScanner->peek() << "\n";
m_pScanner->pop();