[QGIS Commit] r14443 - trunk/qgis/src/analysis/raster

svn_qgis at osgeo.org svn_qgis at osgeo.org
Thu Oct 28 02:50:05 EDT 2010


Author: mhugent
Date: 2010-10-27 23:50:05 -0700 (Wed, 27 Oct 2010)
New Revision: 14443

Added:
   trunk/qgis/src/analysis/raster/qgsrastercalcparser.yy
Log:
Also add rastercalc bison file to svn

Added: trunk/qgis/src/analysis/raster/qgsrastercalcparser.yy
===================================================================
--- trunk/qgis/src/analysis/raster/qgsrastercalcparser.yy	                        (rev 0)
+++ trunk/qgis/src/analysis/raster/qgsrastercalcparser.yy	2010-10-28 06:50:05 UTC (rev 14443)
@@ -0,0 +1,137 @@
+/***************************************************************************
+                          qgsrastercalcparser.yy
+             Bison file for raster calculation parser
+                          --------------------
+    begin                : 2010-10-25
+    copyright            : (C) 2010 by Marco Hugentobler
+    email                : marco dot hugentobler at sourcepole dot ch
+***************************************************************************/
+
+/***************************************************************************
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ ***************************************************************************/
+
+%{
+  #include "qgsrastercalcnode.h"
+
+  // don't redeclare malloc/free
+  #define YYINCLUDED_STDLIB_H 1
+
+  QgsRasterCalcNode* parseRasterCalcString(const QString& str, QString& parserErrorMsg);
+
+  //! from lex.yy.c
+  extern int rasterlex();
+  extern char* rastertext;
+  extern void set_raster_input_buffer(const char* buffer);
+
+  //! varible where the parser error will be stored
+  QString rParserErrorMsg;
+
+  //! sets gParserErrorMsg
+  void rastererror(const char* msg);
+
+  //! temporary list for nodes without parent (if parsing fails these nodes are removed)
+  QList<QgsRasterCalcNode*> gTmpNodes;
+  void joinTmpNodes(QgsRasterCalcNode* parent, QgsRasterCalcNode* left, QgsRasterCalcNode* right);
+  void addToTmpNodes(QgsRasterCalcNode* node);
+
+  // we want verbose error messages
+  #define YYERROR_VERBOSE 1
+%}
+
+%union { QgsRasterCalcNode* node; double number; QgsRasterCalcNode::Operator op;}
+
+%start root
+
+%token RASTER_BAND_REF
+%token<number> NUMBER
+%token<op> FUNCTION
+
+%type <node> root
+%type <node> raster_exp
+
+%left '+' '-'
+%left '*' '/'
+%left '^'
+
+%%
+
+root: raster_exp{}
+;
+
+raster_exp:
+  FUNCTION '(' raster_exp ')'   { $$ = new QgsRasterCalcNode($1, $3, 0); joinTmpNodes($$, $3, 0);}
+  | raster_exp '^' raster_exp   { $$ = new QgsRasterCalcNode(QgsRasterCalcNode::opPOW, $1, $3); joinTmpNodes($$,$1,$3); }
+  | raster_exp '*' raster_exp   { $$ = new QgsRasterCalcNode(QgsRasterCalcNode::opMUL, $1, $3); joinTmpNodes($$,$1,$3); }
+  | raster_exp '/' raster_exp   { $$ = new QgsRasterCalcNode(QgsRasterCalcNode::opDIV, $1, $3); joinTmpNodes($$,$1,$3); }
+  | raster_exp '+' raster_exp   { $$ = new QgsRasterCalcNode(QgsRasterCalcNode::opPLUS, $1, $3); joinTmpNodes($$,$1,$3); }
+  | raster_exp '-' raster_exp   { $$ = new QgsRasterCalcNode(QgsRasterCalcNode::opMINUS, $1, $3); joinTmpNodes($$,$1,$3); }
+  | '(' raster_exp ')'          { $$ = $2; }
+  | NUMBER { $$ = new QgsRasterCalcNode($1); addToTmpNodes($$); }
+  | RASTER_BAND_REF { $$ = new QgsRasterCalcNode(QString::fromUtf8(rastertext)); addToTmpNodes($$); }
+;
+
+%%
+
+void addToTmpNodes(QgsRasterCalcNode* node)
+{
+  gTmpNodes.append(node);
+}
+
+
+void joinTmpNodes(QgsRasterCalcNode* parent, QgsRasterCalcNode* left, QgsRasterCalcNode* right)
+{
+  bool res;
+
+  if (left)
+  {
+    res = gTmpNodes.removeAll(left);
+    Q_ASSERT(res);
+  }
+
+  if (right)
+  {
+    res = gTmpNodes.removeAll(right);
+    Q_ASSERT(res);
+  }
+
+  gTmpNodes.append(parent);
+}
+
+
+QgsRasterCalcNode* parseRasterCalcString(const QString& str, QString& parserErrorMsg)
+{
+  // list should be empty when starting
+  Q_ASSERT(gTmpNodes.count() == 0);
+
+  set_raster_input_buffer(str.toUtf8().constData());
+  int res = rasterparse();
+
+  // list should be empty when parsing was OK
+  if (res == 0) // success?
+  {
+    Q_ASSERT(gTmpNodes.count() == 1);
+    return gTmpNodes.takeFirst();
+  }
+  else // error?
+  {
+    parserErrorMsg = rParserErrorMsg;
+    // remove nodes without parents - to prevent memory leaks
+    while (gTmpNodes.size() > 0)
+      delete gTmpNodes.takeFirst();
+    return NULL;
+  }
+}
+
+void rastererror(const char* msg)
+{
+  rParserErrorMsg = msg;
+}
+
+
+



More information about the QGIS-commit mailing list