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 - 2023.
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; }
114muonspoiler { return MUONSPOILER; }
115muspoiler { return MUONSPOILER; }
116shield {return SHIELD; }
117element { return ELEMENT; }
118screen { return SCREEN; }
119awakescreen { return AWAKESCREEN; }
120awakespectrometer { return AWAKESPECTROMETER; }
121transform3d { return TRANSFORM3D ; }
122laser { return LASER; }
123degrader { return DEGRADER;}
124gap { return GAP;}
125thinrmatrix { return THINRMATRIX;}
126paralleltransporter {return PARALLELTRANSPORTER;}
127rmatrix {return RMATRIX;}
128crystalcol { return CRYSTALCOL; }
129wirescanner { return WIRESCANNER; }
130undulator { return UNDULATOR; }
131usercomponent { return USERCOMPONENT; }
132dump { return DUMP; }
133ct { return CT; }
134target { return TARGET; }
135
136cavitymodel {return CAVITYMODEL; }
137cutsregion { return REGION; }
138newcolour { return NEWCOLOUR; }
139crystal { return CRYSTAL; }
140field { return FIELD; }
141placement { return PLACEMENT; }
142query { return QUERY; }
143samplerplacement { return SAMPLERPLACEMENT; }
144scorer { return SCORER; }
145scorermesh { return SCORERMESH; }
146tunnel { return TUNNEL; }
147xsecbias {return XSECBIAS; }
148xsecBias {return XSECBIAS; }
149aperture {return APERTURE; }
150blm {return BLM;}
151modulator {return MODULATOR;}
152
153matdef { return MATERIAL; }
154atom { return ATOM; }
155
156line { return LINE; }
157
158all { return ALL; }
159period { return PERIOD; }
160range { return RANGE; }
161
162"if" { return IF; }
163"for" { return FOR; }
164"else" { return ELSE; }
165"begin" { return BEGN; }
166"end" { return END; }
167
168
169include BEGIN(incl); //reserved commands
170
171beam { return BEAM; }
172option { return OPTION; }
173beta0 { return BEAM; } // beta0 is a synonym of beam
174print { return PRINT; }
175"return" { return STOP; }
176stop {return STOP;}
177use { return USE; }
178sample { return SAMPLE; }
179csample { return CSAMPLE; }
180
181\"[^",\n]*\" {
182 //strip quotes and return string
183 // no commas or newline in string allowed
184
185 // copy string without quotes,
186 // memory needs to be allocated
187 yylval.str = new std::string(yytext+1,strlen(yytext)-2);
188 // add string to variable vector for deletion afterwards
189 Parser::Instance()->AddVariable(yylval.str);
190 return STR;
191}
static Parser * Instance()
Access method.
Definition: parser.cc:94
void AddVariable(std::string *name)
Add variable memory to variable list for memory management.
Definition: parser.cc:818
192
193\" {
194 // give warning for other strings
195 std::string errorstring = "malformed string or unmatched quote";
196 yyerror(errorstring.c_str());
197}
198
199":=" { return '=';} // alternative assignment
200
201[a-zA-Z#][A-Za-z0-9_#.]* {
202 std::string var(yytext);
203 // look up variable if defined and array or function
204 // else create string (also if in the lookup map(!))
205 Symtab *sp = Parser::Instance()->symlook(var);
206 if (sp) {
207 yylval.symp=sp;
208 switch(sp->GetType()) {
209 case Symtab::symtabtype::FUNCTION:
210 return FUNC;
211 case Symtab::symtabtype::ARRAY:
212 return VECVAR;
213 case Symtab::symtabtype::NUMBER:
214 return NUMVAR;
215 case Symtab::symtabtype::STRING:
216 return STRVAR;
217 default:
218 break;
219 }
220 }
221 std::string* name = new std::string(var);
222 // add string to variable vector for deletion afterwards
224 yylval.str = name;
225 return VARIABLE;
226}
Symtab * symlook(const std::string &s)
look up parser symbol
Definition: parser.cc:706
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
227. { return yytext[0]; } // return characters like * and /
228
229<incl>[ \t]* // eat the whitespace
230<incl>[^ \t\n;]+ {
231
232 //this is perhaps unnecessary now...
233 std::string bdsimpath = (std::string)getEnv("BDSIMPATH");
234 std::string includefilename = "";
235 std::string mainfilename = yyfilename; //get the supplied main filename
236 std::string mainfilepath = "";
237 if(bdsimpath.length()>0){
238#ifdef BDSDEBUG
239 std::cout << "parser> using BDSIMPATH to build included filepaths" << std::endl;
240#endif
241 includefilename = bdsimpath + (std::string)yytext;
242 } else {
243 // get the path part of the supplied path to the main input file
244 std::string::size_type found = mainfilename.rfind("/"); // find the last '/'
245 if (found != std::string::npos) {
246 mainfilepath = mainfilename.substr(0,found+1); // the path is the bit before that, including the '/'
247 } // else remains empty string
248 // need to know whether it's an absolute or relative path
249 if ((mainfilename.substr(0,1)) == "/"){
250 // the main file has an absolute path
251 includefilename = mainfilepath + (std::string)yytext;
252 } else {
253 // the main file has a relative path or just the file name
254 char cwdchars[200]; //filepath up to 200 characters
255 // get current working directory
256 std::string cwd = (std::string)getcwd(cwdchars, sizeof(cwdchars)) + "/";
257 includefilename = cwd + mainfilepath + (std::string)yytext;
258 }
259 }
260
261 std::cout << "parser> reading file " << includefilename << std::endl; //yytext
262 if (includefilename == yyfilename)
263 {
264 std::string errorstring = "\nError: recursively including the same file inside itself!\n\n Problem"; // at line.. etc
265 yyerror(errorstring.c_str());
266 }
267 if(include_stack_ptr >= max_include_depth - 1)
268 {
269 std::string errorstring = "Error : Include depth exceeds " + std::to_string(max_include_depth);
270 yyerror(errorstring.c_str());
271 }
272 else
273 {
274 yyin = fopen(includefilename.c_str(), "r"); //yytext
275 if(yyin)
276 {
277 //std::cout << "saving to stack buffer n " << include_stack_ptr << ", file " << yyfilename << std::endl;
278 // save info to the stack and load new buffer
279 include_linenum_stack[include_stack_ptr] = line_num;
280 line_num = 1;
281 include_filename_stack[include_stack_ptr] = yyfilename;
282 yyfilename = includefilename; //yytext
283 include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER;
284 include_filename_stack[include_stack_ptr] = yyfilename;
285 yy_switch_to_buffer(yy_create_buffer( yyin, YY_BUF_SIZE ) );
286 //std::cout << "done saving to stack" << std::endl;
287 }
288 else
289 {
290 std::string errorstring = "Error : can't open " + includefilename;
291 yyerror(errorstring.c_str());
292 }
293 }
294 BEGIN(INITIAL);
295}
296
297<<EOF>> {
298 if (--include_stack_ptr < 0)
299 {
300 yyterminate();
301 }
302 else
303 {
304 // restore the previous buffer info
305 //std::cout << "switching to previous buffer with " << include_filename_stack[include_stack_ptr] << std::endl;
306 yy_delete_buffer(YY_CURRENT_BUFFER);
307 yy_switch_to_buffer(include_stack[include_stack_ptr]);
308 yyfilename = include_filename_stack[include_stack_ptr];
309 line_num = include_linenum_stack[include_stack_ptr];
310 }
311}
312
313\n line_num++; // unix line separator
314\r\n line_num++; // windows line separator
315
316%%