LMCAS
Lamina Computer Algebra System
载入中...
搜索中...
未找到
LMCAS::expr_detail::ExprParser类 参考

#include </home/runner/work/docs/docs/LMCAS/src/internal/expr_parser.hpp>

LMCAS::expr_detail::ExprParser 的协作图:

Public 成员函数

 ExprParser (std::string source)
ExprResult parse ()

Private 成员函数

ExprResult apply_atan2 (const std::vector< ExprPtr > &arguments)
ExprResult apply_clamp (const std::vector< ExprPtr > &arguments)
ExprResult apply_function (const std::string &name, const std::vector< ExprPtr > &arguments)
ExprResult apply_integral (const std::vector< ExprPtr > &arguments)
ExprResult apply_limit (const std::vector< ExprPtr > &arguments)
ExprResult apply_log (const std::vector< ExprPtr > &arguments)
ExprResult apply_rootof (const std::vector< ExprPtr > &arguments)
bool eof () const noexcept
ExprResult fail (std::string message) const
ExprResult finite_set (const std::vector< ExprPtr > &elements)
ExprResult function_node (const std::string &name, const std::vector< ExprPtr > &arguments, FunctionNode::FuncType type)
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)
bool match (char c)
bool match_keyword (const char *text)
bool match_text (const char *text)
ExprResult membership (const ExprPtr &element, const ExprPtr &set, bool negated)
ExprResult parse_additive ()
ExprResult parse_approx_literal ()
ExprResult parse_call (const std::string &name)
ExprResult parse_equality ()
std::string parse_identifier ()
ExprResult parse_identifier_or_call ()
ExprResult parse_interval_literal (bool lower_closed)
ExprResult parse_logical_and ()
ExprResult parse_logical_not ()
ExprResult parse_logical_or ()
ExprResult parse_membership ()
ExprResult parse_multiplicative ()
ExprResult parse_number ()
ExprResult parse_power ()
ExprResult parse_primary ()
ExprResult parse_relational ()
ExprResult parse_set_literal ()
ExprResult parse_unary ()
char peek () const noexcept
ExprResult relational (const ExprPtr &lhs, const ExprPtr &rhs, RelationOp op)
void skip_space () noexcept
ExprResult uninterpreted_function (const std::string &name, const std::vector< ExprPtr > &arguments)

静态 Private 成员函数

static bool is_ident_continue (unsigned char c) noexcept
static bool is_ident_start (unsigned char c) noexcept

Private 属性

std::size_t pos_ = 0
std::string source_

详细描述

在文件 expr_parser.hpp 第 14 行定义.

构造及析构函数说明

◆ ExprParser()

LMCAS::expr_detail::ExprParser::ExprParser ( std::string source)
inlineexplicit

在文件 expr_parser.hpp 第 16 行定义.

16: source_(std::move(source)) {}

引用了 source_.

被这些函数引用 apply_function().

这是这个函数的调用关系图:

成员函数说明

◆ apply_atan2()

ExprResult LMCAS::expr_detail::ExprParser::apply_atan2 ( const std::vector< ExprPtr > & arguments)
private

在文件 expr_parser_functions.cpp 第 61 行定义.

61 {
62 try {
63 auto result = SymbolicExpr::atan2(arguments[0], arguments[1]);
64 return ExprResult::success(std::move(result));
65 } catch (const std::bad_alloc&) {
67 "atan2 expression allocation failed",
69 } catch (const std::exception& error) {
72 }
73}
static Result success(ExprPtr value)
ExprResult expression_failure(CasErrc code, std::string message, const char *operation)
constexpr const char * kParseOperation

引用了 LMCAS::expr_detail::expr_common::expression_failure(), LMCAS::InternalInvariant, LMCAS::expr_detail::kParseOperation, LMCAS::ResourceLimit , 以及 LMCAS::Result< ExprPtr >::success().

被这些函数引用 apply_function().

函数调用图:
这是这个函数的调用关系图:

◆ apply_clamp()

ExprResult LMCAS::expr_detail::ExprParser::apply_clamp ( const std::vector< ExprPtr > & arguments)
private

在文件 expr_parser_functions.cpp 第 161 行定义.

161 {
162 return clamp(arguments[0], arguments[1], arguments[2]);
163}
ExprResult clamp(const ExprPtr &expression, const ExprPtr &lower, const ExprPtr &upper, ComputationContext &context)

引用了 LMCAS::clamp().

被这些函数引用 apply_function().

函数调用图:
这是这个函数的调用关系图:

◆ apply_function()

ExprResult LMCAS::expr_detail::ExprParser::apply_function ( const std::string & name,
const std::vector< ExprPtr > & arguments )
private

在文件 expr_parser_functions.cpp 第 165 行定义.

