[opengtl-commits] [753] Implement the parser |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/opengtl-commits Archives
]
Revision: 753
Author: cyrille
Date: 2009-05-30 11:45:18 +0200 (Sat, 30 May 2009)
Log Message:
-----------
Implement the parser
Modified Paths:
--------------
trunk/OpenGTL/OpenCTL/OpenCTL/templatecompiler/TemplateParser.cpp
trunk/OpenGTL/OpenCTL/OpenCTL/templatecompiler/TemplateParser_p.h
Modified: trunk/OpenGTL/OpenCTL/OpenCTL/templatecompiler/TemplateParser.cpp
===================================================================
--- trunk/OpenGTL/OpenCTL/OpenCTL/templatecompiler/TemplateParser.cpp 2009-05-30 09:45:06 UTC (rev 752)
+++ trunk/OpenGTL/OpenCTL/OpenCTL/templatecompiler/TemplateParser.cpp 2009-05-30 09:45:18 UTC (rev 753)
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 2009 Cyrille Berger <cberger@xxxxxxxxxxx>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "TemplateParser_p.h"
+
+#include <GTLCore/ErrorMessage.h>
+#include <GTLCore/Macros_p.h>
+
+#include "Debug.h"
+#include "TemplateLexer_p.h"
+
+using namespace OpenCTL;
+using namespace OpenCTL::TemplateAST;
+
+struct TemplateParser::Private {
+ TemplateLexer* m_lexer;
+ GTLCore::String m_fileName;
+ GTLCore::Token token;
+ std::list<GTLCore::ErrorMessage> errorMessages;
+};
+
+TemplateParser::TemplateParser( TemplateLexer* _lexer, const GTLCore::String& _fileName) : d(new Private)
+{
+ d->m_lexer = _lexer;
+ d->m_fileName = _fileName;
+}
+
+TemplateParser::~TemplateParser()
+{
+}
+
+TemplateAST::Node* TemplateParser::parse()
+{
+ using GTLCore::Token;
+ std::list<Node*> nodes;
+ getNextToken() ;
+ while( currentToken().type != GTLCore::Token::END_OF_FILE )
+ {
+ Node* node = 0;
+ switch(currentToken().type)
+ {
+ case Token::STRING_CONSTANT:
+ nodes.push_back( new TextNode(currentToken().string) );
+ break;
+ case Token::STARTBRACKET: // In the body, brackets are always considered as strings
+ nodes.push_back( new TextNode("(") );
+ break;
+ case Token::ENDBRACKET: // In the body, brackets are always considered as strings
+ nodes.push_back( new TextNode(")") );
+ break;
+ case Token::ALLCHANNELS:
+ nodes.push_back( parseAllChannels( AllChannelsNode::AllChannel ) );
+ break;
+ case Token::COLORCHANNELS:
+ nodes.push_back( parseAllChannels( AllChannelsNode::ColorChannel ) );
+ break;
+ case Token::ALPHACHANNEL:
+ nodes.push_back( parseAllChannels( AllChannelsNode::AlphaChannel ) );
+ break;
+ case Token::MAX:
+ nodes.push_back( new NamedMaxNode( parseName() ) );
+ break;
+ case Token::MIN:
+ nodes.push_back( new NamedMinNode( parseName() ) );
+ break;
+ case Token::UNIT:
+ nodes.push_back( new NamedUnitNode( parseName() ) );
+ break;
+ case Token::TYPE:
+ nodes.push_back( new NamedTypeNode( parseName() ) );
+ break;
+ default:
+ reportUnexpected(currentToken());
+ }
+ if( node != 0 )
+ {
+ nodes.push_back(node);
+ }
+ getNextToken();
+ }
+ if(d->errorMessages.size() == 0 )
+ {
+ return new NodesList(nodes);
+ } else {
+ foreach(Node* node, nodes)
+ {
+ delete node;
+ }
+ return 0;
+ }
+}
+
+void TemplateParser::getNextToken()
+{
+ d->token = d->m_lexer->nextToken();
+}
+
+const GTLCore::Token& TemplateParser::currentToken()
+{
+ return d->token;
+}
+
+void TemplateParser::reportError( const GTLCore::String& errMsg, const GTLCore::Token& token )
+{
+ GTL_DEBUG( errMsg );
+ d->errorMessages.push_back( GTLCore::ErrorMessage( errMsg, token.line, d->m_fileName ) );
+}
+
+void TemplateParser::reportUnexpected( const GTLCore::Token& token )
+{
+ reportError("Unexpected: " + GTLCore::Token::typeToString( token.type ), token );
+ getNextToken();
+}
+
+const std::list<GTLCore::ErrorMessage>& TemplateParser::errorMessages() const
+{
+ return d->errorMessages;
+}
+
+bool TemplateParser::isOfType( const GTLCore::Token& token, GTLCore::Token::Type type )
+{
+ if( token.type == type )
+ {
+ return true;
+ } else {
+ reportError("Expected " + GTLCore::Token::typeToString(type) + " before " + GTLCore::Token::typeToString(token.type) + ".", token);
+ return false;
+ }
+}
+
+TemplateAST::Node* TemplateParser::parseAllChannels( TemplateAST::AllChannelsNode::WhichChannel _whichChannel ) {
+ using GTLCore::Token;
+ std::list<Node*> nodes;
+ getNextToken(); // Remove the @allchannels or @colorchannels or @alphachannel
+
+ // Parse the list of commands
+ if(isOfType(currentToken(), Token::STARTBRACKET) ) {
+ int bracketCount = 1; // This is use to manage this kind of situation @allchannels( a * ( 1 + b) )
+ while(currentToken().type != Token::END_OF_FILE and bracketCount > 0) {
+ getNextToken();
+ switch(currentToken().type) {
+ case Token::STARTBRACKET:
+ nodes.push_back(new TextNode( "(" ));
+ ++bracketCount;
+ break;
+ case Token::ENDBRACKET:
+ {
+ if(bracketCount != 1 ) { // Don't add the bracket that correspond to the first one
+ nodes.push_back(new TextNode( ")" ));
+ }
+ --bracketCount;
+ }
+ break;
+ case Token::STRING_CONSTANT:
+ nodes.push_back(new TextNode( currentToken().string ));
+ break;
+ case Token::TYPE:
+ nodes.push_back(new ChannelTypeNode());
+ break;
+ case Token::MAX:
+ nodes.push_back(new ChannelMaxNode());
+ break;
+ case Token::MIN:
+ nodes.push_back(new ChannelMinNode());
+ break;
+ case Token::UNIT:
+ nodes.push_back(new ChannelUnitNode());
+ break;
+ case Token::VAR:
+ {
+ getNextToken();
+ nodes.push_back(new VarNode(parseName()));
+ break;
+ }
+ case Token::OUTPUT:
+ nodes.push_back(new InOutNode(OpenCTL::TemplateAST::InOutNode::Out));
+ break;
+ case Token::INPUT:
+ nodes.push_back(new InOutNode(OpenCTL::TemplateAST::InOutNode::In));
+ break;
+ default:
+ reportUnexpected(currentToken());
+ }
+ }
+ GTL_ASSERT(bracketCount >= 0);
+ isOfType(currentToken(), Token::ENDBRACKET);
+ }
+ return new AllChannelsNode( new NodesList(nodes), _whichChannel);
+}
+
+GTLCore::String TemplateParser::parseName() {
+ if(isOfType(currentToken(), GTLCore::Token::STARTBRACKET)) {
+ getNextToken(); // eat the '('
+ if(isOfType(currentToken(), GTLCore::Token::STRING_CONSTANT)) {
+ GTLCore::String string = currentToken().string;
+ getNextToken(); // eat the name
+ isOfType(currentToken(), GTLCore::Token::ENDBRACKET); // check that we end with ')'
+ return string;
+ }
+ }
+ return "";
+}
+
Modified: trunk/OpenGTL/OpenCTL/OpenCTL/templatecompiler/TemplateParser_p.h
===================================================================
--- trunk/OpenGTL/OpenCTL/OpenCTL/templatecompiler/TemplateParser_p.h 2009-05-30 09:45:06 UTC (rev 752)
+++ trunk/OpenGTL/OpenCTL/OpenCTL/templatecompiler/TemplateParser_p.h 2009-05-30 09:45:18 UTC (rev 753)
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2009 Cyrille Berger <cberger@xxxxxxxxxxx>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * either version 2, or (at your option) any later version of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _OPENCTL_TEMPLATE_PARSER_H_
+#define _OPENCTL_TEMPLATE_PARSER_H_
+
+#include "TemplateAST_p.h"
+
+#include <GTLCore/String.h>
+#include <GTLCore/Token_p.h>
+
+namespace GTLCore {
+ class ErrorMessage;
+ class Token;
+}
+
+namespace OpenCTL {
+ class TemplateLexer;
+ class TemplateParser {
+ public:
+ TemplateParser( TemplateLexer* _lexer, const GTLCore::String& _fileName);
+ ~TemplateParser();
+ TemplateAST::Node* parse();
+ const std::list<GTLCore::ErrorMessage>& errorMessages() const;
+ private:
+ TemplateAST::Node* parseAllChannels( TemplateAST::AllChannelsNode::WhichChannel _whichChannel );
+ /**
+ * parse something like "(myname)"
+ */
+ GTLCore::String parseName();
+ private:
+ void getNextToken();
+ const GTLCore::Token& currentToken();
+ void reportError( const GTLCore::String& errMsg, const GTLCore::Token& token );
+ void reportUnexpected( const GTLCore::Token& token );
+ bool isOfType( const GTLCore::Token& , GTLCore::Token::Type type );
+ private:
+ struct Private;
+ Private* const d;
+ };
+}
+
+#endif