OPALX (Object Oriented Parallel Accelerator Library for Exascal) master (dc2a29eed580)
OPALX
Loading...
Searching...
No Matches
value_parser.hpp
Go to the documentation of this file.
1//
2// Simple value parser for SDDS data values
3// Replaces boost::spirit::qi parsing for parameter and column values
4//
5#ifndef VALUE_PARSER_HPP_
6#define VALUE_PARSER_HPP_
7
8#include <cctype>
9#include <sstream>
10#include <stdexcept>
11#include <string>
12#include "ast.hpp"
13
14namespace SDDS {
15 namespace parser {
16
18 public:
19 ValueParser(const std::string& input, size_t start_pos = 0)
20 : input_(input), pos_(start_pos) {}
21
23 while (pos_ < input_.length()) {
24 if (std::isspace(static_cast<unsigned char>(input_[pos_]))) {
25 pos_++;
26 } else if (input_[pos_] == '!') {
27 // Skip comments
28 while (pos_ < input_.length() && input_[pos_] != '\n') {
29 pos_++;
30 }
31 } else {
32 break;
33 }
34 }
35 }
36
37 bool parseFloat(float& value) {
39 size_t start = pos_;
40 bool has_dot = false;
41 bool has_exp = false;
42
43 if (pos_ < input_.length() && (input_[pos_] == '+' || input_[pos_] == '-')) {
44 pos_++;
45 }
46
47 while (pos_ < input_.length()) {
48 char c = input_[pos_];
49 if (std::isdigit(static_cast<unsigned char>(c))) {
50 pos_++;
51 } else if (c == '.' && !has_dot) {
52 has_dot = true;
53 pos_++;
54 } else if ((c == 'e' || c == 'E') && !has_exp) {
55 has_exp = true;
56 pos_++;
57 if (pos_ < input_.length()
58 && (input_[pos_] == '+' || input_[pos_] == '-')) {
59 pos_++;
60 }
61 } else {
62 break;
63 }
64 }
65
66 if (pos_ > start) {
67 try {
68 value = std::stof(input_.substr(start, pos_ - start));
69 return true;
70 } catch (...) {
71 return false;
72 }
73 }
74 return false;
75 }
76
77 bool parseDouble(double& value) {
79 size_t start = pos_;
80 bool has_dot = false;
81 bool has_exp = false;
82
83 if (pos_ < input_.length() && (input_[pos_] == '+' || input_[pos_] == '-')) {
84 pos_++;
85 }
86
87 while (pos_ < input_.length()) {
88 char c = input_[pos_];
89 if (std::isdigit(static_cast<unsigned char>(c))) {
90 pos_++;
91 } else if (c == '.' && !has_dot) {
92 has_dot = true;
93 pos_++;
94 } else if ((c == 'e' || c == 'E') && !has_exp) {
95 has_exp = true;
96 pos_++;
97 if (pos_ < input_.length()
98 && (input_[pos_] == '+' || input_[pos_] == '-')) {
99 pos_++;
100 }
101 } else {
102 break;
103 }
104 }
105
106 if (pos_ > start) {
107 try {
108 value = std::stod(input_.substr(start, pos_ - start));
109 return true;
110 } catch (...) {
111 return false;
112 }
113 }
114 return false;
115 }
116
117 bool parseShort(short& value) {
119 size_t start = pos_;
120
121 if (pos_ < input_.length() && (input_[pos_] == '-' || input_[pos_] == '+')) {
122 pos_++;
123 }
124
125 while (pos_ < input_.length()
126 && std::isdigit(static_cast<unsigned char>(input_[pos_]))) {
127 pos_++;
128 }
129
130 if (pos_ > start) {
131 try {
132 long long_val = std::stol(input_.substr(start, pos_ - start));
133 value = static_cast<short>(long_val);
134 return true;
135 } catch (...) {
136 return false;
137 }
138 }
139 return false;
140 }
141
142 bool parseLong(long& value) {
144 size_t start = pos_;
145
146 if (pos_ < input_.length() && (input_[pos_] == '-' || input_[pos_] == '+')) {
147 pos_++;
148 }
149
150 while (pos_ < input_.length()
151 && std::isdigit(static_cast<unsigned char>(input_[pos_]))) {
152 pos_++;
153 }
154
155 if (pos_ > start) {
156 try {
157 value = std::stol(input_.substr(start, pos_ - start));
158 return true;
159 } catch (...) {
160 return false;
161 }
162 }
163 return false;
164 }
165
166 bool parseChar(char& value) {
168 if (pos_ < input_.length()) {
169 value = input_[pos_];
170 pos_++;
171 return true;
172 }
173 return false;
174 }
175
176 bool parseQuotedString(std::string& value) {
178 if (pos_ >= input_.length() || input_[pos_] != '"') {
179 return false;
180 }
181 pos_++; // skip opening quote
182 value.clear();
183
184 while (pos_ < input_.length() && input_[pos_] != '"') {
185 if (input_[pos_] == '\\' && pos_ + 1 < input_.length()) {
186 pos_++;
187 value += input_[pos_];
188 } else {
189 value += input_[pos_];
190 }
191 pos_++;
192 }
193
194 if (pos_ < input_.length() && input_[pos_] == '"') {
195 pos_++; // skip closing quote
196 return true;
197 }
198 return false;
199 }
200
201 bool parseString(std::string& value) {
203 if (pos_ < input_.length() && input_[pos_] == '"') {
204 return parseQuotedString(value);
205 }
206
207 // Parse unquoted string (identifier)
208 size_t start = pos_;
209 while (pos_ < input_.length()) {
210 char c = input_[pos_];
211 if (std::isalnum(static_cast<unsigned char>(c)) || c == '@' || c == '#'
212 || c == ':' || c == '+' || c == '-' || c == '%' || c == '.' || c == '_'
213 || c == '$' || c == '&' || c == '/') {
214 pos_++;
215 } else {
216 break;
217 }
218 }
219
220 if (pos_ > start) {
221 value = input_.substr(start, pos_ - start);
222 return true;
223 }
224 return false;
225 }
226
227 size_t getPosition() const { return pos_; }
228 void setPosition(size_t pos) { pos_ = pos; }
229
230 private:
231 const std::string& input_;
232 size_t pos_;
233 };
234
235 } // namespace parser
236} // namespace SDDS
237
238#endif /* VALUE_PARSER_HPP_ */
bool parseQuotedString(std::string &value)
bool parseLong(long &value)
const std::string & input_
bool parseString(std::string &value)
bool parseChar(char &value)
bool parseFloat(float &value)
void setPosition(size_t pos)
ValueParser(const std::string &input, size_t start_pos=0)
bool parseDouble(double &value)
bool parseShort(short &value)