OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
OPAL
LineTemplate.cpp
Go to the documentation of this file.
1 //
2 // Class LineTemplate
3 //
4 // An ``archetype'' for a OPAL beam line with arguments.
5 // The model is stored in form of a MacroStream. A call to the macro line
6 // is expanded by first replacing the arguments, and then parsing the
7 // resulting stream as a LINE definition.
8 //
9 // Copyright (c) 2008 - 2020, Paul Scherrer Institut, Villigen PSI, Switzerland
10 //
11 // All rights reserved
12 //
13 // This file is part of OPAL.
14 //
15 // OPAL is free software: you can redistribute it and/or modify
16 // it under the terms of the GNU General Public License as published by
17 // the Free Software Foundation, either version 3 of the License, or
18 // (at your option) any later version.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with OPAL. If not, see <https://www.gnu.org/licenses/>.
22 //
23 
24 #include "Lines/LineTemplate.h"
25 
26 #include "Utility/PAssert.h"
27 
29 #include "Lines/Line.h"
30 #include "Parser/SimpleStatement.h"
31 #include "Utilities/ParseError.h"
32 #include <vector>
33 
35  Macro(0, "LINE",
36  "This object defines a beamline list with arguments.\n"
37  "\t<name>(<args>);"),
38  body("LINE")
39 {}
40 
41 
42 LineTemplate::LineTemplate(const std::string &name, Object *parent):
43  Macro(name, parent), body(name)
44 {}
45 
46 
48 {}
49 
50 
51 LineTemplate *LineTemplate::clone(const std::string &/*name*/) {
52  throw ParseError("LineTemplate::clone()",
53  "You cannot use this object without attributes.");
54 }
55 
56 
58 (const std::string &name, Statement &statement, const Parser *) {
59  Line *instance = 0;
60 
61  try {
62  // Parse actuals and check their number.
63  parseActuals(statement);
64  if(formals.size() != actuals.size()) {
65  throw ParseError("LineTemplate::makeInstance()",
66  "Inconsistent number of macro arguments.");
67  }
68 
69  // Expand the LINE macro in token form.
70  body.start();
71  Token token = body.readToken();
72  SimpleStatement expansion(getOpalName(), 1);
73  while(! token.isEOF()) {
74  bool found = false;
75  if(token.isWord()) {
76  std::string word = token.getWord();
77 
78  for(std::vector<std::string>::size_type i = 0;
79  i < formals.size(); i++) {
80  if(word == formals[i]) {
81  std::vector<Token> act = actuals[i];
82  for(Token t : act) {
83  expansion.append(t);
84  }
85  found = true;
86  break;
87  }
88  }
89  }
90  if(! found) expansion.append(token);
91  token = body.readToken();
92  }
93 
94  // Parse the modified line.
95  Line *model = dynamic_cast<Line *>(OpalData::getInstance()->find("LINE"));
96  instance = model->clone(name);
97  instance->copyAttributes(*this);
98  expansion.start();
99  instance->parse(expansion);
100  } catch(...) {
101  delete instance;
102  throw;
103  }
104 
105  return instance;
106 }
107 
108 
110  // Should not be called.
111  return 0;
112 }
113 
114 
116  parseFormals(statement);
117  bool isLine = statement.keyword("LINE");
118  PAssert(isLine);
119 
120  // Store the template list.
121  Token token = statement.getCurrent();
122  if(token.isDel('=')) {
123  body.append(token);
124  int level = 0;
125  while(! statement.atEnd()) {
126  token = statement.getCurrent();
127  if(token.isDel('(')) {
128  level++;
129  } else if(token.isDel(')')) {
130  body.append(token);
131  if(--level == 0) break;
132  }
133  body.append(token);
134  }
135  } else {
136  throw ParseError("LineTemplate::parseTemplate()",
137  "Equals sign '=' expected.");
138  }
139 }
#define PAssert(c)
Definition: PAssert.h:102
const std::string name
The base class for all OPAL objects.
Definition: Object.h:48
const std::string & getOpalName() const
Return object name.
Definition: Object.cpp:281
void copyAttributes(const Object &)
Copy attributes from another object.
Definition: Object.cpp:54
Object * find(const std::string &name)
Find entry.
Definition: OpalData.cpp:565
static OpalData * getInstance()
Definition: OpalData.cpp:195
Interface for abstract language parser.
Definition: Parser.h:31
A simple input statement in token form.
Interface for statements.
Definition: Statement.h:38
Token & getCurrent()
Return current token and skip it.
Definition: Statement.cpp:74
void append(const Token &)
Append a token.
Definition: Statement.cpp:45
bool keyword(const char *s)
Test for keyword.
Definition: Statement.cpp:121
bool atEnd() const
Test for end of command.
Definition: Statement.cpp:50
void start()
Return to start.
Definition: Statement.cpp:180
Representation of a single input token.
Definition: Token.h:33
bool isDel(char del) const
Test for delimiter.
Definition: Token.cpp:92
bool isWord() const
Test for word.
Definition: Token.cpp:127
bool isEOF() const
Test for end of file.
Definition: Token.cpp:107
std::string getWord() const
Return word value.
Definition: Token.cpp:190
Abstract interface for a stream of input tokens.
Definition: TokenStream.h:33
Parse exception.
Definition: ParseError.h:32
Definition: Line.h:32
virtual void parse(Statement &stat)
Parse the line object.
Definition: Line.cpp:150
virtual Line * clone(const std::string &name)
Make clone.
Definition: Line.cpp:117
MacroStream body
Definition: LineTemplate.h:71
virtual ~LineTemplate()
void parseTemplate(TokenStream &is, Statement &stat)
Parse the line template.
virtual Object * makeInstance(const std::string &name, Statement &stat, const Parser *)
Make line instance.
virtual LineTemplate * clone(const std::string &name)
Make clone.
virtual Object * makeTemplate(const std::string &, TokenStream &, Statement &)
Make a line template.
Abstract base class for macros.
Definition: Macro.h:34
virtual void parseFormals(Statement &)
Parse formal arguments.
Definition: Macro.cpp:100
std::vector< std::string > formals
The formal argument list.
Definition: Macro.h:78
std::vector< std::vector< Token > > actuals
The actual argument list.
Definition: Macro.h:82
virtual void parseActuals(Statement &)
Parse actual arguments.
Definition: Macro.cpp:64
void append(Token &)
Append a token to the stream.
Definition: MacroStream.cpp:36
void start()
Reset stream to start.
Definition: MacroStream.cpp:53
virtual Token readToken()
Read a token from the stream.
Definition: MacroStream.cpp:41