[7dd4fb]: src / parser / parser.y Maximize Restore History

Download this file

parser.y    515 lines (464 with data), 13.9 kB

/*
 *  parser.y
 *
 *  Copyright  Daniel M. German
 *  
 *  April 2007
 *
 *  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.
 *
 *  This software 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
 *  General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public
 *  License along with this software; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *
 *  Author: Daniel M German dmgerman at uvic doooot ca
 * 
 */

%{
       #include <math.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <string.h>

#include "tparser.h"
#include "tparserprivate.h"

       int yylex (void);
       void yyerror (char const *);
/*  Keeps track of the current type of input line in the file */
int  currentLine = -1;

pt_script script;

/* defining it gives better error messages. It might be an overkill */
#define YYERROR_VERBOSE 1 

static pt_script_image *image;
static pt_script_ctrl_point *ctrlPoint;
static pt_script_morph_point *morphPoint;


/* copy a string while allocating and checking for memory */
static void ParserStringCopy(char **dest, char *from)
{
    if (*dest) 
	free(*dest);
    *dest = strdup(from);
    if (*dest == NULL)
	panoScriptParserError(1,"Not enough memory");
}


%}
     
%defines

%union {
  int   iVal;
  float fVal;
  char strVal[PT_TOKEN_MAX_LEN+1];
  char cVal;
}


%token NUM
%token PT_TOKEN_SEP
%token <fVal> PT_TOKEN_NUMBER
%token <strVal> PT_TOKEN_STRING
%token <cVal> PT_TOKEN_KEYWORD
%token <cVal> PT_TOKEN_CROPPING

%token PT_TOKEN_EOL
%token PT_TOKEN_SEPARATOR
%token PT_TOKEN_INPUT_LINE
%token PT_TOKEN_OUTPUT_LINE
%token PT_TOKEN_PANO_LINE
%token PT_TOKEN_OPTIMIZE_LINE
%token PT_TOKEN_CONTROL_PT_LINE
%token PT_TOKEN_COMMA
%token PT_TOKEN_REFERENCE
%token PT_TOKEN_MORPH_PT_LINE


%start input

%% /* Grammar rules and actions follow.  */

input: lines 
      { 
          int i;
          pt_script_morph_point *morphPoint2;
          int image;
          pt_script_image *imageSpec;
          // We have to move the morphing control points to their corresponding images
          for (i = 0; i < script.iMorphPointsCount; i++) {
              fprintf(stderr, "abc************************************\n");
              // get a pointer to the point to make life easier
              morphPoint = &morphPointsSpec[i];
              image = morphPoint->iImage;
              // we need to verify that the iamge pointer exists
              if (image < 0 || image > script.iInputImagesCount) {
                  panoScriptParserError(0,"Morphing control point number %d references non existent input image [%c].\n", i, image);
                  return -1;
              }
              // point to the image, avoids long dereferrencing
              imageSpec = &script.inputImageSpec[image];

              // allocate the pointer
              morphPoint2 = (pt_script_morph_point *)panoScriptReAlloc((void*)&imageSpec->morphPoints, 
                                                                  sizeof(pt_script_morph_point), &imageSpec->morphPointsCount);
              
              memcpy(morphPoint2, morphPoint, sizeof(pt_script_morph_point));
          }
          for (i=0;i<script.iInputImagesCount; i++)  {
              fprintf(stderr, "LLLLLLLLLLLLLLLLLLLLLLL %d\n", script.inputImageSpec[image].morphPointsCount);
          }
          return 0;
      }

lines: 
        | line input
{
    printf("Per line...\n");
}
     
line:     eoln { ; }
             | inputline
             | outputline
             | panoline
             | optimizeline
             | ctrlPtsLine
             | morphPtsLine
;
     

