📄 parser.y
字号:
%{
/*
* 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 + -