[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


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/