Ocean
Loading...
Searching...
No Matches
Scanner.h
Go to the documentation of this file.
1/*
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8#ifndef META_OCEAN_IO_SCANNER_H
9#define META_OCEAN_IO_SCANNER_H
10
11#include "ocean/io/IO.h"
12
13#include "ocean/base/Memory.h"
14
15#include "ocean/math/Math.h"
16
17#include <array>
18#include <fstream>
19#include <istream>
20#include <sstream>
21
22namespace Ocean
23{
24
25namespace IO
26{
27
28/**
29 * This class implements a simple scanner.
30 * @ingroup io
31 */
32class OCEAN_IO_EXPORT Scanner
33{
34 public:
35
36 /**
37 * Definition of an invalid keyword or symbol id.
38 */
39 static constexpr uint32_t invalidId = uint32_t(-1);
40
41 /**
42 * This class implements a token for the scanner.
43 */
44 class OCEAN_IO_EXPORT Token final
45 {
46 public:
47
48 /**
49 * Definition of different token types.
50 */
51 enum Type : uint32_t
52 {
53 /// Invalid token.
54 TOKEN_INVALID = 0u,
55 /// Character token.
57 /// End of file token.
59 /// Identifier token.
61 /// Line token.
63 /// Number token.
65 /// Integer token.
67 /// Keyword token.
69 /// String token.
71 /// Symbol token.
72 TOKEN_SYMBOL
73 };
74
75 public:
76
77 /**
78 * Creates an invalid token.
79 */
80 Token() = default;
81
82 /**
83 * Creates a new token with given data and type.
84 * @param data Token data
85 * @param type Token type
86 */
87 Token(std::string&& data, const Type type);
88
89 /**
90 * Creates a new token with given data and type.
91 * @param data Token data
92 * @param type Token type
93 */
94 Token(const std::string& data, const Type type);
95
96 /**
97 * Creates a new token with given keyword or symbol id.
98 * @param data Raw token data
99 * @param id Keyword or symbol id of the token
100 * @param type Token type
101 */
102 Token(std::string&& data, const uint32_t id, const Type type);
103
104 /**
105 * Creates a new token with given keyword or symbol id.
106 * @param data Raw token data
107 * @param id Keyword or symbol id of the token
108 * @param type Token type
109 */
110 Token(const std::string& data, const uint32_t id, const Type type);
111
112 /**
113 * Returns the type of the token.
114 * @return Token type
115 */
116 inline Type type() const;
117
118 /**
119 * Returns whether this token is of a specific type.
120 * @param type The type to check
121 * @return True, if so
122 */
123 inline bool isType(const Type type) const;
124
125 /**
126 * Returns whether this token holds a character.
127 * @return True, if so
128 */
129 inline bool isCharacter() const;
130
131 /**
132 * Returns whether this token holds an identifier.
133 * @return True, if so
134 */
135 inline bool isIdentifier() const;
136
137 /**
138 * Returns whether this token holds an integer.
139 * @return True, if so
140 */
141 inline bool isInteger() const;
142
143 /**
144 * Returns whether this token holds a remaining line.
145 * @return True, if so
146 */
147 inline bool isLine() const;
148
149 /**
150 * Returns whether this token holds a number.
151 * @return True, if so
152 */
153 inline bool isNumber() const;
154
155 /**
156 * Returns whether this token holds an integer or a number.
157 * @return True, if so
158 */
159 inline bool isIntegerOrNumber() const;
160
161 /**
162 * Returns whether this token holds a keyword.
163 * @return True, if so
164 */
165 inline bool isKeyword() const;
166
167 /**
168 * Returns whether this token holds a special keyword.
169 * @param keyword The keyword id to check
170 * @return True, if so
171 */
172 bool isKeyword(const uint32_t keyword) const;
173
174 /**
175 * Returns whether this token holds a string.
176 * @return True, if so
177 */
178 inline bool isString() const;
179
180 /**
181 * Returns whether this token holds a symbol.
182 * @return True, if so
183 */
184 inline bool isSymbol() const;
185
186 /**
187 * Returns whether this token holds a special symbol.
188 * @param symbol The symbol id to check
189 * @return True, if so
190 */
191 bool isSymbol(const uint32_t symbol) const;
192
193 /**
194 * Returns whether this token holds an end of file.
195 * @return True, if so
196 */
197 inline bool isEndOfFile() const;
198
199 /**
200 * Returns the character value of this token.
201 * @return Character value
202 */
203 uint8_t character() const;
204
205 /**
206 * Returns the identifier value of this token.
207 * @return Identifier value
208 */
209 const std::string& identifier() const;
210
211 /**
212 * Returns the integer value of this token.
213 * @return Integer value, with range (-infinity, infinity)
214 */
215 int32_t integer() const;
216
217 /**
218 * Returns the floating point value of this token.
219 * @return Floating point value, with range (-infinity, infinity)
220 */
221 double number() const;
222
223 /**
224 * Returns the integer or floating point value of this token.
225 * @return Integer or floating point value, as floating point value, with range (-infinity, infinity)
226 */
227 double integerOrNumber() const;
228
229 /**
230 * Returns the remaining line of this token.
231 * @return Line value
232 */
233 const std::string& line() const;
234
235 /**
236 * Returns the id of the keyword of this token.
237 * @return Keyword id
238 */
239 uint32_t keyword() const;
240
241 /**
242 * Returns the id of the symbol of this token.
243 * @return Symbol id
244 */
245 uint32_t symbol() const;
246
247 /**
248 * Returns the string value of this token.
249 * @return The token's string value
250 */
251 const std::string& string() const;
252
253 /**
254 * Returns the string value of this token and invalidates the token.
255 * @return The token's string value
256 */
257 std::string moveString();
258
259 /**
260 * Returns the raw data of the token.
261 * @return Raw data
262 */
263 inline const std::string& raw() const;
264
265 /**
266 * Returns whether the token is valid.
267 * @return True, if so
268 */
269 explicit inline operator bool() const;
270
271 protected:
272
273 /// Holds the type of the token.
274 Type type_ = TOKEN_INVALID;
275
276 /// Holds the id of the keyword or symbol, if any.
277 uint32_t id_ = invalidId;
278
279 /// Holds the data of the token.
280 std::string data_;
281 };
282
283 protected:
284
285 /**
286 * Definition of an unordered map mapping strings to ids.
287 */
288 using IdMap = std::unordered_map<std::string, uint32_t>;
289
290 /**
291 * Definition of an unordered set holding line remark symbols.
292 */
293 using LineRemarks = std::unordered_set<std::string>;
294
295 /**
296 * Definition of an unordered map mapping begin remark symbols to end remark symbols.
297 */
298 using ScopeRemarks = std::unordered_map<std::string, std::string>;
299
300 /**
301 * Definition of a character table.
302 */
303 using CharTable = std::array<uint16_t, 256>;
304
305 /**
306 * Definition of first character types.
307 */
308 enum FirstChar : uint16_t
309 {
310 /// Invalid.
311 CHAR_INVALID = 0,
312 /// Character.
313 CHAR_CHARACTER = 1,
314 /// Identifier.
315 CHAR_IDENTIFIER = 2,
316 /// Number.
317 CHAR_NUMBER = 4,
318 /// Integer.
319 CHAR_INTEGER = 8,
320 /// Keyword.
321 CHAR_KEYWORD = 16,
322 /// String.
323 CHAR_STRING = 32,
324 /// Symbol.
325 CHAR_SYMBOL = 64,
326 /// Remark.
327 CHAR_REMARK = 128,
328 /// White space.
329 CHAR_SPACE = 256
330 };
331
332 public:
333
334 /**
335 * Creates a new scanner using a stream as input.
336 * @param stream The stream to be used as input
337 * @param progress Optional resulting scanner progress in percent, with range [0, 1]
338 * @param cancel Optional scanner cancel flag
339 */
340 explicit Scanner(const std::shared_ptr<std::istream>& stream, float* progress = nullptr, bool* cancel = nullptr);
341
342 /**
343 * Creates a new scanner using a file or a memory buffer as input.
344 * @param filename The name of the file to be used as input, `buffer` must be empty
345 * @param buffer The buffer to be used as input, `filename` must be empty
346 * @param progress Optional resulting scanner progress in percent, with range [0, 1]
347 * @param cancel Optional scanner cancel flag
348 */
349 inline Scanner(const std::string& filename, const std::string& buffer, float* progress = nullptr, bool* cancel = nullptr);
350
351 /**
352 * Creates a new scanner using a file or a memory buffer as input.
353 * @param filename The name of the file to be used as input, `buffer` must be empty
354 * @param buffer The buffer to be used as input, `filename` must be empty
355 * @param progress Optional resulting scanner progress in percent, with range [0, 1]
356 * @param cancel Optional scanner cancel flag
357 */
358 inline Scanner(const std::string& filename, std::string&& buffer, float* progress = nullptr, bool* cancel = nullptr);
359
360 /**
361 * Destructs a scanner.
362 */
363 virtual ~Scanner();
364
365 /**
366 * Returns the recent token.
367 * @return Recent token
368 */
369 const Token& token();
370
371 /**
372 * Returns a line token starting at the current position.
373 * A line token does not handle remarks.
374 * @return Line token
375 */
376 const Token& lineToken();
377
378 /**
379 * Returns the recent token and pops it afterwards.
380 * @return Recent token.
381 */
383
384 /**
385 * Returns a lookahead to the next token.
386 * @return Next token
387 */
388 const Token& look();
389
390 /**
391 * Pops the recent token.
392 */
393 void pop();
394
395 /**
396 * Returns the recent line.
397 * @return Recent line
398 */
399 inline size_t line() const;
400
401 /**
402 * Returns the recent column.
403 * @return Recent column
404 */
405 inline size_t column() const;
406
407 /**
408 * Returns the position of the scanner.
409 * @return Position of the scanner in characters
410 */
411 size_t position() const;
412
413 /**
414 * Returns the size of the scanner.
415 * @return Size of the scanner in characters
416 */
417 size_t size() const;
418
419 /**
420 * Returns the name of the input file, if the input is a file.
421 * @return The scanner's input filename, empty if the input was a buffer
422 */
423 inline const std::string& filename() const;
424
425 /**
426 * Returns whether the scanner is valid and ready to use.
427 * @return True, if so
428 */
429 inline bool isValid() const;
430
431 /**
432 * Finds the next token in a given string starting from a specified position.
433 * A token is enclosed by white characters or by the borders of the given string, the length of the given string is explicitly defined by the parameter 'size'.
434 * @param pointer The pointer to the string in which the next token is to be found, must be valid
435 * @param size The length of the given string in characters, with range [1, infinity)
436 * @param start The first character within the given string that defines the first possible character of the token, with range [0, size - 1]
437 * @param tokenStart The resulting start location within the given string of the found token, with range [start, strlen(pointer) - 1]
438 * @param tokenLength The resulting length of the found token, with range [1, strlen(pointer) - start]
439 * @return True, if a second token may follow; False, if the token is the last token
440 */
441 static bool findNextToken(const char* pointer, const size_t size, const size_t start, size_t& tokenStart, size_t& tokenLength);
442
443 /**
444 * Finds the next token in a given string starting from a specified position.
445 * A token is enclosed by white characters or by the borders of the given string, the end is identified by a null character.
446 * @param pointer The pointer to the string in which the next token is to be found, can be nullptr
447 * @param start The first character within the given string that defines the first possible character of the token, with range [0, strlen(pointer)]
448 * @param tokenStart The resulting start location within the given string of the found token, with range [start, strlen(pointer) - 1]
449 * @param tokenLength The resulting length of the found token, with range [1, strlen(pointer) - start]
450 * @return True, if a second token may follow; False, if the token is the last token
451 */
452 static bool findNextToken(const char* pointer, const size_t start, size_t& tokenStart, size_t& tokenLength);
453
454 /**
455 * Returns whether a given character is a white space character.
456 * A white space character can be one of the following:
457 * <pre>
458 * ' ', '\\t', '\\n', or '\\r'
459 * </pre>
460 * @param character The character to be checked
461 * @return True, if so
462 */
463 static inline bool isWhitespace(const char& character);
464
465 protected:
466
467 /**
468 * Creates a new scanner.
469 * The scanner may forward an entire progress state, if the pointer value is defined.<br>
470 * Beware: Make sure that the value exists during the whole scanning time!<br>
471 * Further, the scanner may be canceled by an explicit flag.<br>
472 * In the case the scanner is canceled an end of file token is returned.<br>
473 * Beware: As for the progress value, also the cancel object must exist during the whole scanning progress, if provided.
474 * @param progress Optional progress parameter to forward the scanning progress with range [0, 1], use nullptr if the progress state is not necessary
475 * @param cancel Optional cancel state to cancel the scanner progress by setting the flag to 'true', use nullptr if the cancel state is not necessary
476 */
477 Scanner(float* progress, bool* cancel);
478
479 /**
480 * Returns one character.
481 * @param offset Offset to the recent position
482 * @return Character
483 */
484 uint8_t get(const size_t offset = 0);
485
486 /**
487 * Returns data of a specified size starting at the recent position.
488 * Beware: Make sure that enough pending buffer is available
489 * @param size Size of the data to receive
490 * @return Requested data
491 */
492 std::string data(const size_t size) const;
493
494 /**
495 * Returns data of a specified size starting at the offset position.
496 * Beware: Make sure that enough pending buffer is available
497 * @param offset Start position relative to the current position
498 * @param size Size of the data to receive
499 * @return Requested data
500 */
501 std::string data(const size_t offset, const size_t size) const;
502
503 /**
504 * Consumes one or more character.
505 * @param chars Number of characters to consume
506 */
507 void consume(const size_t chars = 1);
508
509 /**
510 * Refills the intermediate buffer.
511 * @return True, if the buffer could be refilled with new characters
512 */
514
515 /**
516 * Returns the keyword id of a given string.
517 * @param data Data to convert to a keyword
518 * @return Id of the identifier, otherwise invalidId
519 */
520 uint32_t keywordId(const std::string& data) const;
521
522 /**
523 * Returns the symbol id of a given string.
524 * @param data Data to convert to a symbol
525 * @return Id of the symbol, otherwise invalidId
526 */
527 uint32_t symbolId(const std::string& data) const;
528
529 /**
530 * Sets whether the keywords are case sensitive or not.
531 * As default all keywords are case sensitive.<br>
532 * Beware: This property has to be set before the first keyword is registered!
533 * @param caseSensitive True, if all keywords will be case sensitive
534 */
535 void setKeywordProperty(const bool caseSensitive);
536
537 /**
538 * Registers a new keyword.
539 * @param keyword New keyword
540 * @param id Id of the keyword
541 */
542 void registerKeyword(const std::string& keyword, const uint32_t id);
543
544 /**
545 * Registers a new symbol.
546 * @param symbol New symbol
547 * @param id Id of the symbol
548 */
549 void registerSymbol(const std::string& symbol, const uint32_t id);
550
551 /**
552 * Registers a line remark symbol.
553 * @param lineRemark Line remark symbol
554 */
555 void registerLineRemark(const std::string& lineRemark);
556
557 /**
558 * Registers a scope remark symbol.
559 * @param begin Begin remark symbol
560 * @param end End remark symbol
561 */
562 void registerScopeRemark(const std::string& begin, const std::string& end);
563
564 /**
565 * Registers a white space character.
566 * @param character White space character to register
567 * @return True, if succeeded
568 */
569 bool registerWhiteSpaceCharacter(const uint8_t character);
570
571 /**
572 * Reads and returns the next token.
573 * @param consumeBytes Determines whether the scanner consume the read characters.
574 * @return New token
575 */
576 virtual Token readToken(const bool consumeBytes = true);
577
578 /**
579 * Reads white space.
580 * @param crossLines Determines whether the white space can be separated over several lines
581 * @return Next not-white-space character
582 */
583 uint8_t readWhiteSpace(bool crossLines = true);
584
585 /**
586 * Discards non white space and jumps to the first white space position.
587 * @return Discarded elements
588 */
589 std::string discardNonWhiteSpace();
590
591 /**
592 * Reads remark comments.
593 * @return True, if a comment was read
594 */
596
597 /**
598 * Reads a line remark comment.
599 * @return True, if a comment was read
600 */
602
603 /**
604 * Reads a scope remark comment.
605 * @return True, if a comment was read
606 */
608
609 /**
610 * Tries to read a character as next token.
611 * @param token Returning token
612 * @param consumeBytes Determines whether the scanner consumes the read characters
613 * @return True, if succeeded
614 */
615 bool readCharacter(Token& token, const bool consumeBytes);
616
617 /**
618 * Tries to read a identifier as next token.
619 * @param token Returning token
620 * @param consumeBytes Determines whether the scanner consumes the read characters
621 * @return True, if succeeded
622 */
623 bool readIdentifier(Token& token, const bool consumeBytes);
624
625 /**
626 * Tries to read an integer as next token.
627 * @param token Returning token
628 * @param consumeBytes Determines whether the scanner consumes the read characters
629 * @return True, if succeeded
630 */
631 bool readInteger(Token& token, const bool consumeBytes);
632
633 /**
634 * Tries to read a keyword as next token.
635 * @param token Returning token
636 * @param consumeBytes Determines whether the scanner consumes the read characters
637 * @return True, if succeeded
638 */
639 bool readKeyword(Token& token, const bool consumeBytes);
640
641 /**
642 * Tries to read a remaining line as next token.
643 * @param token Returning token
644 * @param consumeBytes Determines whether the scanner consumes the read characters
645 * @return True, if succeeded
646 */
647 bool readLine(Token& token, const bool consumeBytes);
648
649 /**
650 * Tries to read a number as next token.
651 * A number may start with a minus or a dot, holds at most one dot, and may end with an exponent, the sign of the exponent is optional but at least one digit must follow it.
652 * The accepted format matches `String::isNumber()`, so that `Token::number()` can always convert the resulting token.
653 * @param token Returning token
654 * @param consumeBytes Determines whether the scanner consumes the read characters
655 * @return True, if succeeded
656 */
657 bool readNumber(Token& token, const bool consumeBytes);
658
659 /**
660 * Tries to read a string as next token.
661 * @param token Returning token
662 * @param consumeBytes Determines whether the scanner consumes the read characters
663 * @return True, if succeeded
664 */
665 bool readString(Token& token, const bool consumeBytes);
666
667 /**
668 * Tries to read a symbol as next token.
669 * @param token Returning token
670 * @param consumeBytes Determines whether the scanner consumes the read characters
671 * @return True, if succeeded
672 */
673 bool readSymbol(Token& token, const bool consumeBytes);
674
675 private:
676
677 /**
678 * Returns one character from the extra buffer.
679 * @param offset Offset inside the recent extra buffer
680 * @return Character
681 */
682 uint8_t getExtra(const size_t offset = 0);
683
684 /**
685 * Refills the extra buffer.
686 * @param minIndex Minimal index of the character needed inside the extra buffer
687 * @return True, if enough characters could be read
688 */
689 bool refillExtraBuffer(const size_t minIndex);
690
691 /**
692 * Creates a file input stream or a string input stream depending on the given input.
693 * @param filename The name of the file to be used as input, `buffer` must be empty
694 * @param buffer The buffer to be used as input, `filename` must be empty
695 */
696 static inline std::shared_ptr<std::istream> createInputStream(const std::string& filename, std::string&& buffer);
697
698 /**
699 * Creates a file input stream or a string input stream depending on the given input.
700 * @param filename The name of the file to be used as input, `buffer` must be empty
701 * @param buffer The buffer to be used as input, `filename` must be empty
702 */
703 static inline std::shared_ptr<std::istream> createInputStream(const std::string& filename, const std::string& buffer);
704
705 protected:
706
707 /// Recent token.
709
710 /// Next token.
712
713 /// The input stream from which the scanner receives the data.
714 std::shared_ptr<std::istream> stream_;
715
716 /// The name of the input file, if the input is a file.
717 std::string filename_;
718
719 /// The scanner's progress in percent, with range [0, 1].
720 float* progress_ = nullptr;
721
722 /// Cancel flag.
723 bool* cancel_ = nullptr;
724
725 /// Local intermediate buffer.
727
728 /// The current pointer inside the intermediate buffer.
729 uint8_t* intermediateBufferPointer_ = nullptr;
730
731 /// Number of remaining characters in the intermediate buffer.
732 size_t intermediateBufferSize_ = 0;
733
734 /// Local extra buffer, used if the intermediate buffer is too small.
736
737 /// Pointer inside the extra buffer.
738 uint8_t* extraBufferPointer_ = nullptr;
739
740 /// Number of remaining characters inside the extra buffer.
741 size_t extraBufferSize_ = 0;
742
743 /// Holds the current line.
744 size_t line_ = 1;
745
746 /// Holds the current column.
747 size_t column_ = 1;
748
749 /// Holds the current position of the scanner.
750 size_t position_ = 0;
751
752 /// Map mapping keyword strings to identifier ids.
754
755 /// Determines whether all keywords are case sensitive.
756 bool keywordsAreCaseSensitive_ = true;
757
758 /// Map mapping symbol strings to symbol ids.
760
761 /// Registered line remarks.
763
764 /// Length of the maximal line remark.
765 size_t maximalLengthLineRemarks_ = 0;
766
767 /// Scope remarks.
769
770 /// Length of the maximal scope remarks.
771 size_t maximalLengthScopeRemarks_ = 0;
772
773 /// Table holding the definition of allowed first characters.
775
776 /// Table holding the definition of allowed following characters.
778
779 /// Table holding the definition of not allowed following characters.
781
782 /// Definition of the minimum intermediate buffer size.
783 static constexpr size_t minBufferSize_ = 2048;
784
785 /// Definition of the maximum intermediate buffer size.
786 static constexpr size_t maxBufferSize_ = 8192;
787};
788
790{
791 return type_;
792}
793
794inline bool Scanner::Token::isType(const Type type) const
795{
796 return type_ == type;
797}
798
800{
801 return type_ == TOKEN_CHARACTER;
802}
803
805{
806 return type_ == TOKEN_IDENTIFIER;
807}
808
809inline bool Scanner::Token::isInteger() const
810{
811 return type_ == TOKEN_INTEGER;
812}
813
814inline bool Scanner::Token::isNumber() const
815{
816 return type_ == TOKEN_NUMBER;
817}
818
820{
821 return type_ == TOKEN_INTEGER || type_ == TOKEN_NUMBER;
822}
823
824inline bool Scanner::Token::isLine() const
825{
826 return type_ == TOKEN_LINE;
827}
828
829inline bool Scanner::Token::isKeyword() const
830{
831 return type_ == TOKEN_KEYWORD;
832}
833
834inline bool Scanner::Token::isString() const
835{
836 return type_ == TOKEN_STRING;
837}
838
839inline bool Scanner::Token::isSymbol() const
840{
841 return type_ == TOKEN_SYMBOL;
842}
843
845{
846 return type_ == TOKEN_END_OF_FILE;
847}
848
849inline const std::string& Scanner::Token::raw() const
850{
851 return data_;
852}
853
854inline Scanner::Token::operator bool() const
855{
856 return type_ != TOKEN_INVALID;
857}
858
859inline Scanner::Scanner(const std::string& filename, const std::string& buffer, float* progress, bool* cancel) :
860 Scanner(createInputStream(filename, buffer), progress, cancel)
861{
862 ocean_assert(!filename.empty() || !buffer.empty());
863
864 if (!filename.empty() && stream_)
865 {
867 }
868}
869
870inline Scanner::Scanner(const std::string& filename, std::string&& buffer, float* progress, bool* cancel) :
871 Scanner(createInputStream(filename, std::move(buffer)), progress, cancel)
872{
873 ocean_assert(!filename.empty() || stream_);
874
875 if (!filename.empty() && stream_)
876 {
878 }
879}
880
881size_t Scanner::line() const
882{
883 return line_;
884}
885
886size_t Scanner::column() const
887{
888 return column_;
889}
890
891inline const std::string& Scanner::filename() const
892{
893 return filename_;
894}
895
896inline bool Scanner::isValid() const
897{
898 return bool(stream_);
899}
900
901inline bool Scanner::isWhitespace(const char& character)
902{
903 return character == ' ' || character == '\t' || character == '\n' || character == '\r';
904}
905
906inline std::shared_ptr<std::istream> Scanner::createInputStream(const std::string& filename, std::string&& buffer)
907{
908 ocean_assert(!filename.empty() || !buffer.empty());
909
910 if (!filename.empty())
911 {
912 return std::shared_ptr<std::istream>(new std::ifstream(filename.c_str(), std::ios_base::binary));
913 }
914
915 return std::shared_ptr<std::istream>(new std::istringstream(std::move(buffer)));
916}
917
918inline std::shared_ptr<std::istream> Scanner::createInputStream(const std::string& filename, const std::string& buffer)
919{
920 ocean_assert(!filename.empty() || !buffer.empty());
921
922 if (!filename.empty())
923 {
924 return std::shared_ptr<std::istream>(new std::ifstream(filename.c_str(), std::ios_base::binary));
925 }
926
927 return std::shared_ptr<std::istream>(new std::istringstream(buffer));
928}
929
930}
931
932}
933
934#endif // META_OCEAN_IO_SCANNER_H
This class implements a token for the scanner.
Definition Scanner.h:45
Token(std::string &&data, const Type type)
Creates a new token with given data and type.
bool isKeyword() const
Returns whether this token holds a keyword.
Definition Scanner.h:829
uint32_t keyword() const
Returns the id of the keyword of this token.
std::string data_
Holds the data of the token.
Definition Scanner.h:280
bool isSymbol(const uint32_t symbol) const
Returns whether this token holds a special symbol.
Type
Definition of different token types.
Definition Scanner.h:52
@ TOKEN_END_OF_FILE
End of file token.
Definition Scanner.h:58
@ TOKEN_INTEGER
Integer token.
Definition Scanner.h:66
@ TOKEN_KEYWORD
Keyword token.
Definition Scanner.h:68
@ TOKEN_LINE
Line token.
Definition Scanner.h:62
@ TOKEN_IDENTIFIER
Identifier token.
Definition Scanner.h:60
@ TOKEN_NUMBER
Number token.
Definition Scanner.h:64
@ TOKEN_CHARACTER
Character token.
Definition Scanner.h:56
@ TOKEN_STRING
String token.
Definition Scanner.h:70
bool isKeyword(const uint32_t keyword) const
Returns whether this token holds a special keyword.
bool isType(const Type type) const
Returns whether this token is of a specific type.
Definition Scanner.h:794
bool isLine() const
Returns whether this token holds a remaining line.
Definition Scanner.h:824
bool isSymbol() const
Returns whether this token holds a symbol.
Definition Scanner.h:839
const std::string & raw() const
Returns the raw data of the token.
Definition Scanner.h:849
bool isCharacter() const
Returns whether this token holds a character.
Definition Scanner.h:799
bool isString() const
Returns whether this token holds a string.
Definition Scanner.h:834
int32_t integer() const
Returns the integer value of this token.
uint32_t symbol() const
Returns the id of the symbol of this token.
std::string moveString()
Returns the string value of this token and invalidates the token.
bool isNumber() const
Returns whether this token holds a number.
Definition Scanner.h:814
Type type() const
Returns the type of the token.
Definition Scanner.h:789
bool isEndOfFile() const
Returns whether this token holds an end of file.
Definition Scanner.h:844
const std::string & string() const
Returns the string value of this token.
const std::string & line() const
Returns the remaining line of this token.
bool isIdentifier() const
Returns whether this token holds an identifier.
Definition Scanner.h:804
bool isIntegerOrNumber() const
Returns whether this token holds an integer or a number.
Definition Scanner.h:819
Type type_
Holds the type of the token.
Definition Scanner.h:274
double number() const
Returns the floating point value of this token.
Token(const std::string &data, const uint32_t id, const Type type)
Creates a new token with given keyword or symbol id.
Token()=default
Creates an invalid token.
uint8_t character() const
Returns the character value of this token.
double integerOrNumber() const
Returns the integer or floating point value of this token.
Token(std::string &&data, const uint32_t id, const Type type)
Creates a new token with given keyword or symbol id.
Token(const std::string &data, const Type type)
Creates a new token with given data and type.
const std::string & identifier() const
Returns the identifier value of this token.
bool isInteger() const
Returns whether this token holds an integer.
Definition Scanner.h:809
This class implements a simple scanner.
Definition Scanner.h:33
std::unordered_map< std::string, std::string > ScopeRemarks
Definition of an unordered map mapping begin remark symbols to end remark symbols.
Definition Scanner.h:298
const Token & lineToken()
Returns a line token starting at the current position.
std::string filename_
The name of the input file, if the input is a file.
Definition Scanner.h:717
std::string discardNonWhiteSpace()
Discards non white space and jumps to the first white space position.
CharTable followingCharTable_
Table holding the definition of allowed following characters.
Definition Scanner.h:777
bool readKeyword(Token &token, const bool consumeBytes)
Tries to read a keyword as next token.
size_t column_
Holds the current column.
Definition Scanner.h:747
size_t column() const
Returns the recent column.
Definition Scanner.h:886
Token recentToken_
Recent token.
Definition Scanner.h:708
uint32_t symbolId(const std::string &data) const
Returns the symbol id of a given string.
uint8_t get(const size_t offset=0)
Returns one character.
std::unordered_map< std::string, uint32_t > IdMap
Definition of an unordered map mapping strings to ids.
Definition Scanner.h:288
CharTable invalidCharTable_
Table holding the definition of not allowed following characters.
Definition Scanner.h:780
bool readInteger(Token &token, const bool consumeBytes)
Tries to read an integer as next token.
IdMap symbolMap_
Map mapping symbol strings to symbol ids.
Definition Scanner.h:759
static std::shared_ptr< std::istream > createInputStream(const std::string &filename, std::string &&buffer)
Creates a file input stream or a string input stream depending on the given input.
Definition Scanner.h:906
static bool findNextToken(const char *pointer, const size_t start, size_t &tokenStart, size_t &tokenLength)
Finds the next token in a given string starting from a specified position.
bool readIdentifier(Token &token, const bool consumeBytes)
Tries to read a identifier as next token.
bool isValid() const
Returns whether the scanner is valid and ready to use.
Definition Scanner.h:896
size_t position() const
Returns the position of the scanner.
uint32_t keywordId(const std::string &data) const
Returns the keyword id of a given string.
CharTable firstCharTable_
Table holding the definition of allowed first characters.
Definition Scanner.h:774
uint8_t getExtra(const size_t offset=0)
Returns one character from the extra buffer.
FirstChar
Definition of first character types.
Definition Scanner.h:309
void consume(const size_t chars=1)
Consumes one or more character.
bool readCharacter(Token &token, const bool consumeBytes)
Tries to read a character as next token.
std::shared_ptr< std::istream > stream_
The input stream from which the scanner receives the data.
Definition Scanner.h:714
std::unordered_set< std::string > LineRemarks
Definition of an unordered set holding line remark symbols.
Definition Scanner.h:293
void registerKeyword(const std::string &keyword, const uint32_t id)
Registers a new keyword.
bool readScopeRemark()
Reads a scope remark comment.
std::string data(const size_t offset, const size_t size) const
Returns data of a specified size starting at the offset position.
bool readRemark()
Reads remark comments.
void registerLineRemark(const std::string &lineRemark)
Registers a line remark symbol.
Scanner(float *progress, bool *cancel)
Creates a new scanner.
Token nextToken_
Next token.
Definition Scanner.h:711
const Token & token()
Returns the recent token.
Token tokenPop()
Returns the recent token and pops it afterwards.
void setKeywordProperty(const bool caseSensitive)
Sets whether the keywords are case sensitive or not.
bool refillExtraBuffer(const size_t minIndex)
Refills the extra buffer.
std::string data(const size_t size) const
Returns data of a specified size starting at the recent position.
size_t line() const
Returns the recent line.
Definition Scanner.h:881
virtual ~Scanner()
Destructs a scanner.
bool readLine(Token &token, const bool consumeBytes)
Tries to read a remaining line as next token.
void registerSymbol(const std::string &symbol, const uint32_t id)
Registers a new symbol.
static bool isWhitespace(const char &character)
Returns whether a given character is a white space character.
Definition Scanner.h:901
uint8_t readWhiteSpace(bool crossLines=true)
Reads white space.
IdMap keywordMap_
Map mapping keyword strings to identifier ids.
Definition Scanner.h:753
size_t line_
Holds the current line.
Definition Scanner.h:744
const std::string & filename() const
Returns the name of the input file, if the input is a file.
Definition Scanner.h:891
bool readNumber(Token &token, const bool consumeBytes)
Tries to read a number as next token.
ScopeRemarks scopeRemarks_
Scope remarks.
Definition Scanner.h:768
void pop()
Pops the recent token.
virtual Token readToken(const bool consumeBytes=true)
Reads and returns the next token.
bool refillIntermediateBuffer()
Refills the intermediate buffer.
std::array< uint16_t, 256 > CharTable
Definition of a character table.
Definition Scanner.h:303
void registerScopeRemark(const std::string &begin, const std::string &end)
Registers a scope remark symbol.
size_t size() const
Returns the size of the scanner.
static bool findNextToken(const char *pointer, const size_t size, const size_t start, size_t &tokenStart, size_t &tokenLength)
Finds the next token in a given string starting from a specified position.
bool readLineRemark()
Reads a line remark comment.
Memory intermediateBuffer_
Local intermediate buffer.
Definition Scanner.h:726
Scanner(const std::shared_ptr< std::istream > &stream, float *progress=nullptr, bool *cancel=nullptr)
Creates a new scanner using a stream as input.
bool registerWhiteSpaceCharacter(const uint8_t character)
Registers a white space character.
bool readSymbol(Token &token, const bool consumeBytes)
Tries to read a symbol as next token.
bool readString(Token &token, const bool consumeBytes)
Tries to read a string as next token.
Memory extraBuffer_
Local extra buffer, used if the intermediate buffer is too small.
Definition Scanner.h:735
const Token & look()
Returns a lookahead to the next token.
LineRemarks lineRemarks_
Registered line remarks.
Definition Scanner.h:762
This class implements an object able to allocate memory.
Definition base/Memory.h:22
The namespace covering the entire Ocean framework.
Definition Accessor.h:15