BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
parser.l
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) BDSIM Collaboration, 2001 - 2026.
3
4This file is part of BDSIM.
5
6BDSIM is free software: you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published
8by the Free Software Foundation version 3 of the License.
9
10BDSIM is distributed in the hope that it will be useful, but
11WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with BDSIM. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19/*
20 * Lexical analyzer for gmad bison parser
21 * Ilya Agapov, 2005
22 *
23*/
24
25
26
27%x incl
28
29/*
30%option yylineno // use own improved line number info
31*/
32
33%{
34
35#include <cstdio>
36#include <map>
37#include <string>
38#include <vector>
39#include <cstring>
40#include <iostream>
41#include "parser.h"
42#include "parser.tab.hh"
43#include "sym_table.h"
44#include "getEnv.h"
45#include <unistd.h>
46
47#ifdef _WIN32
48#include <io.h>
49#define YY_NO_UNISTD_H 1
50#endif
51
52using namespace GMAD;
53
54extern FILE* yyin;
55extern int yyerror(const char *);
56
57namespace GMAD {
58
59const int max_include_depth = 10;
60YY_BUFFER_STATE include_stack[max_include_depth];
61std::vector<std::string> include_filename_stack(max_include_depth);
62int include_linenum_stack[max_include_depth];
63int include_stack_ptr = 0;
64
65int line_num = 1;
66std::string yyfilename;
67
68}
69
Parser namespace for GMAD language. Combination of Geant4 and MAD.
70%}
71
72%s ERROR
73
74%option nounput
75
76%%
77
78[\t ]+ //ignore whitespaces
79
80(([0-9]+)|([0-9]*\.[0-9]*))((e|E)[+|-]?[0-9]+)? { yylval.dval=atof(yytext); return NUMBER; }
81
82
83"<=" { return LE; }
84">=" { return GE; }
85"<>" { return NE; }
86"==" { return EQ; }
87
88"!".*$ {} // comments - ignore
89"!".* {} // comments at end of file (without return) - ignore
90
91marker { return MARKER; } // reserved elements
92drift { return DRIFT; }
93rf { return RF; }
94rfx { return RFX; }
95rfy { return RFY; }
96rfcavity { return RF; }
97sbend { return SBEND; }
98rbend {return RBEND; }
99hkicker { return HKICKER; }
100vkicker { return VKICKER; }
101kicker { return KICKER; }
102tkicker { return TKICKER; }
103quadrupole { return QUADRUPOLE; }
104sextupole { return SEXTUPOLE; }
105octupole { return OCTUPOLE; }
106decapole { return DECAPOLE; }
107multipole { return MULTIPOLE; }
108thinmultipole { return THINMULT; }
109solenoid { return SOLENOID; }
110rcol { return RCOL;}
111ecol { return ECOL; }
112jcol { return JCOL; }
113bmcol { return BMCOL; }
114jcoltip { return JCOLTIP; }
115gascap { return GASCAP; }
116gasjet { return GASJET; }
117muonspoiler { return MUONSPOILER; }
118muspoiler { return MUONSPOILER; }
119shield {return SHIELD; }
120element { return ELEMENT; }
121screen { return SCREEN; }
122awakescreen { return AWAKESCREEN; }
123awakespectrometer { return AWAKESPECTROMETER; }
124transform3d { return TRANSFORM3D ; }
125laser { return LASERWIREOLD; }
126degrader { return DEGRADER;}
127gap { return GAP;}
128thinrmatrix { return THINRMATRIX;}
129paralleltransporter {return PARALLELTRANSPORTER;}
130rmatrix {return RMATRIX;}
131crystalcol { return CRYSTALCOL; }
132wirescanner { return WIRESCANNER; }
133undulator { return UNDULATOR; }
134usercomponent { return USERCOMPONENT; }
135dump { return DUMP; }
136muoncooler { return MUONCOOLER; }
137ct { return CT; }
138target { return TARGET; }
139gaborlens { return GABORLENS; }
140laserwire { return LASERWIRE; }
141cavitymodel {return CAVITYMODEL; }
142cutsregion { return REGION; }
143newcolour { return NEWCOLOUR; }
144coolingchannel { return COOLINGCHANNEL; }
145crystal { return CRYSTAL; }
146field { return FIELD; }
147placement { return PLACEMENT; }
148laserflux {return LASER; }
149query { return QUERY; }
150samplerplacement { return SAMPLERPLACEMENT; }
151scorer { return SCORER; }
152scorermesh { return SCORERMESH; }
153tunnel { return TUNNEL; }
154xsecbias {return XSECBIAS; }
155xsecBias {return XSECBIAS; }
156aperture {return APERTURE; }
157blm {return BLM;}
158modulator {return MODULATOR;}
159
160matdef { return MATERIAL; }
161atom { return ATOM; }
162
163line { return LINE; }
164
165all { return ALL; }
166period { return PERIOD; }
167range { return RANGE; }
168
169"if" { return IF; }
170"for" { return FOR; }
171"else" { return ELSE; }
172"begin" { return BEGN; }
173"end" { return END; }
174
175
176include BEGIN(incl); //reserved commands
177
178beam { return BEAM; }
179option { return OPTION; }
180beta0 { return BEAM; } // beta0 is a synonym of beam
181print { return PRINT; }
182"return" { return STOP; }
183stop {return STOP;}
184use { return USE; }
185sample { return SAMPLE; }
186csample { return CSAMPLE; }
187
188\"[^",\n]*\" {
189 //strip quotes and return string
190 // no commas or newline in string allowed
191
192 // copy string without quotes,
193 // memory needs to be allocated
194 yylval.str = new std::string(yytext+1,strlen(yytext)-2);
195 // add string to variable vector for deletion afterwards
196 Parser::Instance()->AddVariable(yylval.str);
197 return STR;
198}
static Parser * Instance()
Access method.
Definition parser.cc:121
void AddVariable(std::string *name)
Add variable memory to variable list for memory management.
Definition parser.cc:980
199
200\" {
201 // give warning for other strings
202 std::string errorstring = "malformed string or unmatched quote";
203 yyerror(errorstring.c_str());
204}
205
206":=" { return '=';} // alternative assignment
207
208[a-zA-Z#][A-Za-z0-9_#.]* {
209 std::string var(yytext);
210 // look up variable if defined and array or function
211 // else create string (also if in the lookup map(!))
212 Symtab *sp = Parser::Instance()->symlook(var);
213 if (sp) {
214 yylval.symp=sp;
215 switch(sp->GetType()) {
216 case Symtab::symtabtype::FUNCTION:
217 return FUNC;
218 case Symtab::symtabtype::ARRAY:
219 return VECVAR;
220 case Symtab::symtabtype::NUMBER:
221 return NUMVAR;
222 case Symtab::symtabtype::STRING:
223 return STRVAR;
224 default:
225 break;
226 }
227 }
228 std::string* name = new std::string(var);
229 // add string to variable vector for deletion afterwards
231 yylval.str = name;
232 return VARIABLE;
233}
Symtab * symlook(const std::string &s)
look up parser symbol
Definition parser.cc:846
Common header for the lexer and the parser to share Symbol table for numeric variables,...
Definition sym_table.h:32
symtabtype GetType() const
Get type.
Definition sym_table.cc:69
234. { return yytext[0]; } // return characters like * and /
235
236<incl>[ \t]* // eat the whitespace
237<incl>[^ \t\n;]+ {
238
239 //this is perhaps unnecessary now...
240 std::string bdsimpath = (std::string)getEnv("BDSIMPATH");
241 std::string includefilename = "";
242 std::string mainfilename = yyfilename; //get the supplied main filename
243 std::string mainfilepath = "";
244 if(bdsimpath.length()>0){
245#ifdef BDSDEBUG
246 std::cout << "parser> using BDSIMPATH to build included filepaths" << std::endl;
247#endif
248 includefilename = bdsimpath + (std::string)yytext;
249 } else {
250 // get the path part of the supplied path to the main input file
251 std::string::size_type found = mainfilename.rfind("/"); // find the last '/'
252 if (found != std::string::npos) {
253 mainfilepath = mainfilename.substr(0,found+1); // the path is the bit before that, including the '/'
254 } // else remains empty string
255 // need to know whether it's an absolute or relative path
256 if ((mainfilename.substr(0,1)) == "/"){
257 // the main file has an absolute path
258 includefilename = mainfilepath + (std::string)yytext;
259 } else {
260 // the main file has a relative path or just the file name
261 char cwdchars[200]; //filepath up to 200 characters
262 // get current working directory
263 std::string cwd = (std::string)getcwd(cwdchars, sizeof(cwdchars)) + "/";
264 includefilename = cwd + mainfilepath + (std::string)yytext;
265 }
266 }
267
268 std::cout << "parser> reading file " << includefilename << std::endl; //yytext
269 if (includefilename == yyfilename)
270 {
271 std::string errorstring = "\nError: recursively including the same file inside itself!\n\n Problem"; // at line.. etc
272 yyerror(errorstring.c_str());
273 }
274 if(include_stack_ptr >= max_include_depth - 1)
275 {
276 std::string errorstring = "Error : Include depth exceeds " + std::to_string(max_include_depth);
277 yyerror(errorstring.c_str());
278 }
279 else
280 {
281 yyin = fopen(includefilename.c_str(), "r"); //yytext
282 if(yyin)
283 {
284 //std::cout << "saving to stack buffer n " << include_stack_ptr << ", file " << yyfilename << std::endl;
285 // save info to the stack and load new buffer
286 include_linenum_stack[include_stack_ptr] = line_num;
287 line_num = 1;
288 include_filename_stack[include_stack_ptr] = yyfilename;
289 yyfilename = includefilename; //yytext
290 include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER;
291 include_filename_stack[include_stack_ptr] = yyfilename;
292 yy_switch_to_buffer(yy_create_buffer( yyin, YY_BUF_SIZE ) );
293 //std::cout << "done saving to stack" << std::endl;
294 }
295 else
296 {
297 std::string errorstring = "Error : can't open " + includefilename;
298 yyerror(errorstring.c_str());
299 }
300 }
301 BEGIN(INITIAL);
302}
303
304<<EOF>> {
305 if (--include_stack_ptr < 0)
306 {
307 yyterminate();
308 }
309 else
310 {
311 // restore the previous buffer info
312 //std::cout << "switching to previous buffer with " << include_filename_stack[include_stack_ptr] << std::endl;
313 yy_delete_buffer(YY_CURRENT_BUFFER);
314 yy_switch_to_buffer(include_stack[include_stack_ptr]);
315 yyfilename = include_filename_stack[include_stack_ptr];
316 line_num = include_linenum_stack[include_stack_ptr];
317 }
318}
319
320\n line_num++; // unix line separator
321\r\n line_num++; // windows line separator
322
323%%