mirror of
https://github.com/jbeder/yaml-cpp.git
synced 2025-09-09 12:41:17 +00:00
Update docs, formatting for Parser.
This commit is contained in:
@@ -20,23 +20,61 @@ class Scanner;
|
|||||||
struct Directives;
|
struct Directives;
|
||||||
struct Token;
|
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 {
|
class YAML_CPP_API Parser : private noncopyable {
|
||||||
public:
|
public:
|
||||||
|
/** Constructs an empty parser (with no input. */
|
||||||
Parser();
|
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();
|
~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);
|
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);
|
bool HandleNextDocument(EventHandler& eventHandler);
|
||||||
|
|
||||||
void PrintTokens(std::ostream& out);
|
void PrintTokens(std::ostream& out);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/**
|
||||||
|
* Reads any directives that are next in the queue, setting the internal
|
||||||
|
* {@code m_pDirectives} state.
|
||||||
|
*/
|
||||||
void ParseDirectives();
|
void ParseDirectives();
|
||||||
|
|
||||||
void HandleDirective(const Token& token);
|
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);
|
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);
|
void HandleTagDirective(const Token& token);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@@ -26,40 +26,38 @@ void Parser::Load(std::istream& in) {
|
|||||||
m_pDirectives.reset(new Directives);
|
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) {
|
bool Parser::HandleNextDocument(EventHandler& eventHandler) {
|
||||||
if (!m_pScanner.get())
|
if (!m_pScanner.get())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ParseDirectives();
|
ParseDirectives();
|
||||||
if (m_pScanner->empty())
|
if (m_pScanner->empty()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
SingleDocParser sdp(*m_pScanner, *m_pDirectives);
|
SingleDocParser sdp(*m_pScanner, *m_pDirectives);
|
||||||
sdp.HandleDocument(eventHandler);
|
sdp.HandleDocument(eventHandler);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseDirectives
|
|
||||||
// . Reads any directives that are next in the queue.
|
|
||||||
void Parser::ParseDirectives() {
|
void Parser::ParseDirectives() {
|
||||||
bool readDirective = false;
|
bool readDirective = false;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (m_pScanner->empty())
|
if (m_pScanner->empty()) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
Token& token = m_pScanner->peek();
|
Token& token = m_pScanner->peek();
|
||||||
if (token.type != Token::DIRECTIVE)
|
if (token.type != Token::DIRECTIVE) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// we keep the directives from the last document if none are specified;
|
// we keep the directives from the last document if none are specified;
|
||||||
// but if any directives are specific, then we reset them
|
// but if any directives are specific, then we reset them
|
||||||
if (!readDirective)
|
if (!readDirective) {
|
||||||
m_pDirectives.reset(new Directives);
|
m_pDirectives.reset(new Directives);
|
||||||
|
}
|
||||||
|
|
||||||
readDirective = true;
|
readDirective = true;
|
||||||
HandleDirective(token);
|
HandleDirective(token);
|
||||||
@@ -68,58 +66,61 @@ void Parser::ParseDirectives() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Parser::HandleDirective(const Token& token) {
|
void Parser::HandleDirective(const Token& token) {
|
||||||
if (token.value == "YAML")
|
if (token.value == "YAML") {
|
||||||
HandleYamlDirective(token);
|
HandleYamlDirective(token);
|
||||||
else if (token.value == "TAG")
|
} else if (token.value == "TAG") {
|
||||||
HandleTagDirective(token);
|
HandleTagDirective(token);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// HandleYamlDirective
|
|
||||||
// . Should be of the form 'major.minor' (like a version number)
|
|
||||||
void Parser::HandleYamlDirective(const Token& token) {
|
void Parser::HandleYamlDirective(const Token& token) {
|
||||||
if (token.params.size() != 1)
|
if (token.params.size() != 1) {
|
||||||
throw ParserException(token.mark, ErrorMsg::YAML_DIRECTIVE_ARGS);
|
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);
|
throw ParserException(token.mark, ErrorMsg::REPEATED_YAML_DIRECTIVE);
|
||||||
|
}
|
||||||
|
|
||||||
std::stringstream str(token.params[0]);
|
std::stringstream str(token.params[0]);
|
||||||
str >> m_pDirectives->version.major;
|
str >> m_pDirectives->version.major;
|
||||||
str.get();
|
str.get();
|
||||||
str >> m_pDirectives->version.minor;
|
str >> m_pDirectives->version.minor;
|
||||||
if (!str || str.peek() != EOF)
|
if (!str || str.peek() != EOF) {
|
||||||
throw ParserException(
|
throw ParserException(
|
||||||
token.mark, std::string(ErrorMsg::YAML_VERSION) + token.params[0]);
|
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);
|
throw ParserException(token.mark, ErrorMsg::YAML_MAJOR_VERSION);
|
||||||
|
}
|
||||||
|
|
||||||
m_pDirectives->version.isDefault = false;
|
m_pDirectives->version.isDefault = false;
|
||||||
// TODO: warning on major == 1, minor > 2?
|
// 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) {
|
void Parser::HandleTagDirective(const Token& token) {
|
||||||
if (token.params.size() != 2)
|
if (token.params.size() != 2)
|
||||||
throw ParserException(token.mark, ErrorMsg::TAG_DIRECTIVE_ARGS);
|
throw ParserException(token.mark, ErrorMsg::TAG_DIRECTIVE_ARGS);
|
||||||
|
|
||||||
const std::string& handle = token.params[0];
|
const std::string& handle = token.params[0];
|
||||||
const std::string& prefix = token.params[1];
|
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);
|
throw ParserException(token.mark, ErrorMsg::REPEATED_TAG_DIRECTIVE);
|
||||||
|
}
|
||||||
|
|
||||||
m_pDirectives->tags[handle] = prefix;
|
m_pDirectives->tags[handle] = prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::PrintTokens(std::ostream& out) {
|
void Parser::PrintTokens(std::ostream& out) {
|
||||||
if (!m_pScanner.get())
|
if (!m_pScanner.get()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (m_pScanner->empty())
|
if (m_pScanner->empty()) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
out << m_pScanner->peek() << "\n";
|
out << m_pScanner->peek() << "\n";
|
||||||
m_pScanner->pop();
|
m_pScanner->pop();
|
||||||
|
Reference in New Issue
Block a user