166 {
167 if (auto unary = find_unary_function(name)) {
168 if (arguments.size() == 1) {
169 return unary(arguments[0]);
170 }
171 if (name == "log" && arguments.size() == 2) {
172 return apply_log(arguments);
173 }
174 return fail("invalid argument count for function '" + name + "'");
175 }
176 using Constructor = ExprResult (ExprParser::*)(const std::vector<ExprPtr>&);
177 static const struct {
178 const char* name;
179 Constructor construct;
180 std::size_t arity;
181 std::size_t alternative_arity;
182 } functions[] = {
183 {"atan2", &ExprParser::apply_atan2, 2, 2},
184 {"clamp", &ExprParser::apply_clamp, 3, 3},
185 {"Integral", &ExprParser::apply_integral, 2, 4},
186 {"integral", &ExprParser::apply_integral, 2, 4},
187 {"Limit", &ExprParser::apply_limit, 4, 4},
188 {"limit", &ExprParser::apply_limit, 4, 4},
189 {"RootOf", &ExprParser::apply_rootof, 3, 3},
190 {"rootof", &ExprParser::apply_rootof, 3, 3}
191 };
192 for (const auto& entry : functions) {
193 if (name == entry.name) {
194 if (arguments.size() != entry.arity &&
195 arguments.size() != entry.alternative_arity) {
196 return fail("invalid argument count for function '" + name + "'");
197 }
198 return (this->*entry.construct)(arguments);
199 }
200 }
201 if (!arguments.empty() && (name == "max" || name == "min")) {
202 return function_node(name, arguments,
204 }
205 return uninterpreted_function(name, arguments);
206}
@ Max
最大值 max(a, b)。
@ Min
最小值 min(a, b)。
ExprResult apply_log(const std::vector< ExprPtr > &arguments)
ExprResult uninterpreted_function(const std::string &name, const std::vector< ExprPtr > &arguments)
ExprResult function_node(const std::string &name, const std::vector< ExprPtr > &arguments, FunctionNode::FuncType type)
ExprResult apply_clamp(const std::vector< ExprPtr > &arguments)
ExprResult apply_atan2(const std::vector< ExprPtr > &arguments)
ExprResult apply_limit(const std::vector< ExprPtr > &arguments)
ExprResult apply_integral(const std::vector< ExprPtr > &arguments)
ExprResult apply_rootof(const std::vector< ExprPtr > &arguments)
ExprResult fail(std::string message) const
Result< ExprPtr > ExprResult
__attribute__((visibility("default"))) Result< EqvProfile > eqv_profile_from_name(const std const std::string & name

引用了 ExprParser(), apply_atan2(), apply_clamp(), apply_integral(), apply_limit(), apply_log(), apply_rootof(), fail(), function_node(), LMCAS::FunctionNode::Max, LMCAS::FunctionNode::Min, LMCAS::name , 以及 uninterpreted_function().

被这些函数引用 parse_call().

函数调用图:
这是这个函数的调用关系图:

◆ apply_integral()

ExprResult LMCAS::expr_detail::ExprParser::apply_integral ( const std::vector< ExprPtr > & arguments)
private

在文件 expr_parser_functions.cpp 第 75 行定义.

75 {
76 auto variable = std::dynamic_pointer_cast<const VariableNode>(
77 LMCAS::detail::node(arguments[1]));
78 if (!variable || variable->is_constant()) {
79 return fail("Integral variable must be a symbol");
80 }
81 try {
83 LMCAS::detail::node(arguments[0]), variable->name(),
84 arguments.size() == 4
85 ? LMCAS::detail::node(arguments[2])
86 : nullptr,
87 arguments.size() == 4
88 ? LMCAS::detail::node(arguments[3])
89 : nullptr);
91 LMCAS::detail::make_expression_ptr(std::move(node)));
92 } catch (const std::bad_alloc&) {
94 "Integral expression allocation failed",
96 } catch (const std::exception& error) {
98 }
99}
std::shared_ptr<::LMCAS::SymbolicExpr > make_expression_ptr(SymbolicNodePtr root)
const SymbolicNodePtr & node(const ::LMCAS::SymbolicExpr &expression) noexcept
std::shared_ptr< const Node > make_node(Args &&... args)
const std::string & variable

引用了 LMCAS::expr_detail::expr_common::expression_failure(), fail(), LMCAS::InternalInvariant, LMCAS::expr_detail::kParseOperation, LMCAS::detail::make_expression_ptr(), LMCAS::detail::make_node(), LMCAS::detail::node(), LMCAS::ResourceLimit, LMCAS::Result< ExprPtr >::success() , 以及 LMCAS::variable.

被这些函数引用 apply_function().

函数调用图:
这是这个函数的调用关系图:

◆ apply_limit()

ExprResult LMCAS::expr_detail::ExprParser::apply_limit ( const std::vector< ExprPtr > & arguments)
private

在文件 expr_parser_functions.cpp 第 101 行定义.

101 {
102 auto variable = std::dynamic_pointer_cast<const VariableNode>(
103 LMCAS::detail::node(arguments[1]));
104 auto direction = std::dynamic_pointer_cast<const VariableNode>(
105 LMCAS::detail::node(arguments[3]));
106 if (!variable || variable->is_constant() ||
107 !direction || direction->is_constant()) {
108 return fail("limit variable and direction must be symbols");
109 }
110 LimitDirection parsed_direction;
111 if (direction->name() == "both") {
112 parsed_direction = LimitDirection::Both;
113 } else if (direction->name() == "below" ||
114 direction->name() == "left" ||
115 direction->name() == "from_below") {
116 parsed_direction = LimitDirection::FromBelow;
117 } else if (direction->name() == "above" ||
118 direction->name() == "right" ||
119 direction->name() == "from_above") {
120 parsed_direction = LimitDirection::FromAbove;
121 } else {
122 return fail("invalid limit direction");
123 }
126 LMCAS::detail::node(arguments[0]), variable->name(),
127 LMCAS::detail::node(arguments[2]), parsed_direction)));
128}
const std::string const LimitExprPtr LimitDirection direction
LimitDirection
Direction from which a limit approaches its point.

引用了 LMCAS::Both, LMCAS::direction, fail(), LMCAS::FromAbove, LMCAS::FromBelow, LMCAS::detail::make_expression_ptr(), LMCAS::detail::make_node(), LMCAS::detail::node(), LMCAS::Result< ExprPtr >::success() , 以及 LMCAS::variable.

