17 return fail(
"empty expression");
20 if (!result) {
return result; }
23 return fail(
"unexpected token '" + std::string(1,
peek()) +
"'");
36 if (
peek() !=
c) {
return false; }
43 const std::size_t start =
pos_;
44 for (
const char* p = text; *p; ++p) {
56 const std::size_t start =
pos_;
67 std::isspace(
static_cast<unsigned char>(
source_[
pos_]))) {
74 std::move(message) +
" at byte " + std::to_string(
pos_),
79 return std::isalpha(
c) ||
c ==
'_' ||
c >= 0x80;
83 return std::isalnum(
c) ||
c ==
'_' ||
c >= 0x80;
88 if (!lhs) {
return lhs; }
93 if (!lhs) {
return lhs; }
100 if (!lhs) {
return lhs; }
105 if (!lhs) {
return lhs; }
113 if (!operand) {
return operand; }
121 if (!lhs) {
return lhs; }
127 const auto save =
pos_;
141 if (!lhs) {
return lhs; }
154 if (!lhs) {
return lhs; }
160 if (!lhs) {
return lhs; }
167 }
else if (
match(
'<')) {
169 }
else if (
match(
'>')) {
177 if (!lhs) {
return lhs; }
183 if (!lhs) {
return lhs; }
188 lhs =
add(lhs.value(),
rhs.value());
189 }
else if (
match(
'-')) {
192 lhs =
sub(lhs.value(),
rhs.value());
196 if (!lhs) {
return lhs; }
202 if (!lhs) {
return lhs; }
205 return fail(
"operator '**' is not supported; use '^'");
206 }
else if (
match(
'*')) {
209 lhs =
mul(lhs.value(),
rhs.value());
210 }
else if (
match(
'/')) {
213 lhs =
div(lhs.value(),
rhs.value());
217 if (!lhs) {
return lhs; }
223 if (!base) {
return base; }
225 return fail(
"operator '**' is not supported; use '^'");
239 if (!operand) {
return operand; }
240 return neg(operand.value());
249 if (!inner) {
return inner; }
253 if (!
match(
')')) {
return fail(
"expected ')' after interval"); }
254 return interval(inner.value(),
rhs.value(),
false,
false);
256 if (!
match(
')')) {
return fail(
"expected ')'"); }
265 if (std::isdigit(
static_cast<unsigned char>(
peek())) ||
peek() ==
'.') {
271 return fail(
"expected expression");
275 std::vector<ExprPtr> elements;
280 elements.push_back(
element.value());
281 if (
match(
'}'))
break;
282 if (!
match(
',')) {
return fail(
"expected ',' or '}' in set literal"); }
291 if (!
match(
',')) {
return fail(
"expected ',' in interval literal"); }
297 }
else if (
match(
')')) {
300 return fail(
"expected ']' or ')' after interval literal");
307 const std::size_t start =
pos_;
308 bool saw_digit =
false;
309 while (std::isdigit(
static_cast<unsigned char>(
peek()))) {
315 while (std::isdigit(
static_cast<unsigned char>(
peek()))) {
320 if (!saw_digit) {
return fail(
"invalid number literal"); }
321 if (
peek() ==
'e' ||
peek() ==
'E') {
324 bool saw_exp_digit =
false;
325 while (std::isdigit(
static_cast<unsigned char>(
peek()))) {
326 saw_exp_digit =
true;
329 if (!saw_exp_digit) {
return fail(
"invalid number exponent"); }
333 }
catch (
const std::bad_alloc&) {
335 "number literal allocation failed",
337 }
catch (
const std::invalid_argument& error) {
340 }
catch (
const std::out_of_range& error) {
343 }
catch (
const std::exception& error) {
351 const std::size_t start =
pos_;
360 const auto start =
pos_;
361 while (!
eof() &&
peek() !=
')' &&
362 !std::isspace(
static_cast<unsigned char>(
peek()))) ++
pos_;
363 const std::string_view token(
source_.data() + start,
pos_ - start);
364 if (!
match(
')'))
return fail(
"expected ')' after approximate decimal");
372 std::vector<ExprPtr> arguments;
373 bool closed =
match(
')');
380 arguments.push_back(argument.value());
385 }
while (
match(
','));
388 return fail(
"expected ')'");
396 return fail(
"expected identifier");
438 }
catch (
const std::bad_alloc&) {
440 "expression parse allocation failed",
442 }
catch (
const std::exception& error) {
static bool is_ident_continue(unsigned char c) noexcept
static bool is_ident_start(unsigned char c) noexcept
ExprResult parse_logical_and()
ExprResult parse_logical_or()
char peek() const noexcept
ExprResult parse_multiplicative()
ExprResult parse_membership()
ExprResult parse_logical_not()
void skip_space() noexcept
ExprResult parse_approx_literal()
bool match_keyword(const char *text)
ExprResult parse_number()
ExprParser(std::string source)
ExprResult parse_relational()
ExprResult parse_equality()
ExprResult parse_identifier_or_call()
bool match_text(const char *text)
ExprResult parse_call(const std::string &name)
ExprResult parse_set_literal()
ExprResult parse_additive()
std::string parse_identifier()
bool eof() const noexcept
ExprResult parse_primary()
ExprResult fail(std::string message) const
ExprResult parse_interval_literal(bool lower_closed)
@ Not
一元逻辑非,right 为 nullptr。
static Result failure(CasErrc code, std::string message, std::string operation={})
static bool is_ident_continue(unsigned char c) noexcept
static bool is_ident_start(unsigned char c) noexcept
ExprResult parse_logical_and()
ExprResult parse_logical_or()
char peek() const noexcept
ExprResult parse_multiplicative()
ExprResult interval(const ExprPtr &lower, const ExprPtr &upper, bool lower_closed, bool upper_closed)
ExprResult logical(const ExprPtr &lhs, const ExprPtr &rhs, LogicalNode::Op op)
ExprResult parse_membership()
ExprResult parse_logical_not()
void skip_space() noexcept
ExprResult apply_function(const std::string &name, const std::vector< ExprPtr > &arguments)
ExprResult parse_approx_literal()
bool match_keyword(const char *text)
ExprResult parse_number()
ExprResult finite_set(const std::vector< ExprPtr > &elements)
ExprResult parse_relational()
ExprResult parse_equality()
ExprResult relational(const ExprPtr &lhs, const ExprPtr &rhs, RelationOp op)
ExprResult parse_identifier_or_call()
bool match_text(const char *text)
ExprResult parse_call(const std::string &name)
ExprResult membership(const ExprPtr &element, const ExprPtr &set, bool negated)
ExprResult parse_set_literal()
ExprResult parse_additive()
std::string parse_identifier()
bool eof() const noexcept
ExprResult parse_primary()
ExprResult fail(std::string message) const
ExprResult parse_interval_literal(bool lower_closed)
bool is_imaginary_unit_name(const std::string &name)
Result< double > parse_finite_decimal(std::string_view token)
ExprResult expression_failure(CasErrc code, std::string message, const char *operation)
constexpr const char * kParseOperation
ExprResult pow(const ExprPtr &base, const ExprPtr &exponent, ComputationContext &context)
ExprResult imaginary_unit()
__attribute__((visibility("default"))) ExprResult function(const std __attribute__((visibility("default"))) ExprResult finite_set(std ExprPtr upper
const std::vector< Polynomial< BigInt > > const BigInt ComputationContext & context
ExprResult neg(const ExprPtr &expression, ComputationContext &context)
ExprResult approx_real(double value)
ExprResult sub(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
ExprResult div(const ExprPtr &numerator, const ExprPtr &denominator, ComputationContext &context)
ExprResult mul(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
const VectorField const VectorField & c
Result< ExprPtr > ExprResult
ExprResult add(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
RelationOp
Stable relational operator used by public APIs.
const ExprPtr RelationOp op
__attribute__((visibility("default"))) ExprResult function(const std __attribute__((visibility("default"))) ExprResult finite_set(std ExprPtr bool lower_closed
ExprResult parse_expr(const std::string &source)
ExprResult sym(const std::string &name)
constexpr const char * kParseOperation
const std::string const ExprPtr & value
__attribute__((visibility("default"))) ExprResult function(const std __attribute__((visibility("default"))) ExprResult finite_set(std ExprPtr bool bool upper_closed
__attribute__((visibility("default"))) Result< EqvProfile > eqv_profile_from_name(const std const std::string & name
ExprResult rational(const Rational &value)