Macaulay2 Engine
Loading...
Searching...
No Matches

◆ parseBasicPoly() [1/2]

void parseBasicPoly ( const std::string_view & str,
const IdentifierHash & idenHash,
BasicPoly & result )

This version is a potentially faster alternative when reading many polynomials.

Definition at line 137 of file BasicPolyListParser.cpp.

138{
139 size_t begin_loc = 0;
140 size_t end_loc = str.size();
141
142 result.clear();
143
144 if (end_loc > begin_loc and str[begin_loc] == '[')
145 {
146 ++begin_loc;
147 }
148 while (end_loc > begin_loc and str[end_loc-1] == ' ') --end_loc;
149 if (end_loc > begin_loc and str[end_loc-1] == ',') --end_loc;
150 if (end_loc > begin_loc and str[end_loc-1] == ':') --end_loc;
151 if (end_loc > begin_loc and str[end_loc-1] == ']') --end_loc;
152
153 if (begin_loc == end_loc) return; // result is already set to 0.
154
155 while (end_loc > begin_loc)
156 {
157 int sign = 1;
158
159 // Read the next term into `result`.
160 if (str[begin_loc] == '+')
161 {
162 ++begin_loc;
163 }
164 // TODO: do not want +- ...
165 if (str[begin_loc] == '-')
166 {
167 ++begin_loc;
168 sign = -1;
169 }
170 mpz_class coeff{readInteger_mpz_class(str, begin_loc, end_loc)}; // defaults to 1 if no integer present.
171
172 if (sign == -1) coeff = -coeff;
173 result.mCoefficients.push_back(coeff); // do not clear(coeff) !
174
175 // Now we read the monomial part.
176 long loc = result.mMonomials.size(); // this is where the length field will go.
177 result.mMonomials.push_back(1); // 1 means that the monomial is `1`.
178
179 // We expect the first character to be an identifier char.
180 // then right after that a `*` or `^'.
181 // If we get to "+", or "-" or end of string: we set result.mMonomials[loc] to the correct size.
182 while (end_loc > begin_loc)
183 {
184 char c = str[begin_loc];
185 if (c == '-' or c == '+')
186 break; // on to the next term
187 if (c == '*')
188 {
189 ++begin_loc;
190 if (begin_loc == end_loc)
191 {
192 throw parsing_error("line ends after a *");
193 // throw an error
194 }
195 c = str[begin_loc];
196 }
197
198 if (not isalpha(c))
199 // not well forrmed, I think.
200 {
201 throw parsing_error("expected an identifier at position " + std::to_string(begin_loc));
202 }
203 // TODO: in fact, throw an error here
204 auto prev_loc = begin_loc;
205 int v = readIdentifier(str, idenHash, begin_loc, end_loc);
206 if (v == -1)
207 {
208 throw parsing_error("expected a variable name at position " + std::to_string(prev_loc));
209 }
210 // TODO: if the identifier is not found, throw an error.
211 int e = 1;
212 if (end_loc > begin_loc and str[begin_loc] == '^')
213 {
214 ++begin_loc;
215 // if not a digit, throw an error. Note: here we are currently assuming positive exponents.
216 if (begin_loc >= end_loc or not std::isdigit(str[begin_loc]))
217 {
218 throw parsing_error("expected a digit at position " + std::to_string(begin_loc));
219 }
220 e = readInteger_long(str, begin_loc, end_loc);
221 }
222 // if exponent is zero, don't add anything to monomial.
223 if (e != 0)
224 {
225 result.mMonomials.push_back(v);
226 result.mMonomials.push_back(e);
227 result.mMonomials[loc] += 2;
228 }
229 }
230 }
231}
int readIdentifier(const std::string_view &str, const IdentifierHash &map, size_t &begin_loc, size_t end_loc)
mpz_class readInteger_mpz_class(const std::string_view &str, size_t &begin_loc, size_t end_loc)
long readInteger_long(const std::string_view &str, size_t &begin_loc, size_t end_loc)
VALGRIND_MAKE_MEM_DEFINED & result(result)

References readIdentifier(), readInteger_long(), readInteger_mpz_class(), and result().

Referenced by parseBasicPoly(), parseBasicPolyListFromString(), and parseMsolveFromString().