被这些函数引用 apply_function().

函数调用图:
这是这个函数的调用关系图:

◆ apply_log()

ExprResult LMCAS::expr_detail::ExprParser::apply_log ( const std::vector< ExprPtr > & arguments)
private

在文件 expr_parser_functions.cpp 第 47 行定义.

47 {
48 try {
49 auto result = SymbolicExpr::log(arguments[0], arguments[1]);
50 return ExprResult::success(std::move(result));
51 } catch (const std::bad_alloc&) {
53 "log expression allocation failed",
55 } catch (const std::exception& error) {
58 }
59}

引用了 LMCAS::expr_detail::expr_common::expression_failure(), LMCAS::InternalInvariant, LMCAS::expr_detail::kParseOperation, LMCAS::ResourceLimit , 以及 LMCAS::Result< ExprPtr >::success().

被这些函数引用 apply_function().

函数调用图:
这是这个函数的调用关系图:

◆ apply_rootof()

ExprResult LMCAS::expr_detail::ExprParser::apply_rootof ( const std::vector< ExprPtr > & arguments)
private

在文件 expr_parser_functions.cpp 第 130 行定义.

130 {
131 auto variable = std::dynamic_pointer_cast<const VariableNode>(
132 LMCAS::detail::node(arguments[1]));
133 auto index = std::dynamic_pointer_cast<const NumberNode>(
134 LMCAS::detail::node(arguments[2]));
135 if (!variable || variable->is_constant() || !index) {
136 return fail("RootOf variable and index are invalid");
137 }
138 BigInt index_value;
139 if (std::holds_alternative<BigInt>(index->value())) {
140 index_value = std::get<BigInt>(index->value());
141 } else {
142 const auto& rational = std::get<Rational>(index->value());
143 if (!rational.is_integer()) {
144 return fail("RootOf index must be an integer");
145 }
146 index_value = rational.to_bigint();
147 }
148 const auto converted = index_value.try_to_int64();
149 if (!converted || *converted < 0) {
150 return fail("RootOf index is negative or too large");
151 }
152 auto root = make_rootof_checked(
153 arguments[0], variable->name(),
154 static_cast<std::size_t>(*converted));
155 if (!root) {
156 return ExprResult::failure(root.error());
157 }
158 return ExprResult::success(std::move(root.value()));
159}
static Result failure(CasErrc code, std::string message, std::string operation={})
RootOfConstructionResult make_rootof_checked(const std::shared_ptr< SymbolicExpr > &polynomial, const std::string &variable, std::size_t index, ComputationContext &context)
ExprResult rational(const Rational &value)

引用了 fail(), LMCAS::Result< ExprPtr >::failure(), LMCAS::make_rootof_checked(), LMCAS::detail::node(), LMCAS::rational(), LMCAS::Result< ExprPtr >::success() , 以及 LMCAS::variable.

被这些函数引用 apply_function().

函数调用图:
这是这个函数的调用关系图:

◆ eof()

bool LMCAS::expr_detail::ExprParser::eof ( ) const
privatenoexcept

在文件 expr_parsing.cpp 第 28 行定义.

28{ return pos_ >= source_.size(); }

引用了 pos_ , 以及 source_.

被这些函数引用 parse(), parse_approx_literal(), peek() , 以及 skip_space().

这是这个函数的调用关系图:

◆ fail()

ExprResult LMCAS::expr_detail::ExprParser::fail ( std::string message) const
private

在文件 expr_parsing.cpp 第 72 行定义.

72 {
74 std::move(message) + " at byte " + std::to_string(pos_),
76}

引用了 LMCAS::expr_detail::expr_common::expression_failure(), LMCAS::expr_detail::kParseOperation, LMCAS::ParseError , 以及 pos_.

被这些函数引用 apply_function(), apply_integral(), apply_limit(), apply_rootof(), parse(), parse_approx_literal(), parse_call(), parse_identifier_or_call(), parse_interval_literal(), parse_multiplicative(), parse_number(), parse_power(), parse_primary() , 以及 parse_set_literal().

函数调用图:
这是这个函数的调用关系图:

◆ finite_set()

ExprResult LMCAS::expr_detail::ExprParser::finite_set ( const std::vector< ExprPtr > & elements)
private

在文件 expr_parser_construction.cpp 第 60 行定义.

60 {
61 for (const auto& element : elements) {
63 return invalid_construction("set elements cannot be null");
64 }
65 }
67 "set expression allocation failed", [&] {
68 std::vector<std::shared_ptr<const SymbolicNode>> nodes;
69 nodes.reserve(elements.size());
70 for (const auto& element : elements) {
71 nodes.push_back(LMCAS::detail::node(element));
72 }
73 return LMCAS::detail::make_node<FiniteSetNode>(std::move(nodes));
74 });
75}
ExprResult construct_expression(std::string allocation_message, Factory &&factory)
const ExprPtr & element

引用了 LMCAS::element, LMCAS::detail::make_node() , 以及 LMCAS::detail::node().

被这些函数引用 parse_set_literal().

函数调用图:
这是这个函数的调用关系图:

◆ function_node()

ExprResult LMCAS::expr_detail::ExprParser::function_node ( const std::string & name,
const std::vector< ExprPtr > & arguments,
FunctionNode::FuncType type )
private

在文件 expr_parser_construction.cpp 第 109 行定义.

