OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
SequenceTemplate.cpp
Go to the documentation of this file.
1 // ------------------------------------------------------------------------
2 // $RCSfile: SequenceTemplate.cpp,v $
3 // ------------------------------------------------------------------------
4 // $Revision: 1.2 $
5 // ------------------------------------------------------------------------
6 // Copyright: see Copyright.readme
7 // ------------------------------------------------------------------------
8 //
9 // Class: SequenceTemplate
10 // The class for storage of OPAL beam sequences with arguments.
11 //
12 // ------------------------------------------------------------------------
13 //
14 // $Date: 2000/03/29 10:41:41 $
15 // $Author: opal $
16 //
17 // ------------------------------------------------------------------------
18 
19 #include "Lines/SequenceTemplate.h"
21 #include "Lines/Sequence.h"
22 #include "Lines/SequenceParser.h"
23 #include "OpalParser/MacroStream.h"
24 #include "OpalParser/OpalParser.h"
25 #include "Parser/SimpleStatement.h"
26 #include "Utilities/ParseError.h"
27 #include <vector>
28 #include <cassert>
29 
30 // Class SequenceTemplate
31 // ------------------------------------------------------------------------
32 
34  Macro(0, "SEQUENCE",
35  "This object defines a beamsequence list with arguments.\n"
36  "\t<name>(<args>);"),
37  body("SEQUENCE")
38 {}
39 
40 
41 SequenceTemplate::SequenceTemplate(const std::string &name, Object *parent):
42  Macro(name, parent), body(name)
43 {}
44 
45 
47 {}
48 
49 
51  throw ParseError("SequenceTemplate::clone()",
52  "You cannot use this object without attributes.");
53 }
54 
55 
57 (const std::string &name, Statement &statement, const Parser *) {
58  MacroStream *expansion = 0;
59  Sequence *instance = 0;
60 
61  try {
62  // Parse actuals and check their number.
63  parseActuals(statement);
64  if(formals.size() != actuals.size()) {
65  throw ParseError("MacroCmd::makeInstance()",
66  "Inconsistent number of macro arguments.");
67  }
68 
69  // Expand the SEQUENCE macro in token form.
70  body.start();
71  Token token = body.readToken();
72  expansion = new MacroStream(getOpalName());
73  while(! token.isEOF()) {
74  bool found = false;
75  if(token.isWord()) {
76  std::string word = token.getWord();
77  for(std::vector<std::string>::size_type i = 0;
78  i < formals.size(); i++) {
79  if(word == formals[i]) {
80  std::vector<Token> act = actuals[i];
81  for(Token t : act) {
82  expansion->append(t);
83  }
84  found = true;
85  break;
86  }
87  }
88  }
89  if(! found) expansion->append(token);
90  token = body.readToken();
91  }
92 
93  // Make the instance and parse it.
94  Sequence *model = dynamic_cast<Sequence *>(OpalData::getInstance()->find("SEQUENCE"));
95  instance = model->clone(name);
96  instance->copyAttributes(*this);
97  expansion->start();
98  SequenceParser parser(instance);
99  parser.run(&*expansion);
100  } catch(...) {
101  delete expansion;
102  delete instance;
103  throw;
104  }
105 
106  return instance;
107 }
108 
109 
111 (const std::string &, TokenStream &, Statement &) {
112  // Should not be called.
113  return 0;
114 }
115 
116 
118  // Save the formals.
119  parseFormals(statement);
120  assert(statement.keyword("SEQUENCE"));
121 
122  // Parse the sequence header.
123  Object::parse(statement);
124 
125  // Save the sequence body.
126  Token token = is.readToken();
127 
128  // Read through ENDSEQUENCE.
129  while(! token.isEOF()) {
130  body.append(token);
131  if(token.isKey("ENDSEQUENCE")) {
132  // Read remainder up to ';'.
133  token = is.readToken();
134  while(! token.isEOF()) {
135  body.append(token);
136  if(token.isDel(';')) break;
137  token = is.readToken();
138  }
139  break;
140  }
141  token = is.readToken();
142  }
143 }
virtual ~SequenceTemplate()
bool isEOF() const
Test for end of file.
Definition: Token.cpp:107
bool keyword(const char *s)
Test for keyword.
Definition: Statement.cpp:123
Parse exception.
Definition: ParseError.h:32
void copyAttributes(const Object &)
Copy attributes from another object.
Definition: Object.cpp:57
void parseTemplate(TokenStream &, Statement &)
Parse the sequence template.
Abstract interface for a stream of input tokens.
Definition: TokenStream.h:33
bool isWord() const
Test for word.
Definition: Token.cpp:127
An ``archetype&#39;&#39; for a SEQUENCE with arguments.
Interface for abstract language parser.
Definition: Parser.h:31
static OpalData * getInstance()
Definition: OpalData.cpp:209
virtual Token readToken()=0
Read single token from stream.
virtual void parseFormals(Statement &)
Parse formal arguments.
Definition: Macro.cpp:100
Interface for statements.
Definition: Statement.h:38
virtual Object * makeTemplate(const std::string &name, TokenStream &, Statement &)
Make a sequence template.
Representation of a single input token.
Definition: Token.h:33
void start()
Reset stream to start.
Definition: MacroStream.cpp:53
The SEQUENCE definition.
Definition: Sequence.h:38
void append(Token &)
Append a token to the stream.
Definition: MacroStream.cpp:36
The parser for SEQUENCE members.
virtual Sequence * clone(const std::string &name)
Make clone.
Definition: Sequence.cpp:98
virtual void run() const
Read current stream.
Definition: OpalParser.cpp:601
An input buffer for macro commands.
Definition: MacroStream.h:31
Abstract base class for macros.
Definition: Macro.h:34
Object * find(const std::string &name)
Find entry.
Definition: OpalData.cpp:618
The base class for all OPAL objects.
Definition: Object.h:48
virtual SequenceTemplate * clone(const std::string &name)
Make clone.
virtual Object * makeInstance(const std::string &name, Statement &, const Parser *)
Make line instance.
const std::string name
bool isKey(const char *key) const
Test for keyword.
Definition: Token.cpp:137
bool isDel(char del) const
Test for delimiter.
Definition: Token.cpp:92
virtual void parse(Statement &)
Parse the object.
Definition: Object.cpp:100
std::string getWord() const
Return word value.
Definition: Token.cpp:190