Frobby  0.9.5
Scanner.h
Go to the documentation of this file.
1 /* Frobby: Software for monomial ideal computations.
2  Copyright (C) 2007 Bjarke Hammersholt Roune (www.broune.com)
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program. If not, see http://www.gnu.org/licenses/.
16 */
17 #ifndef SCANNER_GUARD
18 #define SCANNER_GUARD
19 
20 #include "VarNames.h"
21 #include <string>
22 
23 class IOHandler;
24 
50 class Scanner {
51 public:
58  Scanner(const string& formatName, FILE* in);
59  ~Scanner() {delete[] _tmpString;}
60 
61  const string& getFormat() const {return _formatName;}
62  void setFormat(const string& format) {_formatName = format;}
63  auto_ptr<IOHandler> createIOHandler() const;
64 
67  bool match(char c);
68 
70  bool matchEOF();
71 
74  void expect(char expected);
75 
78  void expect(char a, char b);
79 
82  void expect(const char* str);
83 
86  void expect(const string& str) {expect(str.c_str());}
87 
89  void expectEOF();
90 
92  void expectIntegerNoSign();
93 
95  void readInteger(mpz_class& integer);
96 
98  void readIntegerNoSign(string& str);
99 
101  void readIntegerNoSign(mpz_class& str);
102 
106  void readIntegerAndNegativeAsZero(mpz_class& integer);
107 
111  void readIntegerAndNegativeAsZero(std::string& integer);
112 
116  void readSizeT(size_t& size);
117 
120  const char* readIdentifier();
121 
123  void readIdentifier(string& str);
124 
129  size_t readVariable(const VarNames& names);
130 
133  bool peekIdentifier();
134 
137  bool peekWhite() {return isspace(peek());}
138 
141  bool peek(char character);
142 
145  unsigned int getLineNumber() const {return _lineNumber;}
146 
148  int peek() {return _char;}
149 
152  inline void eatWhite();
153 
154 private:
156  size_t readIntegerString();
157 
159  size_t readIntegerStringNoSign();
160 
161  void parseInteger(mpz_class& integer, size_t size);
162 
163  void errorExpectTwo(char a, char b, int got);
164  void errorExpectOne(char expected, int got);
165  void errorReadVariable(const char* name);
166  void errorReadIdentifier();
167 
168  void reportErrorUnexpectedToken(const string& expected, int got);
169  void reportErrorUnexpectedToken(const string& expected, const string& got);
170 
171  inline int getChar();
172  void growTmpString();
173  int readBuffer();
174 
175  mpz_class _integer;
176  FILE* _in;
177  unsigned long _lineNumber;
178  int _char; // next character on stream
179 
180  char* _tmpString;
182 
183  string _formatName;
184 
185  vector<char> _buffer;
186  vector<char>::iterator _bufferPos;
187 };
188 
189 
190 
191 inline void Scanner::readIdentifier(string& str) {
192  eatWhite();
193  if (!isalpha(peek()))
195  str.clear();
196  do {
197  str += static_cast<char>(getChar());
198  } while (isalnum(peek()) || peek() == '_');
199 }
200 
201 inline size_t Scanner::readVariable(const VarNames& names) {
202  const char* name = readIdentifier();
203  size_t var = names.getIndex(name);
204  if (var == VarNames::invalidIndex)
205  errorReadVariable(name);
206  return var;
207 }
208 
209 
210 inline bool Scanner::matchEOF() {
211  eatWhite();
212  return peek() == EOF;
213 }
214 
215 inline bool Scanner::match(char c) {
216  eatWhite();
217  if (c == peek()) {
218  getChar();
219  return true;
220  } else
221  return false;
222 }
223 
224 inline void Scanner::expect(char a, char b) {
225  eatWhite();
226  int got = getChar();
227  if (got != a && got != b)
228  errorExpectTwo(a, b, got);
229 }
230 
231 inline void Scanner::expect(char expected) {
232  eatWhite();
233  int got = getChar();
234  if (got != expected)
235  errorExpectOne(expected, got);
236 }
237 
238 inline void Scanner::readInteger(mpz_class& integer) {
239  size_t size = readIntegerString();
240  parseInteger(integer, size);
241 }
242 
245 }
246 
247 inline void Scanner::readIntegerNoSign(mpz_class& integer) {
249  integer = _tmpString;
250 }
251 
252 inline void Scanner::readIntegerNoSign(string& integer) {
254  integer = _tmpString;
255 }
256 
257 inline bool Scanner::peekIdentifier() {
258  eatWhite();
259  return isalpha(peek());
260 }
261 
262 inline bool Scanner::peek(char character) {
263  eatWhite();
264  return peek() == character;
265 }
266 
267 inline void Scanner::eatWhite() {
268  while (isspace(peek()))
269  getChar();
270 }
271 
272 inline int Scanner::getChar() {
273  if (_char == '\n')
274  ++_lineNumber;
275  int oldChar = _char;
276  if (_bufferPos == _buffer.end())
277  _char = readBuffer();
278  else {
279  _char = *_bufferPos;
280  ++_bufferPos;
281  }
282  return oldChar;
283 }
284 
285 #endif
An IOHandler implements input and output for some format in such a way that client code does not need...
Definition: IOHandler.h:41
This class offers an input interface which is more convenient and for some purposes more efficient th...
Definition: Scanner.h:50
const string & getFormat() const
Definition: Scanner.h:61
auto_ptr< IOHandler > createIOHandler() const
Definition: Scanner.cpp:42
void expect(const string &str)
Require the following characters to be equal to str.
Definition: Scanner.h:86
mpz_class _integer
Definition: Scanner.h:175
int peek()
Returns the next character or EOF.
Definition: Scanner.h:148
size_t readIntegerString()
Returns the size of the string.
Definition: Scanner.cpp:101
void growTmpString()
Definition: Scanner.cpp:243
void readIntegerNoSign(string &str)
Read an arbitrary-precision integer.
Definition: Scanner.h:252
char * _tmpString
Definition: Scanner.h:180
size_t _tmpStringCapacity
Definition: Scanner.h:181
void parseInteger(mpz_class &integer, size_t size)
Definition: Scanner.cpp:150
string _formatName
Definition: Scanner.h:183
Scanner(const string &formatName, FILE *in)
Construct a Scanner object.
Definition: Scanner.cpp:28
void reportErrorUnexpectedToken(const string &expected, int got)
Definition: Scanner.cpp:285
FILE * _in
Definition: Scanner.h:176
void eatWhite()
Reads past any whitespace, where whitespace is defined by the standard function isspace().
Definition: Scanner.h:267
~Scanner()
Definition: Scanner.h:59
int _char
Definition: Scanner.h:178
vector< char >::iterator _bufferPos
Definition: Scanner.h:186
vector< char > _buffer
Definition: Scanner.h:185
void errorReadIdentifier()
Definition: Scanner.cpp:274
void expectEOF()
Require that there is no more input.
Definition: Scanner.cpp:77
bool peekWhite()
Returns true if the next character is whitespace.
Definition: Scanner.h:137
void readIntegerAndNegativeAsZero(mpz_class &integer)
Read an integer and set it to zero if it is negative.
Definition: Scanner.cpp:171
void expectIntegerNoSign()
Read an arbitrary-precision integer.
Definition: Scanner.h:243
unsigned long _lineNumber
Definition: Scanner.h:177
void expect(char expected)
Require the next character to be equal to expected.
Definition: Scanner.h:231
const char * readIdentifier()
The returned string is only valid until the next method on this object gets called.
Definition: Scanner.cpp:255
bool peekIdentifier()
Skips whitespace and returns true if the next token is an identifier.
Definition: Scanner.h:257
void readIntegerAndNegativeAsZero(std::string &integer)
Read an integer and set it to zero if it is negative.
void errorExpectTwo(char a, char b, int got)
Definition: Scanner.cpp:87
unsigned int getLineNumber() const
Returns the number of newlines seen.
Definition: Scanner.h:145
void readSizeT(size_t &size)
Reads a size_t, where the representable range of that type determines when the number is too big.
Definition: Scanner.cpp:205
int readBuffer()
Definition: Scanner.cpp:304
size_t readVariable(const VarNames &names)
Reads an identifier and returns the index of that identifier as the index of a variable in names.
Definition: Scanner.h:201
bool matchEOF()
Return true if no more input.
Definition: Scanner.h:210
void readInteger(mpz_class &integer)
Read an arbitrary-precision integer.
Definition: Scanner.h:238
void errorExpectOne(char expected, int got)
Definition: Scanner.cpp:94
void setFormat(const string &format)
Definition: Scanner.h:62
void errorReadVariable(const char *name)
Definition: Scanner.cpp:278
bool match(char c)
Return true if the next character is c, and in that case skip past it.
Definition: Scanner.h:215
int getChar()
Definition: Scanner.h:272
size_t readIntegerStringNoSign()
Returns the size of the string.
Definition: Scanner.cpp:127
Defines the variables of a polynomial ring and facilities IO involving them.
Definition: VarNames.h:40
static const size_t invalidIndex
Returns a fixed variable offset that is always invalid.
Definition: VarNames.h:100
size_t getIndex(const string &name) const
Returns VarNames::invalidIndex() if name is not known.
Definition: VarNames.cpp:83