111 {
112 for (const auto& argument : arguments) {
113 if (!argument || !LMCAS::detail::node(argument)) {
114 return invalid_construction("function arguments cannot be null");
115 }
116 }
118 name + " expression allocation failed", [&] {
119 std::vector<std::shared_ptr<const SymbolicNode>> nodes;
120 nodes.reserve(arguments.size());
121 for (const auto& argument : arguments) {
122 nodes.push_back(LMCAS::detail::node(argument));
123 }
125 type, std::move(nodes));
126 });
127}

引用了 LMCAS::detail::make_node(), LMCAS::name , 以及 LMCAS::detail::node().

被这些函数引用 apply_function().

函数调用图:
这是这个函数的调用关系图:

◆ interval()

ExprResult LMCAS::expr_detail::ExprParser::interval ( const ExprPtr & lower,
const ExprPtr & upper,
bool lower_closed,
bool upper_closed )
private

在文件 expr_parser_construction.cpp 第 77 行定义.

79 {
80 if (!lower || !upper) {
81 return invalid_construction("interval bounds cannot be null");
82 }
84 "interval expression allocation failed", [&] {
88 });
89}
__attribute__((visibility("default"))) ExprResult function(const std __attribute__((visibility("default"))) ExprResult finite_set(std ExprPtr upper
const ExprPtr & lower
__attribute__((visibility("default"))) ExprResult function(const std __attribute__((visibility("default"))) ExprResult finite_set(std ExprPtr bool lower_closed
__attribute__((visibility("default"))) ExprResult function(const std __attribute__((visibility("default"))) ExprResult finite_set(std ExprPtr bool bool upper_closed

引用了 LMCAS::lower, LMCAS::lower_closed, LMCAS::detail::make_node(), LMCAS::detail::node(), LMCAS::upper , 以及 LMCAS::upper_closed.

被这些函数引用 parse_interval_literal() , 以及 parse_primary().

函数调用图:
这是这个函数的调用关系图:

◆ is_ident_continue()

bool LMCAS::expr_detail::ExprParser::is_ident_continue ( unsigned char c)
staticprivatenoexcept

在文件 expr_parsing.cpp 第 82 行定义.

82 {
83 return std::isalnum(c) || c == '_' || c >= 0x80;
84}
const VectorField const VectorField & c

引用了 LMCAS::c.

被这些函数引用 match_keyword() , 以及 parse_identifier().

这是这个函数的调用关系图:

◆ is_ident_start()

bool LMCAS::expr_detail::ExprParser::is_ident_start ( unsigned char c)
staticprivatenoexcept

在文件 expr_parsing.cpp 第 78 行定义.

78 {
79 return std::isalpha(c) || c == '_' || c >= 0x80;
80}

引用了 LMCAS::c.

被这些函数引用 parse_identifier() , 以及 parse_primary().

这是这个函数的调用关系图:

◆ logical()

ExprResult LMCAS::expr_detail::ExprParser::logical ( const ExprPtr & lhs,
const ExprPtr & rhs,
LogicalNode::Op op )
private

在文件 expr_parser_construction.cpp 第 47 行定义.

48 {
49 if (!lhs || (op != LogicalNode::Op::Not && !rhs)) {
50 return invalid_construction("logical operands cannot be null");
51 }
53 "logical expression allocation failed", [&] {
56 rhs ? LMCAS::detail::node(rhs) : nullptr, op);
57 });
58}
@ Not
一元逻辑非,right 为 nullptr。
const ExprPtr RelationOp op
const ExprPtr & rhs

引用了 LMCAS::detail::make_node(), LMCAS::detail::node(), LMCAS::LogicalNode::Not, LMCAS::op , 以及 LMCAS::rhs.

被这些函数引用 parse_logical_and(), parse_logical_not() , 以及 parse_logical_or().

函数调用图:
这是这个函数的调用关系图:

◆ match()

bool LMCAS::expr_detail::ExprParser::match ( char c)
private

在文件 expr_parsing.cpp 第 34 行定义.

34 {
35 skip_space();
36 if (peek() != c) { return false; }
37 ++pos_;
38 return true;
39}
char peek() const noexcept
void skip_space() noexcept

引用了 LMCAS::c, peek(), pos_ , 以及 skip_space().

被这些函数引用 parse_additive(), parse_approx_literal(), parse_call(), parse_identifier_or_call(), parse_interval_literal(), parse_logical_not(), parse_multiplicative(), parse_power(), parse_primary(), parse_relational(), parse_set_literal() , 以及 parse_unary().

函数调用图:
这是这个函数的调用关系图:

◆ match_keyword()

bool LMCAS::expr_detail::ExprParser::match_keyword ( const char * text)
private

在文件 expr_parsing.cpp 第 54 行定义.

54 {
55 skip_space();
56 const std::size_t start = pos_;
57 if (!match_text(text)) { return false; }
58 if (is_ident_continue(static_cast<unsigned char>(peek()))) {
59 pos_ = start;
60 return false;
61 }
62 return true;
63}
static bool is_ident_continue(unsigned char c) noexcept
bool match_text(const char *text)

引用了 is_ident_continue(), match_text(), peek(), pos_ , 以及 skip_space().

被这些函数引用 parse_logical_and(), parse_logical_not(), parse_logical_or() , 以及 parse_membership().

函数调用图:
这是这个函数的调用关系图:

◆ match_text()

bool LMCAS::expr_detail::ExprParser::match_text ( const char * text)
private

在文件 expr_parsing.cpp 第 41 行定义.

41 {
42 skip_space();
43 const std::size_t start = pos_;
44 for (const char* p = text; *p; ++p) {
45 if (pos_ >= source_.size() || source_[pos_] != *p) {
46 pos_ = start;
47 return false;
48 }
49 ++pos_;
50 }
51 return true;
52}

引用了 pos_, skip_space() , 以及 source_.

被这些函数引用 match_keyword(), parse_equality(), parse_multiplicative(), parse_power() , 以及 parse_relational().

函数调用图:
这是这个函数的调用关系图:

◆ membership()

ExprResult LMCAS::expr_detail::ExprParser::membership ( const ExprPtr & element,
const ExprPtr & set,
bool negated )
private

在文件 expr_parser_construction.cpp 第 91 行定义.

92 {
93 if (!element || !set) {
94 return invalid_construction("membership operands cannot be null");
95 }
97 "membership expression allocation failed", [&] {
98 std::shared_ptr<const SymbolicNode> node =
101 if (negated) {
103 std::move(node), nullptr, LogicalNode::Op::Not);
104 }
105 return node;
106 });
107}
const ExprPtr & set
const ExprPtr bool negated

引用了 LMCAS::element, LMCAS::detail::make_node(), LMCAS::negated, LMCAS::detail::node(), LMCAS::LogicalNode::Not , 以及 LMCAS::set.

被这些函数引用 parse_membership().

函数调用图:
这是这个函数的调用关系图:

◆ parse()

在文件 expr_parsing.cpp 第 14 行定义.

14 {
15 skip_space();
16 if (eof()) {
17 return fail("empty expression");
18 }
19 auto result = parse_logical_or();
20 if (!result) { return result; }
21 skip_space();
22 if (!eof()) {
23 return fail("unexpected token '" + std::string(1, peek()) + "'");
24 }
25 return result;
26}
ExprResult parse_logical_or()
bool eof() const noexcept
ExprResult fail(std::string message) const

引用了 eof(), fail(), parse_logical_or(), peek() , 以及 skip_space().

函数调用图:

◆ parse_additive()

在文件 expr_parsing.cpp 第 181 行定义.

181 {
182 auto lhs = parse_multiplicative();
183 if (!lhs) { return lhs; }
184 while (true) {
185 if (match('+')) {
186 auto rhs = parse_multiplicative();
187 if (!rhs) { return rhs; }
188 lhs = add(lhs.value(), rhs.value());
189 } else if (match('-')) {
190 auto rhs = parse_multiplicative();
191 if (!rhs) { return rhs; }
192 lhs = sub(lhs.value(), rhs.value());
193 } else {
194 return lhs;
195 }
196 if (!lhs) { return lhs; }
197 }
198}
ExprResult parse_multiplicative()
ExprResult sub(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)
ExprResult add(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)

引用了 LMCAS::add(), match(), parse_multiplicative(), LMCAS::rhs , 以及 LMCAS::sub().

被这些函数引用 parse_relational().

函数调用图:
这是这个函数的调用关系图:

◆ parse_approx_literal()

在文件 expr_parsing.cpp 第 358 行定义.

358 {
359 skip_space();
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");
366 if (!value) return fail(value.error().message);
367 return approx_real(value.value());
368}
Result< double > parse_finite_decimal(std::string_view token)
ExprResult approx_real(double value)
const std::string const ExprPtr & value

引用了 LMCAS::approx_real(), eof(), fail(), match(), LMCAS::detail::parse_finite_decimal(), peek(), pos_, skip_space(), source_ , 以及 LMCAS::value.

被这些函数引用 parse_call().

函数调用图:
这是这个函数的调用关系图:

◆ parse_call()

ExprResult LMCAS::expr_detail::ExprParser::parse_call ( const std::string & name)
private

在文件 expr_parsing.cpp 第 370 行定义.

370 {
371 if (name == "approx") return parse_approx_literal();
372 std::vector<ExprPtr> arguments;
373 bool closed = match(')');
374 if (!closed) {
375 do {
376 auto argument = parse_logical_or();
377 if (!argument) {
378 return argument;
379 }
380 arguments.push_back(argument.value());
381 if (match(')')) {
382 closed = true;
383 break;
384 }
385 } while (match(','));
386 }
387 if (!closed) {
388 return fail("expected ')'");
389 }
390 return apply_function(name, arguments);
391}
ExprResult apply_function(const std::string &name, const std::vector< ExprPtr > &arguments)
ExprResult parse_approx_literal()

引用了 apply_function(), fail(), match(), LMCAS::name, parse_approx_literal() , 以及 parse_logical_or().

被这些函数引用 parse_identifier_or_call().

函数调用图:
这是这个函数的调用关系图:

◆ parse_equality()

在文件 expr_parsing.cpp 第 139 行定义.

139 {
140 auto lhs = parse_relational();
141 if (!lhs) { return lhs; }
142 while (true) {
144 if (match_text("==")) {
146 } else if (match_text("!=")) {
148 } else {
149 return lhs;
150 }
151 auto rhs = parse_relational();
152 if (!rhs) { return rhs; }
153 lhs = relational(lhs.value(), rhs.value(), op);
154 if (!lhs) { return lhs; }
155 }
156}
ExprResult relational(const ExprPtr &lhs, const ExprPtr &rhs, RelationOp op)
RelationOp
Stable relational operator used by public APIs.

引用了 LMCAS::EQ, match_text(), LMCAS::NEQ, LMCAS::op, parse_relational(), relational() , 以及 LMCAS::rhs.

被这些函数引用 parse_membership().

函数调用图:
这是这个函数的调用关系图:

◆ parse_identifier()

在文件 expr_parsing.cpp 第 349 行定义.

349 {
350 skip_space();
351 const std::size_t start = pos_;
352 if (!is_ident_start(static_cast<unsigned char>(peek()))) { return {}; }
353 ++pos_;
354 while (is_ident_continue(static_cast<unsigned char>(peek()))) ++pos_;
355 return source_.substr(start, pos_ - start);
356}
static bool is_ident_start(unsigned char c) noexcept

引用了 is_ident_continue(), is_ident_start(), peek(), pos_, skip_space() , 以及 source_.

被这些函数引用 parse_identifier_or_call().

函数调用图:
这是这个函数的调用关系图:

◆ parse_identifier_or_call()

在文件 expr_parsing.cpp 第 393 行定义.

393 {
394 auto name = parse_identifier();
395 if (name.empty()) {
396 return fail("expected identifier");
397 }
398 skip_space();
399 if (match('(')) {
400 return parse_call(name);
401 }
402 if (name == "pi" || name == "π") {
403 return pi();
404 }
405 if (name == "e") {
406 return e();
407 }
408 if (name == "phi") {
409 return phi();
410 }
412 return imaginary_unit();
413 }
414 return sym(name);
415}
ExprResult parse_call(const std::string &name)
std::string parse_identifier()
bool is_imaginary_unit_name(const std::string &name)
ExprResult imaginary_unit()
ExprResult e()
ExprResult sym(const std::string &name)
ExprResult pi()
ExprResult phi()

引用了 LMCAS::e(), fail(), LMCAS::imaginary_unit(), LMCAS::detail::is_imaginary_unit_name(), match(), LMCAS::name, parse_call(), parse_identifier(), LMCAS::phi(), LMCAS::pi(), skip_space() , 以及 LMCAS::sym().

被这些函数引用 parse_primary().

函数调用图:
这是这个函数的调用关系图:

◆ parse_interval_literal()

在文件 expr_parsing.cpp 第 288 行定义.

288 {
289 auto lower = parse_logical_or();
290 if (!lower) { return lower; }
291 if (!match(',')) { return fail("expected ',' in interval literal"); }
292 auto upper = parse_logical_or();
293 if (!upper) { return upper; }
294 bool upper_closed;
295 if (match(']')) {
296 upper_closed = true;
297 } else if (match(')')) {
298 upper_closed = false;
299 } else {
300 return fail("expected ']' or ')' after interval literal");
301 }
302 return interval(lower.value(), upper.value(), lower_closed, upper_closed);
303}
ExprResult interval(const ExprPtr &lower, const ExprPtr &upper, bool lower_closed, bool upper_closed)

引用了 fail(), interval(), LMCAS::lower, LMCAS::lower_closed, match(), parse_logical_or(), LMCAS::upper, LMCAS::upper_closed , 以及 LMCAS::Result< T >::value().

被这些函数引用 parse_primary().

函数调用图:
这是这个函数的调用关系图:

◆ parse_logical_and()

在文件 expr_parsing.cpp 第 98 行定义.

98 {
99 auto lhs = parse_logical_not();
100 if (!lhs) { return lhs; }
101 while (match_keyword("and")) {
102 auto rhs = parse_logical_not();
103 if (!rhs) { return rhs; }
104 lhs = logical(lhs.value(), rhs.value(), LogicalNode::Op::And);
105 if (!lhs) { return lhs; }
106 }
107 return lhs;
108}
ExprResult logical(const ExprPtr &lhs, const ExprPtr &rhs, LogicalNode::Op op)
bool match_keyword(const char *text)

引用了 LMCAS::LogicalNode::And, logical(), match_keyword(), parse_logical_not() , 以及 LMCAS::rhs.

被这些函数引用 parse_logical_or().

函数调用图:
这是这个函数的调用关系图:

◆ parse_logical_not()

在文件 expr_parsing.cpp 第 110 行定义.

110 {
111 if (match_keyword("not") || match('!')) {
112 auto operand = parse_logical_not();
113 if (!operand) { return operand; }
114 return logical(operand.value(), nullptr, LogicalNode::Op::Not);
115 }
116 return parse_membership();
117}

引用了 logical(), match(), match_keyword(), LMCAS::LogicalNode::Not, parse_logical_not() , 以及 parse_membership().

被这些函数引用 parse_logical_and() , 以及 parse_logical_not().

函数调用图:
这是这个函数的调用关系图:

◆ parse_logical_or()

在文件 expr_parsing.cpp 第 86 行定义.

86 {
87 auto lhs = parse_logical_and();
88 if (!lhs) { return lhs; }
89 while (match_keyword("or")) {
90 auto rhs = parse_logical_and();
91 if (!rhs) { return rhs; }
92 lhs = logical(lhs.value(), rhs.value(), LogicalNode::Op::Or);
93 if (!lhs) { return lhs; }
94 }
95 return lhs;
96}
ExprResult parse_logical_and()

引用了 logical(), match_keyword(), LMCAS::LogicalNode::Or, parse_logical_and() , 以及 LMCAS::rhs.

被这些函数引用 parse(), parse_call(), parse_interval_literal(), parse_primary() , 以及 parse_set_literal().

函数调用图:
这是这个函数的调用关系图:

◆ parse_membership()

在文件 expr_parsing.cpp 第 119 行定义.

119 {
120 auto lhs = parse_equality();
121 if (!lhs) { return lhs; }
122 if (match_keyword("in")) {
123 auto rhs = parse_equality();
124 if (!rhs) { return rhs; }
125 return membership(lhs.value(), rhs.value(), false);
126 }
127 const auto save = pos_;
128 if (match_keyword("not")) {
129 if (match_keyword("in")) {
130 auto rhs = parse_equality();
131 if (!rhs) { return rhs; }
132 return membership(lhs.value(), rhs.value(), true);
133 }
134 pos_ = save;
135 }
136 return lhs;
137}
ExprResult membership(const ExprPtr &element, const ExprPtr &set, bool negated)

引用了 match_keyword(), membership(), parse_equality(), pos_ , 以及 LMCAS::rhs.

被这些函数引用 parse_logical_not().

函数调用图:
这是这个函数的调用关系图:

◆ parse_multiplicative()

在文件 expr_parsing.cpp 第 200 行定义.

200 {
201 auto lhs = parse_power();
202 if (!lhs) { return lhs; }
203 while (true) {
204 if (match_text("**")) {
205 return fail("operator '**' is not supported; use '^'");
206 } else if (match('*')) {
207 auto rhs = parse_power();
208 if (!rhs) { return rhs; }
209 lhs = mul(lhs.value(), rhs.value());
210 } else if (match('/')) {
211 auto rhs = parse_power();
212 if (!rhs) { return rhs; }
213 lhs = div(lhs.value(), rhs.value());
214 } else {
215 return lhs;
216 }
217 if (!lhs) { return lhs; }
218 }
219}
ExprResult div(const ExprPtr &numerator, const ExprPtr &denominator, ComputationContext &context)
ExprResult mul(const ExprPtr &lhs, const ExprPtr &rhs, ComputationContext &context)

引用了 LMCAS::div(), fail(), match(), match_text(), LMCAS::mul(), parse_power() , 以及 LMCAS::rhs.

被这些函数引用 parse_additive().

函数调用图:
这是这个函数的调用关系图:

◆ parse_number()

在文件 expr_parsing.cpp 第 305 行定义.

305 {
306 skip_space();
307 const std::size_t start = pos_;
308 bool saw_digit = false;
309 while (std::isdigit(static_cast<unsigned char>(peek()))) {
310 saw_digit = true;
311 ++pos_;
312 }
313 if (peek() == '.') {
314 ++pos_;
315 while (std::isdigit(static_cast<unsigned char>(peek()))) {
316 saw_digit = true;
317 ++pos_;
318 }
319 }
320 if (!saw_digit) { return fail("invalid number literal"); }
321 if (peek() == 'e' || peek() == 'E') {
322 ++pos_;
323 if (peek() == '+' || peek() == '-') ++pos_;
324 bool saw_exp_digit = false;
325 while (std::isdigit(static_cast<unsigned char>(peek()))) {
326 saw_exp_digit = true;
327 ++pos_;
328 }
329 if (!saw_exp_digit) { return fail("invalid number exponent"); }
330 }
331 try {
332 return rational(Rational(source_.substr(start, pos_ - start)));
333 } catch (const std::bad_alloc&) {
335 "number literal allocation failed",
337 } catch (const std::invalid_argument& error) {
339 CasErrc::ParseError, error.what(), kParseOperation);
340 } catch (const std::out_of_range& error) {
342 CasErrc::ParseError, error.what(), kParseOperation);
343 } catch (const std::exception& error) {
346 }
347}
@ Rational
Rational numbers