ctrlPtsLine: PT_TOKEN_CONTROL_PT_LINE PT_TOKEN_SEPARATOR
        { 
            currentLine = PT_TOKEN_CONTROL_PT_LINE;
            ctrlPoint = (pt_script_ctrl_point *)panoScriptReAlloc((void*)&script.ctrlPointsSpec, 
                                                                  sizeof(pt_script_ctrl_point), &script.iCtrlPointsCount);
        }  
        varsparms eoln       { ; }

morphPtsLine: PT_TOKEN_MORPH_PT_LINE PT_TOKEN_SEPARATOR
        { 
            currentLine = PT_TOKEN_MORPH_PT_LINE;
            morphPoint = (pt_script_morph_point *)panoScriptReAlloc((void*)&morphPointsSpec, 
                                                                  sizeof(pt_script_morph_point), &script.iMorphPointsCount);
        }  
        varsparms eoln       { ; }


eoln:     PT_TOKEN_EOL  { currentLine = -1; /* This says we don't know the type of line being processed */}

inputline:  PT_TOKEN_INPUT_LINE PT_TOKEN_SEPARATOR
        {

	    currentLine = PT_TOKEN_INPUT_LINE; 

            image = (pt_script_image *)panoScriptReAlloc((void*)&(script.inputImageSpec),
                                                         sizeof(pt_script_image), &script.iInputImagesCount);

#ifdef asdfasf
	    // allocate the new output
	    script.iInputImagesCount++;
	    script.inputImageSpec = realloc(script.inputImageSpec, 
					     sizeof(*script.inputImageSpec) * script.iInputImagesCount);
	    if (script.inputImageSpec == NULL) {
		yyerror("Not enough memory");
	    }
	    // clear the end of the reallocated region
	    bzero(&(script.inputImageSpec[script.iInputImagesCount-1]), sizeof(*script.inputImageSpec));
	    image = &script.inputImageSpec[script.iInputImagesCount-1];
#endif
        }   
        vars eoln      { ; }

outputline: PT_TOKEN_OUTPUT_LINE PT_TOKEN_SEPARATOR 
        {
	    currentLine = PT_TOKEN_OUTPUT_LINE; 
	    // allocate the new output
	    script.iOutputImagesCount++;
	    script.outputImageSpec = realloc(script.outputImageSpec, 
					     sizeof(*script.outputImageSpec) * script.iOutputImagesCount);
	    if (script.outputImageSpec == NULL) {
		yyerror("Not enough memory");
	    }
	    // clear the end of the reallocated region
	    bzero(&(script.outputImageSpec[script.iOutputImagesCount-1]), sizeof(*script.outputImageSpec));
	    image = &script.outputImageSpec[script.iOutputImagesCount-1];
	}      vars eoln      { ; }

optimizeline: PT_TOKEN_OPTIMIZE_LINE PT_TOKEN_SEPARATOR { currentLine=PT_TOKEN_OPTIMIZE_LINE; } vars eoln      { ; }

panoline: PT_TOKEN_PANO_LINE  PT_TOKEN_SEPARATOR { currentLine=PT_TOKEN_PANO_LINE; } vars eoln      { ; }


vars:      var
          | vars PT_TOKEN_SEPARATOR var

/* a variable can be a cropping one (with 4 parms), a one-parm one, a reference to another variable, or finally, a name 
   only */
var:      varcropping |  varparameter  | varreference | varonly

varsparms:  varparameter
          | varsparms PT_TOKEN_SEPARATOR varparameter



 /*  Rule for input image field references <var>=<index> */
