OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
OPAL
SequenceTemplate.cpp
Go to the documentation of this file.
1 //
2 // Class SequenceTemplate
3 //
4 // An ``archetype'' for a SEQUENCE with arguments.
5 // The model is stored in form of a MacroStream. A call to the macro
6 // sequence is expanded by first replacing the arguments, and then parsing
7 // the resulting stream as a SEQUENCE 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 
25 #include "Lines/SequenceTemplate.h"
26 
27 #include "Utility/PAssert.h"
28 
30 #include "Lines/Sequence.h"
31 #include "Lines/SequenceParser.h"
32 #include "OpalParser/MacroStream.h"
33 #include "OpalParser/OpalParser.h"
34 #include "Parser/SimpleStatement.h"
35 #include "Utilities/ParseError.h"
36 #include <vector>
37 
38 // Class SequenceTemplate
39 // ------------------------------------------------------------------------
40 
42  Macro(0, "SEQUENCE",
43  "This object defines a beamsequence list with arguments.\n"
44  "\t<name>(<args>);"),
45  body("SEQUENCE")
46 {}
47 
48 
49 SequenceTemplate::SequenceTemplate(const std::string &name, Object *parent):
50  Macro(name, parent), body(name)
51 {}
52 
53 
55 {}
56 
57 
58 SequenceTemplate *SequenceTemplate::clone(const std::string &/*name*/) {
59  throw ParseError("SequenceTemplate::clone()",
60  "You cannot use this object without attributes.");
61 }
62 
63 
65 (const std::string &name, Statement &statement, const Parser *) {
66  MacroStream *expansion = 0;
67  Sequence *instance = 0;
68 
69  try {
70  // Parse actuals and check their number.
71  parseActuals(statement);
72  if(formals.size() != actuals.size()) {
73  throw ParseError("MacroCmd::makeInstance()",
74  "Inconsistent number of macro arguments.");
75  }
76 
77  // Expand the SEQUENCE macro in token form.
78  body.start();
79  Token token = body.readToken();
80  expansion = new MacroStream(getOpalName());
81  while(! token.isEOF()) {
82  bool found = false;
83  if(token.isWord()) {
84  std::string word = token.getWord();
85  for(std::vector<std::string>::size_type i = 0;
86  i < formals.size(); i++) {
87  if(word == formals[i]) {
88  std::vector<Token> act = actuals[i];
89  for(Token t : act) {
90  expansion->append(t);
91  }
92  found = true;
93  break;
94  }
95  }
96  }
97  if(! found) expansion->append(token);
98  token = body.readToken();
99  }
100 
101  // Make the instance and parse it.
102  Sequence *model = dynamic_cast<Sequence *>(OpalData::getInstance()->find("SEQUENCE"));
103  instance = model->clone(name);
104  instance->copyAttributes(*this);
105  expansion->start();
106  SequenceParser parser(instance);
107  parser.run(&*expansion);
108  } catch(...) {
109  delete expansion;
110  delete instance;
111  throw;
112  }
113 
114  return instance;
115 }
116 
117 
119 (const std::string &, TokenStream &, Statement &) {
120  // Should not be called.
121  return 0;
122 }
123 
124 
126  // Save the formals.
127  parseFormals(statement);
128  bool isSequence = statement.keyword("SEQUENCE");
129  PAssert(isSequence);
130 
131  // Parse the sequence header.
132  Object::parse(statement);
133 
134  // Save the sequence body.
135  Token token = is.readToken();
136 
137  // Read through ENDSEQUENCE.
138  while(! token.isEOF()) {
139  body.append(token);
140  if(token.isKey("ENDSEQUENCE")) {
141  // Read remainder up to ';'.
142  token = is.readToken();
143  while(! token.isEOF()) {
144  body.append(token);
145  if(token.isDel(';')) break;
146  token = is.readToken();
147  }
148  break;
149  }
150  token = is.readToken();
151  }
152 }
#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
virtual void parse(Statement &)
Parse the object.
Definition: Object.cpp:97
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
Interface for statements.
Definition: Statement.h:38
bool keyword(const char *s)
Test for keyword.
Definition: Statement.cpp:121
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
bool isKey(const char *key) const
Test for keyword.
Definition: Token.cpp:137
Abstract interface for a stream of input tokens.
Definition: TokenStream.h:33
virtual Token readToken()=0
Read single token from stream.
Parse exception.
Definition: ParseError.h:32
virtual Sequence * clone(const std::string &name)
Make clone.
Definition: Sequence.cpp:97
The parser for SEQUENCE members.
virtual SequenceTemplate * clone(const std::string &name)
Make clone.
void parseTemplate(TokenStream &, Statement &)
Parse the sequence template.
virtual Object * makeInstance(const std::string &name, Statement &, const Parser *)
Make line instance.
virtual ~SequenceTemplate()
virtual Object * makeTemplate(const std::string &name, TokenStream &, Statement &)
Make a sequence 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
An input buffer for macro commands.
Definition: MacroStream.h:31
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
virtual void run() const
Read current stream.
Definition: OpalParser.cpp:602