引用了 LMCAS::expr_detail::expr_common::expression_failure(), fail(), LMCAS::InternalInvariant, LMCAS::expr_detail::kParseOperation, LMCAS::ParseError, peek(), pos_, LMCAS::rational(), LMCAS::ResourceLimit, skip_space() , 以及 source_.

被这些函数引用 parse_primary().

函数调用图:
这是这个函数的调用关系图:

◆ parse_power()

在文件 expr_parsing.cpp 第 221 行定义.

221 {
222 auto base = parse_unary();
223 if (!base) { return base; }
224 if (match_text("**")) {
225 return fail("operator '**' is not supported; use '^'");
226 }
227 if (match('^')) {
228 auto exponent = parse_power();
229 if (!exponent) { return exponent; }
230 return pow(base.value(), exponent.value());
231 }
232 return base;
233}
ExprResult pow(const ExprPtr &base, const ExprPtr &exponent, ComputationContext &context)
const ExprPtr & exponent

引用了 LMCAS::exponent, fail(), match(), match_text(), parse_power(), parse_unary() , 以及 LMCAS::pow().

被这些函数引用 parse_multiplicative() , 以及 parse_power().

函数调用图:
这是这个函数的调用关系图:

◆ parse_primary()

在文件 expr_parsing.cpp 第 245 行定义.

