File: tokenizer.h

package info (click to toggle)
wsclean 3.6-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 16,296 kB
  • sloc: cpp: 129,246; python: 22,066; sh: 360; ansic: 230; makefile: 185
file content (103 lines) | stat: -rw-r--r-- 2,522 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#ifndef TOKENIZER_H
#define TOKENIZER_H

#include <fstream>
#include <stdexcept>

namespace wsclean {

class Tokenizer {
 public:
  std::string getString() {
    std::string token;
    getToken(token);
    if (token.size() < 2 || token[0] != '\"' || token[token.size() - 1] != '\"')
      throw std::runtime_error("Expecting string");
    return token.substr(1, token.size() - 2);
  }
  double getTokenAsDouble() {
    std::string token;
    getToken(token);
    return atof(token.c_str());
  }

  bool getTokenAsBool() {
    std::string token;
    getToken(token);
    if (token == "1" || token == "true" || token == "True")
      return true;
    else if (token == "0" || token == "false" || token == "False")
      return false;
    else
      throw std::runtime_error("Expecting boolean");
  }

  bool getToken(std::string &token) {
    if (!_stream->good()) return false;

    std::stringstream s;
    bool finished = false;
    enum {
      StateStart,
      StateInToken,
      StateInString,
      StateEscaped,
      StateInLineComment
    } state = StateStart;
    do {
      char c;
      _stream->get(c);
      if (!_stream->fail()) {
        switch (state) {
          case StateStart:
            if (!(c == ' ' || c == '\t' || c == '\n')) {
              if (c == '/')
                state = StateEscaped;
              else {
                s << c;
                if (c == '\"')
                  state = StateInString;
                else
                  state = StateInToken;
              }
            }
            break;
          case StateInString:
            s << c;
            if (c == '\"') finished = true;
            break;
          case StateInToken:
            if (c == ' ' || c == '\t' || c == '\n' || c == ';')
              finished = true;
            else
              s << c;
            break;
          case StateEscaped:
            if (c == '/')
              state = StateInLineComment;
            else
              throw std::runtime_error("Incorrect /");
            break;
          case StateInLineComment:
            if (c == '\n') state = StateStart;
            break;
        }
      } else {
        token = s.str();
        return !token.empty();
      }
    } while (!finished);
    token = s.str();
    return true;
  }

  void SetStream(std::ifstream &stream) { _stream = &stream; }
  std::ifstream &Stream() { return *_stream; }
  const std::ifstream &Stream() const { return *_stream; }

  std::ifstream *_stream;
};

}  // namespace wsclean

#endif