parser.cpp
Go to the documentation of this file.
00001 #include "yaml-cpp-pm/parser.h"
00002 #include "yaml-cpp-pm/eventhandler.h"
00003 #include "yaml-cpp-pm/exceptions.h"
00004 #include "yaml-cpp-pm/node.h"
00005 #include "directives.h"
00006 #include "nodebuilder.h"
00007 #include "scanner.h"
00008 #include "singledocparser.h"
00009 #include "tag.h"
00010 #include "token.h"
00011 #include <sstream>
00012 #include <cstdio>
00013 
00014 namespace YAML_PM
00015 {
00016         Parser::Parser()
00017         {
00018         }
00019         
00020         Parser::Parser(std::istream& in)
00021         {
00022                 Load(in);
00023         }
00024 
00025         Parser::~Parser()
00026         {
00027         }
00028 
00029         Parser::operator bool() const
00030         {
00031                 return m_pScanner.get() && !m_pScanner->empty();
00032         }
00033 
00034         void Parser::Load(std::istream& in)
00035         {
00036                 m_pScanner.reset(new Scanner(in));
00037                 m_pDirectives.reset(new Directives);
00038         }
00039 
00040         // HandleNextDocument
00041         // . Handles the next document
00042         // . Throws a ParserException on error.
00043         // . Returns false if there are no more documents
00044         bool Parser::HandleNextDocument(EventHandler& eventHandler)
00045         {
00046                 if(!m_pScanner.get())
00047                         return false;
00048 
00049                 ParseDirectives();
00050                 if(m_pScanner->empty())
00051                         return false;
00052                 
00053                 SingleDocParser sdp(*m_pScanner, *m_pDirectives);
00054                 sdp.HandleDocument(eventHandler);
00055                 return true;
00056         }
00057 
00058         // GetNextDocument
00059         // . Reads the next document in the queue (of tokens).
00060         // . Throws a ParserException on error.
00061         bool Parser::GetNextDocument(Node& document)
00062         {
00063                 NodeBuilder builder(document);
00064                 return HandleNextDocument(builder);
00065         }
00066 
00067         // ParseDirectives
00068         // . Reads any directives that are next in the queue.
00069         void Parser::ParseDirectives()
00070         {
00071                 bool readDirective = false;
00072 
00073                 while(1) {
00074                         if(m_pScanner->empty())
00075                                 break;
00076 
00077                         Token& token = m_pScanner->peek();
00078                         if(token.type != Token::DIRECTIVE)
00079                                 break;
00080 
00081                         // we keep the directives from the last document if none are specified;
00082                         // but if any directives are specific, then we reset them
00083                         if(!readDirective)
00084                                 m_pDirectives.reset(new Directives);
00085 
00086                         readDirective = true;
00087                         HandleDirective(token);
00088                         m_pScanner->pop();
00089                 }
00090         }
00091 
00092         void Parser::HandleDirective(const Token& token)
00093         {
00094                 if(token.value == "YAML")
00095                         HandleYamlDirective(token);
00096                 else if(token.value == "TAG")
00097                         HandleTagDirective(token);
00098         }
00099 
00100         // HandleYamlDirective
00101         // . Should be of the form 'major.minor' (like a version number)
00102         void Parser::HandleYamlDirective(const Token& token)
00103         {
00104                 if(token.params.size() != 1)
00105                         throw ParserException(token.mark, ErrorMsg::YAML_DIRECTIVE_ARGS);
00106                 
00107                 if(!m_pDirectives->version.isDefault)
00108                         throw ParserException(token.mark, ErrorMsg::REPEATED_YAML_DIRECTIVE);
00109 
00110                 std::stringstream str(token.params[0]);
00111                 str >> m_pDirectives->version.major;
00112                 str.get();
00113                 str >> m_pDirectives->version.minor;
00114                 if(!str || str.peek() != EOF)
00115                         throw ParserException(token.mark, std::string(ErrorMsg::YAML_VERSION) + token.params[0]);
00116 
00117                 if(m_pDirectives->version.major > 1)
00118                         throw ParserException(token.mark, ErrorMsg::YAML_MAJOR_VERSION);
00119 
00120                 m_pDirectives->version.isDefault = false;
00121                 // TODO: warning on major == 1, minor > 2?
00122         }
00123 
00124         // HandleTagDirective
00125         // . Should be of the form 'handle prefix', where 'handle' is converted to 'prefix' in the file.
00126         void Parser::HandleTagDirective(const Token& token)
00127         {
00128                 if(token.params.size() != 2)
00129                         throw ParserException(token.mark, ErrorMsg::TAG_DIRECTIVE_ARGS);
00130 
00131                 const std::string& handle = token.params[0];
00132                 const std::string& prefix = token.params[1];
00133                 if(m_pDirectives->tags.find(handle) != m_pDirectives->tags.end())
00134                         throw ParserException(token.mark, ErrorMsg::REPEATED_TAG_DIRECTIVE);
00135                 
00136                 m_pDirectives->tags[handle] = prefix;
00137         }
00138 
00139         void Parser::PrintTokens(std::ostream& out)
00140         {
00141                 if(!m_pScanner.get())
00142                         return;
00143                 
00144                 while(1) {
00145                         if(m_pScanner->empty())
00146                                 break;
00147 
00148                         out << m_pScanner->peek() << "\n";
00149                         m_pScanner->pop();
00150                 }
00151         }
00152 }


libpointmatcher
Author(s):
autogenerated on Thu Jun 20 2019 19:51:32