245 {
246 skip_space();
247 if (match('(')) {
248 auto inner = parse_logical_or();
249 if (!inner) { return inner; }
250 if (match(',')) {
251 auto rhs = parse_logical_or();
252 if (!rhs) { return rhs; }
253 if (!match(')')) { return fail("expected ')' after interval"); }
254 return interval(inner.value(), rhs.value(), false, false);
255 }
256 if (!match(')')) { return fail("expected ')'"); }
257 return inner;
258 }
259 if (match('{')) {
260 return parse_set_literal();
261 }
262 if (match('[')) {
263 return parse_interval_literal(true);
264 }
265 if (std::isdigit(static_cast<unsigned char>(peek())) || peek() == '.') {
266 return parse_number();
267 }
268 if (is_ident_start(static_cast<unsigned char>(peek()))) {
270 }
271 return fail("expected expression");
272}
ExprResult parse_identifier_or_call()
ExprResult parse_interval_literal(bool lower_closed)

引用了 fail(), interval(), is_ident_start(), match(), parse_identifier_or_call(), parse_interval_literal(), parse_logical_or(), parse_number(), parse_set_literal(), peek(), LMCAS::rhs , 以及 skip_space().

被这些函数引用 parse_unary().

函数调用图:
这是这个函数的调用关系图:

◆ parse_relational()

在文件 expr_parsing.cpp 第 158 行定义.

158 {
159 auto lhs = parse_additive();
160 if (!lhs) { return lhs; }
161 while (true) {
163 if (match_text("<=")) {
165 } else if (match_text(">=")) {
167 } else if (match('<')) {
169 } else if (match('>')) {
171 } else {
172 return lhs;
173 }
174 auto rhs = parse_additive();
175 if (!rhs) { return rhs; }
176 lhs = relational(lhs.value(), rhs.value(), op);
177 if (!lhs) { return lhs; }
178 }
179}

引用了 LMCAS::GEQ, LMCAS::GT, LMCAS::LEQ, LMCAS::LT, match(), match_text(), LMCAS::op, parse_additive(), relational() , 以及 LMCAS::rhs.

被这些函数引用 parse_equality().

函数调用图:
这是这个函数的调用关系图:

◆ parse_set_literal()

在文件 expr_parsing.cpp 第 274 行定义.

274 {
275 std::vector<ExprPtr> elements;
276 if (!match('}')) {
277 while (true) {
278 auto element = parse_logical_or();
279 if (!element) { return element; }
280 elements.push_back(element.value());
281 if (match('}')) break;
282 if (!match(',')) { return fail("expected ',' or '}' in set literal"); }
283 }
284 }
285 return finite_set(elements);
286}
ExprResult finite_set(const std::vector< ExprPtr > &elements)