varreference: PT_TOKEN_KEYWORD PT_TOKEN_REFERENCE PT_TOKEN_NUMBER
   {
       int imageRef = lroundf($3) + 1;
       switch (currentLine) {
       case PT_TOKEN_INPUT_LINE:
	   switch ($1) {
	    case 'v':
		image->fHorFOVIndex = imageRef;
		break;
	    case 'y':
		image->yawIndex = imageRef;
		break;
	    case 'p':
		image->pitchIndex = imageRef;
		break;
	    case 'r':
		image->rollIndex = imageRef;
		break;
	    case 'a':
	    case 'b':
	    case 'c':
	    case 'd':
	    case 'e':
		image->coefIndex[$1-'a'] = imageRef;
		break;
	    case 'g':
		image->coefIndex[5] = imageRef;
		break;
	    case 't':
		image->coefIndex[6] = imageRef;
		break;
	   default:
	       panoScriptParserError(1,"Invalid variable name [%c] in input line.\n", $1);
	       return -1;
	       break;
	   }
	   break;
       default:
	   panoScriptParserError(1,"Error Not handled 3 [%c]\n", $1);
	   return -1;
       }
   }

 /* Rule for [CS]<x>,<x>,<x>,<x> */
varcropping: PT_TOKEN_CROPPING PT_TOKEN_NUMBER PT_TOKEN_COMMA PT_TOKEN_NUMBER PT_TOKEN_COMMA PT_TOKEN_NUMBER PT_TOKEN_COMMA PT_TOKEN_NUMBER
    {
	switch (currentLine) {
	case PT_TOKEN_OUTPUT_LINE:
	case PT_TOKEN_INPUT_LINE:
	    switch ($1) {
	    case 'C':
	    case 'S':
		image->cropType = $1;
		image->cropArea[0] = lroundf($2);
		image->cropArea[1] = lroundf($4);
		image->cropArea[2] = lroundf($6);
		image->cropArea[3] = lroundf($8);
		break;
	    default:
		panoScriptParserError(1,"Invalid variable name- [%c] in image line\n", $1);
		return -1;
	    }
	    break;
	default:
	    panoScriptParserError(1,"Error Not handled 3\n");
	    return -1;
	}
    }

/*  
    Rules for <variable><parameter> 
 */
varparameter: PT_TOKEN_KEYWORD PT_TOKEN_STRING 
    { 
        /* Processing of string variables */
	switch (currentLine) {
	case PT_TOKEN_PANO_LINE:
	    switch ($1) {
	    case 'f':
		ParserStringCopy(&script.pano.projectionName, $2);
		break;
	    case 'n':
		ParserStringCopy(&script.pano.outputFormat, $2);
		break;
	    case 'P':
		ParserStringCopy(&script.pano.projectionParmsString, $2);
		break;
	    default:
		panoScriptParserError(1,"Invalid variable name [%c] in pano line\n", $1);
		return -1;
	    }
	    break;
	case PT_TOKEN_OUTPUT_LINE:
	case PT_TOKEN_INPUT_LINE:
	    switch ($1) {
	    case 'n':
		ParserStringCopy(&image->name, $2);
		break;
	    default:
		panoScriptParserError(1,"Invalid variable name [%c] in image line..\n", $1);
		return -1;
	    }
	    break;
	default:
	    panoScriptParserError(1,"Error Not handled case [%c]\n", $1);
	    return -1;
	}
    }
   | PT_TOKEN_KEYWORD PT_TOKEN_NUMBER
    {
        /* Processing of int variables */
	switch (currentLine) {
        case PT_TOKEN_CONTROL_PT_LINE:
	   switch ($1) {
           case 'n':
               ctrlPoint->iImage1 = lround($2);
               break;
           case 'N':
               ctrlPoint->iImage2 = lround($2);
               break;
           case 'x':
               ctrlPoint->p1.x = $2;
               break;
           case 'y':
               ctrlPoint->p1.y = $2;
               break;
           case 'X':
               ctrlPoint->p2.x = $2;
               break;
           case 'Y':
               ctrlPoint->p2.y = $2;
               break;
           case 't':
               ctrlPoint->type = $2;
               break;
	   default:
	       panoScriptParserError(1, "Invalid variable name [%c] in input line.\n", $1);
	       return -1;
	       break;
	   }
           break;
        case PT_TOKEN_MORPH_PT_LINE:
	   switch ($1) {
           case 'i':
               morphPoint->iImage = lround($2);
               break;
           case 'x':
               morphPoint->p1.x = $2;
               break;
           case 'y':
               morphPoint->p1.y = $2;
               break;
           case 'X':
               morphPoint->p2.x = $2;
               break;
           case 'Y':
               morphPoint->p2.y = $2;
               break;
	   default:
	       panoScriptParserError(1, "Invalid variable name [%c] in input line.\n", $1);
	       return -1;
	       break;
	   }
           break;
	case PT_TOKEN_PANO_LINE:
	    switch ($1) {
	    case 'w':
		script.pano.width = lroundf($2);
		break;
	    case 'h':
		script.pano.height = lroundf($2);
		break;
	    case 'f':
		script.pano.projection = lroundf($2);
		break;
	    case 'v':
		script.pano.fHorFOV = $2;
		break;
	    case 'E':
		panoScriptParserError(1,"Invalid variable name [%c] in pano line. Ignored...\n", $1);
		break;
	    case 'R':
		panoScriptParserError(1,"Invalid variable name [%c] in pano line. Ignored...\n", $1);
		break;
	    default:
		panoScriptParserError(1,"Invalid variable name [%c] in pano line\n", $1);
		return -1;
	    }
	    break;
	case PT_TOKEN_OUTPUT_LINE:
	case PT_TOKEN_INPUT_LINE:
	    switch ($1) {
	    case 'w':
		image->width = lroundf($2);
		break;
	    case 'h':
		image->height = lroundf($2);
		break;
	    case 'f':
		image->projection = lroundf($2);
		break;
	    case 'v':
		image->fHorFOV = $2;
		break;
	    case 'y':
		image->yaw = $2;
		break;
	    case 'p':
		image->pitch = $2;
		break;
	    case 'r':
		image->roll = $2;
		break;
	    case 'a':
	    case 'b':
	    case 'c':
	    case 'd':
	    case 'e':
		image->coef[$1-'a'] = $2;
		break;
	    case 'g':
		image->coef[5] = $2;
		break;
	    case 't':
		image->coef[6] = $2;
		break;
	    case 'u':
	    case 'm':
		printf("Option %c in image line deprecated. Ignored...\n", $1);
		break;
	    default:
		panoScriptParserError(1,"Invalid variable name [%c] in image line...\n", $1);
		return -1;
	    }
	    break;
	case PT_TOKEN_OPTIMIZE_LINE:
	    switch ($1) {
	    case 'g':
		script.optimize.fGamma = $2;
		break;
	    case 'i':
		script.optimize.interpolator = lroundf($2);
		break;
	    case 'f':
		script.optimize.fastFT = lroundf($2);
		break;
	    case 'm':
		script.optimize.huberEstimator = lround($2);
		break;
	    case 'p':
		panoScriptParserError(1,"Obsolete variable name [%c] in optimize line. Ignored...\n", $1);
		break;
	    default:
		panoScriptParserError(1,"Invalid variable name [%c] in optimize line\n", $1);
		return -1;
	    }
	    break;
	default:
	    panoScriptParserError(1,"Error. Not handled (token int [%c]\n", $1);
	    return -1;
	}
    }
             

varonly: PT_TOKEN_KEYWORD
    {
	switch (currentLine) {
	case PT_TOKEN_PANO_LINE:
	    switch ($1) {
	    case 'T':
		panoScriptParserError(1,"Invalid variable name [%c] in pano line. Ignored...\n", $1);
		break;
	    default:
		panoScriptParserError(1,"Invalid variable name [%c] in pano line\n", $1);
		return -1;
	    }
	    break;
	case PT_TOKEN_OUTPUT_LINE:
	case PT_TOKEN_INPUT_LINE:
	    switch ($1) {
	    default:
		panoScriptParserError(1,"Invalid variable name [%c] in image line....\n", $1);
		return -1;
	    }
	    break;
	default:
	    panoScriptParserError(1,"Error Not handled 3\n");
	    return -1;
	}
    }




%%