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