引用了 LMCAS::element, fail(), finite_set(), match() , 以及 parse_logical_or().

被这些函数引用 parse_primary().

函数调用图:
这是这个函数的调用关系图:

◆ parse_unary()

在文件 expr_parsing.cpp 第 235 行定义.

235 {
236 if (match('+')) { return parse_unary(); }
237 if (match('-')) {
238 auto operand = parse_unary();
239 if (!operand) { return operand; }
240 return neg(operand.value());
241 }
242 return parse_primary();
243}
ExprResult neg(const ExprPtr &expression, ComputationContext &context)

引用了 match(), LMCAS::neg(), parse_primary() , 以及 parse_unary().

被这些函数引用 parse_power() , 以及 parse_unary().

函数调用图:
这是这个函数的调用关系图:

◆ peek()

char LMCAS::expr_detail::ExprParser::peek ( ) const
privatenoexcept

在文件 expr_parsing.cpp 第 30 行定义.

30 {
31 return eof() ? '\0' : source_[pos_];
32}

引用了 eof(), pos_ , 以及 source_.

被这些函数引用 match(), match_keyword(), parse(), parse_approx_literal(), parse_identifier(), parse_number() , 以及 parse_primary().

函数调用图:
这是这个函数的调用关系图:

◆ relational()

ExprResult LMCAS::expr_detail::ExprParser::relational ( const ExprPtr & lhs,
const ExprPtr & rhs,
RelationOp op )
private

在文件 expr_parser_construction.cpp 第 35 行定义.

36 {
37 if (!lhs || !rhs) {
38 return invalid_construction("relational operands cannot be null");
39 }
41 "relational expression allocation failed", [&] {
44 });
45}

引用了 LMCAS::detail::make_node(), LMCAS::detail::node(), LMCAS::op , 以及 LMCAS::rhs.

被这些函数引用 parse_equality() , 以及 parse_relational().

函数调用图:
这是这个函数的调用关系图:

◆ skip_space()

在文件 expr_parsing.cpp 第 65 行定义.

65 {
66 while (!eof() &&
67 std::isspace(static_cast<unsigned char>(source_[pos_]))) {
68 ++pos_;
69 }
70}

引用了 eof(), pos_ , 以及 source_.

被这些函数引用 match(), match_keyword(), match_text(), parse(), parse_approx_literal(), parse_identifier(), parse_identifier_or_call(), parse_number() , 以及 parse_primary().

函数调用图:
这是这个函数的调用关系图:

◆ uninterpreted_function()

ExprResult LMCAS::expr_detail::ExprParser::uninterpreted_function ( const std::string & name,
const std::vector< ExprPtr > & arguments )
private

在文件 expr_parser_functions.cpp 第 208 行定义.

209 {
210 try {
211 std::vector<std::shared_ptr<const SymbolicNode>> nodes;
212 nodes.reserve(arguments.size());
213 for (const auto& argument : arguments) {
214 if (!argument || !LMCAS::detail::node(argument)) {
216 "function arguments cannot be null",
218 }
219 nodes.push_back(LMCAS::detail::node(argument));
220 }
222 name, std::move(nodes));
224 } catch (const std::bad_alloc&) {
226 "function expression allocation failed",
228 } catch (const std::exception& error) {
231 }
232}

引用了 LMCAS::expr_detail::expr_common::expression_failure(), LMCAS::InternalInvariant, LMCAS::InvalidArgument, LMCAS::expr_detail::kParseOperation, LMCAS::detail::make_expression_ptr(), LMCAS::detail::make_node(), LMCAS::name, LMCAS::detail::node(), LMCAS::ResourceLimit , 以及 LMCAS::Result< ExprPtr >::success().

被这些函数引用 apply_function().

函数调用图:
这是这个函数的调用关系图:

类成员变量说明

◆ pos_

std::size_t LMCAS::expr_detail::ExprParser::pos_ = 0
private

◆ source_

std::string LMCAS::expr_detail::ExprParser::source_
private

该类的文档由以下文件生成: