⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.y

📁 蒙特卡罗模拟光子成像C语言版,代码简洁专业
💻 Y
📖 第 1 页 / 共 2 页
字号:
%{
/*
 * This file is part of tMCimg.
 * 
 * tMCimg 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 program 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 program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

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

#include "config.h"
#include "tMCimg.h"

#if (HAVE_ASSERT_H)
#include <assert.h>
#endif

static double tmpmus, tmpmua, tmpn, tmpg;
static double tmppos[3], tmpdir[3], tmprad, tmpna;
static struct Config *config = NULL;
 
void init_config(void);
int  checkconfig(void);
void add_tissue(double mus, double mua, double g, double n);
void add_detector(double r[3], double d[3], double rad, double na);
void   add_source(double r[3], double d[3], double rad, double na);

#define YYDEBUG 0

extern void parsefile(FILE *);
extern int yylex();

void yyerror(const char *s)
{
  extern int linenumber;
  extern char *yytext;

  fprintf(stderr, "%s\n", (s == NULL) ? "" : s);
  fprintf(stderr, "Error on line %d near text \"%s\"\n", 
          linenumber, (yytext == NULL) ? "" : yytext);

  return;
}
%}

%union {
  double      real;
  int         integer;
  const char *string;
  char        character;
  int        *ipointer;
  double     *rpointer;
}

%token NPHOTONS
%token SEED
%token SEGFILE
%token FREQUENCY
%token CLIGHT

%token STIME
%token NTIME
%token DTIME

%token TISSUETYPE

%token MUS
%token MUA
%token G
%token N

%token SOURCE
%token DETECTOR
%token SDPOS
%token SDDIR
%token SDRAD
%token SDNA

%token DX
%token DY
%token DZ

%token IMGX
%token IMGY
%token IMGZ

%token NXSTEP
%token NYSTEP
%token NZSTEP

%token SETFLAG
%token FTWOPT
%token FSMOVE
%token FDMOVE
%token FXMOVE
%token FXTIME
%token FMATLAB
%token FMIRROR

%token <string>   FILENAME
%token <real>     REALNUMBER
%token <integer>  DECNUMBER

%type  <rpointer> vector
%type  <ipointer> range
%type  <real>     number
%type  <integer>  bool
  
%%

input:	/* empty */
	| input statement
	| input error { exit(1); };

statement: flag
	| option
	| tissue
        | source
	| detector;

option:   NPHOTONS  DECNUMBER { config->NT        = $2; };
	| SEED      DECNUMBER { config->seed      = (long)$2; };
	| SEGFILE   FILENAME  { strncpy(config->segFile, $2, FILENMLEN); };
	| FREQUENCY number    { config->frequency = $2; };
	| CLIGHT    number    { config->v0        = $2; };
	| STIME     number    { config->Tmin      = $2; };
	| DTIME     number    { config->stepT     = $2; };
	| NTIME     number    { config->nTstep    = (int)$2; };
	| IMGX      range     { config->Ixmin=($2)[0]; config->Ixmax=($2)[1]; };
	| IMGY      range     { config->Iymin=($2)[0]; config->Iymax=($2)[1]; };
	| IMGZ      range     { config->Izmin=($2)[0]; config->Izmax=($2)[1]; };
	| DX        number    { config->xstep = $2; };
	| DY        number    { config->ystep = $2; };
	| DZ        number    { config->zstep = $2; };
	| NXSTEP    number    { config->nxstep=(int)$2; };
	| NYSTEP    number    { config->nystep=(int)$2; };
	| NZSTEP    number    { config->nzstep=(int)$2; };
	| SETFLAG   flag;

flag:	  SETFLAG FTWOPT  bool { if ($3 == 1)
				   printf("\t!Config set 2pt flag\n");
				 else
				   printf("\t!Config set no-2pt flag\n");
				 config->flags.gen_twopt = $3; };
	| SETFLAG FSMOVE  bool { if ($3 == 1)
				   printf("\t!Config set src move flag\n");
				 else
				   printf("\t!Config set no-src move flag\n");
				 config->flags.source_move = $3; };
	| SETFLAG FDMOVE  bool { if ($3 == 1)
				   printf("\t!Config set det move flag\n");
				 else
				   printf("\t!Config set no-det move flag\n");
				 config->flags.detector_move = $3; };
	| SETFLAG FXMOVE  bool { if ($3 == 1)
				   printf("\t!Config set exit move flag\n");
				 else
				   printf("\t!Config set no-exit move flag\n");
				 config->flags.exiting_move = $3; };
	| SETFLAG FXTIME  bool { if ($3 == 1)
				   printf("\t!Config set exit time flag\n");
				 else
				   printf("\t!Config set exit bin flag\n");
				 config->flags.exact_exit_time = $3; };
	| SETFLAG FMATLAB bool { if ($3 == 1)
				   printf("\t!Config set matlab order flag\n");
				 else
				   printf("\t!Config set C order flag\n");
				 config->flags.matlab_order = $3; };
	| SETFLAG FMIRROR bool { if ($3 == 1)
				   printf("\t!Config set mirror BC flag\n");
				 else
				   printf("\t!Config set no-mirror BC flag\n");
				 config->flags.mirror = $3; };

tissue:   TISSUETYPE '{' { tmpmus = -1; tmpmua = -1; 
                           tmpn   = -1; tmpg   = -1; };
	| tissue tissue_prop 
	| tissue '}' { if ((tmpmus == -1) || (tmpmua == -1) ||
		           (tmpg   == -1) || (tmpn   == -1)) {
                         yyerror("Incompletely initialized tissue type\n");
			 YYABORT;
		       }

		       add_tissue(tmpmus, tmpmua, tmpg, tmpn); 
		     };

detector: DETECTOR '{' { tmppos[0] = tmppos[1] = tmppos[2] = -998;
                         tmpdir[0] = tmpdir[1] = tmpdir[2] = 0.0;
                         tmprad = -1.0;
                         tmpna  =  1.0; };
        | detector sd_prop
        | detector '}' { add_detector(tmppos, tmpdir, tmprad, tmpna); 
                         tmprad = -1; };

source:   SOURCE '{'   { tmppos[0] = tmppos[1] = tmppos[2] = -998;
                         tmpdir[0] = tmpdir[1] = tmpdir[2] = 0.0;
                         tmprad = 0.0;
                         tmpna  = 0.0; };
        | source sd_prop
        | source '}'   { add_source(tmppos, tmpdir, tmprad, tmpna); 
                         tmprad = -1; };

tissue_prop: MUS number { tmpmus = $2; };
	   | MUA number { tmpmua = $2; };
	   | G   number { tmpg   = $2; };
	   | N   number { tmpn   = $2; };

sd_prop:  SDRAD number  { tmprad = $2; };
	| SDNA  number  { tmpna  = $2; };
	| SDPOS vector  { memcpy(tmppos, (double *)$2, sizeof(tmppos)); 
                          free((double *)$2); };
	| SDDIR vector  { memcpy(tmpdir, (double *)$2, sizeof(tmpdir));
                          free((double *)$2); };

vector:  '[' number number number ']' {
                double *rvec = (double *)malloc(3*sizeof(double));
#if (HAVE_ASSERT_H)
                assert(rvec != NULL);
#endif

                rvec[0] = $2; rvec[1] = $3; rvec[2] = $4;
                $$ = rvec;
              };

range: DECNUMBER DECNUMBER {
		static int drange[2];

		drange[0] = $1;  drange[1] = $2;
		$$ = drange;
	      };

bool:	  DECNUMBER  { if ($1 == 0)  /* Boolean from integer */
                         { $$ = 0; }
                       else
                         { $$ = 1; } };

number:   REALNUMBER { $$ =         $1; };
        | DECNUMBER  { $$ = (double)$1; /* type promotion */ };

%%

int parseconfig(struct Config *p, FILE *fp)
{
  double dv = 0;

#if (HAVE_ASSERT_H)
  assert(p  != NULL);
  assert(fp != NULL);
#endif

  config = p;

  init_config();                  /* Initialize the memory */

  parsefile(fp);                  /* Read and parse the .inp file */

  /* Compute the various derived quantities */

  config->frequency *= 1.0e6;     /* Convert from MHz */
  config->k0         = 2*PI*config->frequency / config->v0;

  config->Tmax = config->Tmin + config->nTstep * config->stepT;

  /* Image sizes not specified implicitly mean "use all" */

  if ((config->Ixmin == -1) && (config->Ixmax == -1))
    {
      config->Ixmin = 0;
      config->Ixmax = config->nxstep - 1;
    }

  if ((config->Iymin == -1) && (config->Iymax == -1))
    {
      config->Iymin = 0;
      config->Iymax = config->nystep - 1;
    }

  if ((config->Izmin == -1) && (config->Izmax == -1))
    {
      config->Izmin = 0;
      config->Izmax = config->nzstep - 1;
    }

  /* Compute number of voxels in image region */

  config->nIxstep = config->Ixmax - config->Ixmin + 1;
  config->nIystep = config->Iymax - config->Iymin + 1;
  config->nIzstep = config->Izmax - config->Izmin + 1;

  if (config->zstep > dv) dv = config->zstep;
  if (config->ystep > dv) dv = config->ystep;
  if (config->xstep > dv) dv = config->xstep;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -