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