libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
SourceSyntax Namespace Reference

printf 降级阶段共享的描述表与策略辅助函数 / Shared descriptor-table and policy helpers for printf lowering More...

Data Structures

struct  IndexingState
 brace 字段自动索引与手动索引的源级状态 / Source-level indexing mode for automatic versus manual brace fields More...
 
struct  ResolvedArgumentVisitor
 将已解析转换解析成最终源顺序参数元信息摘要的 visitor / Visitor that resolves parsed conversions into the final source-ordered argument metadata summary More...
 
struct  SourceAnalysis
 单条 brace 风格格式字面量的仅源串分析数据 / Source-only analysis data for one brace-style format literal More...
 
struct  SourceAnalysisScratch
 仅源串分析阶段使用的保守临时累加器 / Conservative temporary accumulator used during source-only analysis More...
 

Functions

constexpr bool IsDigit (char ch)
 brace 风格语法的源串解析辅助函数 / Source parser helpers for the brace-style grammar
 
constexpr bool IsAlign (char ch)
 判断一个源字符是否为合法的 brace 格式对齐标记 / Return whether one source character is a valid brace-format align token
 
constexpr Align ParseAlign (char ch)
 将一个 brace 格式对齐字符转换为前端枚举值 / Convert one brace-format align token to the frontend enum value
 
constexpr bool HasEmbeddedNul (std::string_view source)
 判断源字符串在终止前是否包含嵌入式 NUL / Return whether the source contains an embedded NUL before the terminator
 
constexpr bool IsSupportedPresentation (char ch)
 判断一个展示字符是否被 brace 前端支持 / Return whether one presentation token is supported by the brace frontend
 
template<typename UInt >
consteval Error ParseUnsigned (std::string_view source, size_t &pos, UInt limit, UInt &value)
 解析一个十进制整数字段片段,并检查是否溢出 / Parse one decimal integer fragment with overflow checking
 
consteval Error ParseFieldHead (std::string_view source, size_t &pos, IndexingState &indexing, ParsedField &field)
 解析 :} 之前的字段头,包括自动或手动参数索引选择 / Parse the field head before : or }, including automatic or manual argument index selection
 
consteval Error ParseFormatSpec (std::string_view source, size_t &pos, ParsedField &field)
 解析一个 brace 字段中 : 之后的可选 format-spec 部分 / Parse the optional format-spec portion after : inside one brace field
 
consteval Error ParseField (std::string_view source, size_t &pos, IndexingState &indexing, ParsedField &field)
 解析一个完整 brace 字段,从 { 一直到匹配的 } / Parse one complete brace field from { through the matching }
 
consteval Error WalkSource (std::string_view source, auto &visitor)
 遍历一个 brace 源字符串,并发射字面文本片段与已解析字段 / Walk one brace source string and emit literal-text spans plus parsed fields
 
template<Text Source>
consteval auto Analyze ()
 对一个 brace 字面量执行仅源串分析,并返回按顺序整理的参数索引摘要 / Run source-only analysis for one brace literal and return the ordered argument-index summary
 
consteval Error ParseArgumentIndex (std::string_view source, size_t &pos, IndexingState &indexing, Conversion &conversion)
 解析可选的前导 n$ 位置参数选择器 / Parse the optional leading n$ positional argument selector
 
consteval Error ParseByte (std::string_view source, size_t &pos, uint8_t limit, uint8_t &value)
 解析一个目标为字节宽度的十进制整数字段片段,并检查是否溢出 / Parse one decimal byte-sized integer fragment with overflow checking
 
consteval Error ParseFlags (std::string_view source, size_t &pos, Conversion &conversion)
 单个 printf 转换体的源级解析器 / Source parser for one printf conversion body
 
consteval Error ParseWidth (std::string_view source, size_t &pos, Conversion &conversion)
 解析一个可选的常量宽度字段 / Parse one optional constant width field
 
consteval Error ParsePrecision (std::string_view source, size_t &pos, Conversion &conversion)
 解析一个可选的常量精度字段 / Parse one optional constant precision field
 
consteval void ParseLength (std::string_view source, size_t &pos, Conversion &conversion)
 解析一个可选的长度修饰符序列 / Parse one optional length modifier sequence
 
consteval Error ParseSpecifier (std::string_view source, size_t &pos, Conversion &conversion)
 解析并校验最终的转换说明符字符 / Parse and validate the final conversion specifier token
 
consteval Error Parse (std::string_view source, size_t &pos, IndexingState &indexing, Conversion &conversion)
 在前导 % 之后解析一个完整 printf 转换项 / Parse one complete printf conversion after the leading %
 

Detailed Description

printf 降级阶段共享的描述表与策略辅助函数 / Shared descriptor-table and policy helpers for printf lowering

为一个已解析 printf 转换选择运行期语义类型 / Choose the runtime semantic type for one parsed printf conversion

Function Documentation

◆ Analyze()

template<Text Source>
auto SourceSyntax::Analyze ( )
nodiscardconsteval

对一个 brace 字面量执行仅源串分析,并返回按顺序整理的参数索引摘要 / Run source-only analysis for one brace literal and return the ordered argument-index summary

对一个 printf 字面量执行仅源串分析,并返回按顺序整理的参数引用摘要 / Run source-only analysis for one printf literal and return the ordered argument-reference summary

Template Parameters
Sourcebrace 风格格式串字面量 / Brace-style format literal
Returns
源串分析结果,包含字段顺序、所需参数个数与首个源级错误 / Returns the source analysis result, including field order, required argument count, and the first source-level error
Template Parameters
Sourceprintf 风格格式串字面量 / Printf-style format literal
Returns
源串分析结果,包含字段顺序、参数引用摘要与首个源级错误 / Returns the source analysis result, including field order, argument reference summary, and the first source-level error

Definition at line 140 of file format_frontend_source.hpp.

141{
142 constexpr auto scratch = []() consteval {
143 SourceAnalysisScratch<Source.Size()> visitor{};
144 visitor.error = WalkSource(std::string_view(Source.Data(), Source.Size()), visitor);
145 return visitor;
146 }();
147
148 SourceAnalysis<scratch.field_count> result{};
149 result.required_argument_count = scratch.required_argument_count;
150 result.error = scratch.error;
151 for (size_t i = 0; i < scratch.field_count; ++i)
152 {
153 result.argument_order[i] = scratch.order[i];
154 }
155 return result;
156}
仅源串分析阶段使用的保守临时累加器 / Conservative temporary accumulator used during source-only analysis
Error error
first parse error / 首个解析错误

◆ HasEmbeddedNul()

bool SourceSyntax::HasEmbeddedNul ( std::string_view source)
nodiscardconstexpr

判断源字符串在终止前是否包含嵌入式 NUL / Return whether the source contains an embedded NUL before the terminator

判断源字符串在结尾终止字节之前是否包含嵌入式 NUL / Return whether the source contains an embedded NUL byte before the terminator

Parameters
source待检查的源字符串 / Source string to inspect
Returns
若终止前包含 \\0 则返回 true,否则返回 false / Returns true when \\0 appears before the terminator, otherwise false
Parameters
source待检查的源字符串 / Source string to inspect
Returns
若终止前包含嵌入式 NUL 则返回 true,否则返回 false / Returns true when an embedded NUL exists before the terminator, otherwise false

Definition at line 52 of file format_frontend_source.hpp.

52{
53 if (HasEmbeddedNul(source))
54 {
55 return Error::EmbeddedNul;
56 }
57
58 size_t pos = 0;
59 size_t text_begin = 0;
60 IndexingState indexing{};
61
62 while (pos < source.size())
brace 字段自动索引与手动索引的源级状态 / Source-level indexing mode for automatic versus manual brace fields

◆ IsAlign()

bool SourceSyntax::IsAlign ( char ch)
nodiscardconstexpr

判断一个源字符是否为合法的 brace 格式对齐标记 / Return whether one source character is a valid brace-format align token

Parameters
ch待检查的源字符 / Source character to inspect
Returns
合法对齐字符返回 true,否则返回 false / Returns true for a valid align token, otherwise false

Definition at line 22 of file format_frontend_source.hpp.

23{
24 std::array<size_t, MaxFieldCount> order{};
25 size_t field_count = 0;

◆ IsDigit()

bool SourceSyntax::IsDigit ( char ch)
nodiscardconstexpr

brace 风格语法的源串解析辅助函数 / Source parser helpers for the brace-style grammar

判断一个源字节是否为 ASCII 十进制数字 / Return whether one source byte is an ASCII decimal digit

判断一个源字节是否为 ASCII 十进制数字 / Return whether one source byte is an ASCII decimal digit

Parameters
ch待检查的源字节 / Source byte to inspect
Returns
若是 ASCII 十进制数字则返回 true,否则返回 false / Returns true for an ASCII decimal digit, otherwise false
Parameters
ch待检查的源字节 / Source byte to test
Returns
若是 ASCII 十进制数字则返回 true,否则返回 false / Returns true for an ASCII decimal digit, otherwise false

Definition at line 12 of file format_frontend_source.hpp.

12 {};
13 size_t required_argument_count = 0;
14 Error error = Error::None;
15};

◆ IsSupportedPresentation()

bool SourceSyntax::IsSupportedPresentation ( char ch)
nodiscardconstexpr

判断一个展示字符是否被 brace 前端支持 / Return whether one presentation token is supported by the brace frontend

Parameters
ch展示字符 / Presentation token
Returns
支持返回 true,否则返回 false / Returns true when the token is supported, otherwise false

Definition at line 69 of file format_frontend_source.hpp.

70 {
71 return error;
72 }
73 error = visitor.Text(pos, 1);
74 if (error != Error::None)
75 {
76 return error;
77 }
78 pos += 2;
79 text_begin = pos;
80 continue;
81 }
82
83 auto error = visitor.Text(text_begin, pos - text_begin);
84 if (error != Error::None)
85 {
86 return error;
87 }
88
89 ParsedField field{};
90 error = ParseField(source, pos, indexing, field);
91 if (error != Error::None)
92 {

◆ Parse()

Error SourceSyntax::Parse ( std::string_view source,
size_t & pos,
IndexingState & indexing,
Conversion & conversion )
nodiscardconsteval

在前导 % 之后解析一个完整 printf 转换项 / Parse one complete printf conversion after the leading %

Parameters
source完整 printf 源字符串 / Full printf source string
pos当前解析位置,进入时应指向 %,成功时推进到该转换项之后 / Current parse position; must point at % on entry and lands after the conversion on success
indexing源级索引模式跟踪状态 / Source-level indexing mode tracker
conversion输出转换项结果 / Conversion result output
Returns
成功返回 Error::None;解析或校验失败时返回对应错误 / Returns Error::None on success, or the first parse or validation failure

Definition at line 207 of file printf_frontend_source.hpp.

◆ ParseAlign()

Align SourceSyntax::ParseAlign ( char ch)
nodiscardconstexpr

将一个 brace 格式对齐字符转换为前端枚举值 / Convert one brace-format align token to the frontend enum value

Parameters
ch对齐字符 / Align token
Returns
对应的 Align 枚举;未知字符返回 Align::None / Returns the corresponding Align enum; unknown tokens map to Align::None

Definition at line 32 of file format_frontend_source.hpp.

32 {
33 order[field_count++] = field.arg_index;
34 size_t used_argument_count = field.arg_index + 1;
35 if (used_argument_count > required_argument_count)
36 {
37 required_argument_count = used_argument_count;
38 }
39 return Error::None;
40 }
41};
42
43#include "format_frontend_parser.hpp"
44

◆ ParseArgumentIndex()

Error SourceSyntax::ParseArgumentIndex ( std::string_view source,
size_t & pos,
IndexingState & indexing,
Conversion & conversion )
nodiscardconsteval

解析可选的前导 n$ 位置参数选择器 / Parse the optional leading n$ positional argument selector

This probe only consumes digits when they are immediately followed by '$'. Plain width digits such as %05d stay untouched for the later width parser. 只有当数字后面紧跟 '$' 时,这个探测才会真正消费它们;像 %05d 这样的普通宽度 数字会完整保留给后续宽度解析阶段。

Parameters
source完整 printf 源字符串 / Full printf source string
pos当前解析位置,成功时推进到 n$ 之后 / Current parse position; advanced past n$ on success
indexing源级索引模式跟踪状态 / Source-level indexing mode tracker
conversion当前正在填充的转换项 / Conversion being filled
Returns
解析成功或本段没有位置参数选择器时返回 Error::None;出错时返回首个解析错误 / Returns the first parse error, or Error::None when no positional selector is present or parsing succeeds

Definition at line 54 of file printf_frontend_source.hpp.

54{
56
57 [[nodiscard]] consteval Error Text(size_t, size_t) const { return Error::None; }
58
59 [[nodiscard]] consteval Error Field(const Conversion& conversion)
60 {
61 auto field = FieldSelection::BuildFormatField(conversion);
62 auto info = FormatArgumentInfo{
63 .pack = field.pack,
64 .rule = field.rule,
65 };
66 auto& slot = analysis.args[conversion.arg_index];
67 if (slot.rule != FormatArgumentRule::None &&
68 (slot.rule != info.rule || slot.pack != info.pack))
69 {
70 return Error::ConflictingArgument;
71 }
72
73 slot = info;
74 return Error::None;
75 }
76};
77
78#include "printf_frontend_parser.hpp"
79
86[[nodiscard]] consteval Error WalkSource(std::string_view source, auto& visitor)
87{
88 if (HasEmbeddedNul(source))
89 {
90 return Error::EmbeddedNul;
91 }
92
93 size_t pos = 0;
94 size_t text_begin = 0;
95 IndexingState indexing{};
96
97 while (pos < source.size())
98 {
99 if (source[pos] != '%')
100 {
101 ++pos;
Error
brace 风格 format 前端的编译期失败类别。 / Compile-time failure categories for the brace-style format frontend.
单个 printf 转换在降为共享格式前的解析结果 / One parsed printf conversion before lowering into the shared format
size_t arg_index
source argument index consumed by this field / 当前字段消耗的源参数索引
单条 brace 风格格式字面量的仅源串分析数据 / Source-only analysis data for one brace-style format literal
std::array< FormatArgumentInfo, ArgCount > args
source-ordered argument metadata / 按源参数顺序排列的参数元信息

◆ ParseByte()

Error SourceSyntax::ParseByte ( std::string_view source,
size_t & pos,
uint8_t limit,
uint8_t & value )
nodiscardconsteval

解析一个目标为字节宽度的十进制整数字段片段,并检查是否溢出 / Parse one decimal byte-sized integer fragment with overflow checking

Parameters
source含该十进制片段的源字符串 / Source string holding the decimal fragment
pos当前解析位置,成功时推进到片段之后 / Current parse position; advanced past the fragment on success
limit该字段允许的最大值 / Inclusive upper bound accepted by this field
value输出解析结果 / Parsed result output
Returns
成功返回 Error::None;溢出或语法非法时返回对应错误 / Returns Error::None on success, or the first overflow or syntax failure

Definition at line 111 of file printf_frontend_source.hpp.

112 {
113 error = visitor.Text(pos, 1);
114 if (error != Error::None)
115 {
116 return error;
117 }
118
119 pos += 2;
120 text_begin = pos;
121 continue;
122 }
123
124 auto parse_pos = pos;
125 Conversion conversion{};
126 error = Parse(source, parse_pos, indexing, conversion);
127 if (error != Error::None)
128 {
129 return error;
130 }
131
132 error = visitor.Field(conversion);
133 if (error != Error::None)
consteval Error Parse(std::string_view source, size_t &pos, IndexingState &indexing, Conversion &conversion)
在前导 % 之后解析一个完整 printf 转换项 / Parse one complete printf conversion after the leading %

◆ ParseField()

Error SourceSyntax::ParseField ( std::string_view source,
size_t & pos,
IndexingState & indexing,
ParsedField & field )
nodiscardconsteval

解析一个完整 brace 字段,从 { 一直到匹配的 } / Parse one complete brace field from { through the matching }

Parameters
source源字符串 / Source string
pos当前解析位置,进入时应指向 {,成功时推进到 } 之后 / Current parse position; must point at { on entry and lands after } on success
indexing自动或手动索引状态 / Auto or manual indexing state
field输出字段结果 / Parsed field output
Returns
成功返回 Error::None;字段语法不合法时返回对应错误 / Returns Error::None on success, or the first field-syntax error

Definition at line 313 of file format_frontend_source.hpp.

316{
321template <size_t FieldCount>
322struct SourceAnalysis
323{
324 std::array<size_t, FieldCount> argument_order{};
325 size_t required_argument_count = 0;
326 Error error = Error::None;
327};
328
333template <size_t MaxFieldCount>
334struct SourceAnalysisScratch
335{
336 std::array<size_t, MaxFieldCount> order{};
337 size_t field_count = 0;
338 size_t required_argument_count = 0;
339 Error error = Error::None;
340
341 [[nodiscard]] consteval Error Text(size_t, size_t) const { return Error::None; }
342
343 [[nodiscard]] consteval Error Field(const ParsedField& field)
344 {
345 order[field_count++] = field.arg_index;
346 size_t used_argument_count = field.arg_index + 1;
347 if (used_argument_count > required_argument_count)
348 {
349 required_argument_count = used_argument_count;
350 }
351 return Error::None;
352 }
353};
354
355#include "format_frontend_parser.hpp"
356
363[[nodiscard]] consteval Error WalkSource(std::string_view source, auto& visitor)
364{
365 if (HasEmbeddedNul(source))
366 {
367 return Error::EmbeddedNul;
368 }
369
370 size_t pos = 0;
371 size_t text_begin = 0;
372 IndexingState indexing{};
373
374 while (pos < source.size())
375 {
376 if (source[pos] == '{')
377 {
378 if (pos + 1 < source.size() && source[pos + 1] == '{')
379 {
380 auto error = visitor.Text(text_begin, pos - text_begin);
381 if (error != Error::None)
382 {
383 return error;
384 }
385 error = visitor.Text(pos, 1);
386 if (error != Error::None)
387 {
388 return error;
389 }
390 pos += 2;
391 text_begin = pos;
392 continue;
393 }
394
395 auto error = visitor.Text(text_begin, pos - text_begin);
396 if (error != Error::None)
397 {
398 return error;
399 }
400
401 ParsedField field{};
402 error = ParseField(source, pos, indexing, field);
403 if (error != Error::None)
404 {
405 return error;
406 }
407
408 error = visitor.Field(field);
409 if (error != Error::None)
410 {
411 return error;
412 }
413
414 text_begin = pos;
415 continue;
416 }
417
418 if (source[pos] == '}')
419 {
420 if (pos + 1 < source.size() && source[pos + 1] == '}')
421 {
422 auto error = visitor.Text(text_begin, pos - text_begin);
423 if (error != Error::None)
424 {
425 return error;
426 }
427 error = visitor.Text(pos, 1);
428 if (error != Error::None)
429 {
430 return error;
431 }
432 pos += 2;
433 text_begin = pos;
434 continue;
435 }
436
437 return Error::UnmatchedBrace;
438 }
439
440 ++pos;
441 }
442
443 return visitor.Text(text_begin, source.size() - text_begin);
444}
445
451template <Text Source>
452[[nodiscard]] consteval auto Analyze()
453{
454 constexpr auto scratch = []() consteval {
455 SourceAnalysisScratch<Source.Size()> visitor{};
456 visitor.error = WalkSource(std::string_view(Source.Data(), Source.Size()), visitor);
457 return visitor;
458 }();
459
460 SourceAnalysis<scratch.field_count> result{};
461 result.required_argument_count = scratch.required_argument_count;
462 result.error = scratch.error;
463 for (size_t i = 0; i < scratch.field_count; ++i)
464 {
465 result.argument_order[i] = scratch.order[i];
466 }
467 return result;
468}
469} // namespace SourceSyntax

◆ ParseFieldHead()

Error SourceSyntax::ParseFieldHead ( std::string_view source,
size_t & pos,
IndexingState & indexing,
ParsedField & field )
nodiscardconsteval

解析 :} 之前的字段头,包括自动或手动参数索引选择 / Parse the field head before : or }, including automatic or manual argument index selection

Parameters
source源字符串 / Source string
pos当前解析位置,成功时推进到字段头之后 / Current parse position; advanced past the field head on success
indexing自动或手动索引状态 / Auto or manual indexing state
field输出字段头结果 / Parsed field-head output
Returns
成功返回 Error::None;语法或索引模式不合法时返回对应错误 / Returns Error::None on success, or the first syntax or indexing error

Definition at line 147 of file format_frontend_source.hpp.

148 {};
149 result.required_argument_count = scratch.required_argument_count;
150 result.error = scratch.error;
151 for (size_t i = 0; i < scratch.field_count; ++i)
152 {
153 result.argument_order[i] = scratch.order[i];
154 }
155 return result;
156}
157} // namespace SourceSyntax

◆ ParseFlags()

Error SourceSyntax::ParseFlags ( std::string_view source,
size_t & pos,
Conversion & conversion )
nodiscardconsteval

单个 printf 转换体的源级解析器 / Source parser for one printf conversion body

解析单个转换项前导的标志位簇 / Parse the leading flag cluster of one conversion

Parameters
source完整 printf 源字符串 / Full printf source string
pos当前解析位置,成功时推进到已解析标志之后 / Current parse position; advanced past parsed flags
conversion当前正在填充的转换项 / Conversion being filled
Returns
成功返回 Error::None;遇到非法标志时返回对应错误 / Returns Error::None on success, or the first invalid flag error

Definition at line 16 of file printf_frontend_source.hpp.

20 { return Error::None; }
21
22 [[nodiscard]] consteval Error Field(const Conversion& conversion)
23 {
24 order[field_count++] = conversion.arg_index;
25 size_t used_argument_count = conversion.arg_index + 1;
26 if (used_argument_count > argument_count)
27 {
28 argument_count = used_argument_count;
29 }
30 return Error::None;
31 }
32};
33
39template <size_t FieldCount, size_t ArgCount>
40struct SourceAnalysis
41{
42 std::array<size_t, FieldCount> order{};
43 std::array<FormatArgumentInfo, ArgCount> args{};
44 Error error = Error::None;
45};
46

◆ ParseFormatSpec()

Error SourceSyntax::ParseFormatSpec ( std::string_view source,
size_t & pos,
ParsedField & field )
nodiscardconsteval

解析一个 brace 字段中 : 之后的可选 format-spec 部分 / Parse the optional format-spec portion after : inside one brace field

Parameters
source源字符串 / Source string
pos当前解析位置,成功时推进到 format-spec 之后 / Current parse position; advanced past the format-spec on success
field待填充的字段结果 / Parsed field output being filled
Returns
成功返回 Error::None;format-spec 非法时返回对应错误 / Returns Error::None on success, or the first format-spec error

Definition at line 203 of file format_frontend_source.hpp.

206{
211template <size_t FieldCount>
212struct SourceAnalysis
213{
214 std::array<size_t, FieldCount> argument_order{};
215 size_t required_argument_count = 0;
216 Error error = Error::None;
217};
218
223template <size_t MaxFieldCount>
224struct SourceAnalysisScratch
225{
226 std::array<size_t, MaxFieldCount> order{};
227 size_t field_count = 0;
228 size_t required_argument_count = 0;
229 Error error = Error::None;
230
231 [[nodiscard]] consteval Error Text(size_t, size_t) const { return Error::None; }
232
233 [[nodiscard]] consteval Error Field(const ParsedField& field)
234 {
235 order[field_count++] = field.arg_index;
236 size_t used_argument_count = field.arg_index + 1;
237 if (used_argument_count > required_argument_count)
238 {
239 required_argument_count = used_argument_count;
240 }
241 return Error::None;
242 }
243};
244
245#include "format_frontend_parser.hpp"
246
253[[nodiscard]] consteval Error WalkSource(std::string_view source, auto& visitor)
254{
255 if (HasEmbeddedNul(source))
256 {
257 return Error::EmbeddedNul;
258 }
259
260 size_t pos = 0;
261 size_t text_begin = 0;
262 IndexingState indexing{};
263
264 while (pos < source.size())
265 {
266 if (source[pos] == '{')
267 {
268 if (pos + 1 < source.size() && source[pos + 1] == '{')
269 {
270 auto error = visitor.Text(text_begin, pos - text_begin);
271 if (error != Error::None)
272 {
273 return error;
274 }
275 error = visitor.Text(pos, 1);
276 if (error != Error::None)
277 {
278 return error;
279 }
280 pos += 2;
281 text_begin = pos;
282 continue;
283 }
284
285 auto error = visitor.Text(text_begin, pos - text_begin);
286 if (error != Error::None)
287 {
288 return error;
289 }
290
291 ParsedField field{};
292 error = ParseField(source, pos, indexing, field);
293 if (error != Error::None)
294 {
295 return error;
296 }
297
298 error = visitor.Field(field);
299 if (error != Error::None)
300 {
301 return error;
302 }
303
304 text_begin = pos;
305 continue;
306 }
307
308 if (source[pos] == '}')
309 {
310 if (pos + 1 < source.size() && source[pos + 1] == '}')
311 {
312 auto error = visitor.Text(text_begin, pos - text_begin);
313 if (error != Error::None)
314 {
315 return error;
316 }
317 error = visitor.Text(pos, 1);
318 if (error != Error::None)
319 {
320 return error;
321 }
322 pos += 2;
323 text_begin = pos;
324 continue;
325 }
326
327 return Error::UnmatchedBrace;
328 }
329
330 ++pos;
331 }
332
333 return visitor.Text(text_begin, source.size() - text_begin);
334}
335
341template <Text Source>
342[[nodiscard]] consteval auto Analyze()
343{
344 constexpr auto scratch = []() consteval {
345 SourceAnalysisScratch<Source.Size()> visitor{};
346 visitor.error = WalkSource(std::string_view(Source.Data(), Source.Size()), visitor);
347 return visitor;
348 }();
349
350 SourceAnalysis<scratch.field_count> result{};
351 result.required_argument_count = scratch.required_argument_count;
352 result.error = scratch.error;
353 for (size_t i = 0; i < scratch.field_count; ++i)
354 {
355 result.argument_order[i] = scratch.order[i];
356 }
357 return result;
358}
359} // namespace SourceSyntax

◆ ParseLength()

void SourceSyntax::ParseLength ( std::string_view source,
size_t & pos,
Conversion & conversion )
consteval

解析一个可选的长度修饰符序列 / Parse one optional length modifier sequence

Parameters
source完整 printf 源字符串 / Full printf source string
pos当前解析位置;若存在长度修饰符则推进到其后 / Current parse position; advanced past the length modifier when present
conversion当前正在填充的转换项 / Conversion being filled

Definition at line 120 of file printf_frontend_source.hpp.

125 {};
126 error = Parse(source, parse_pos, indexing, conversion);
127 if (error != Error::None)
128 {
129 return error;
130 }
131
132 error = visitor.Field(conversion);
133 if (error != Error::None)
134 {
135 return error;
136 }
137
138 pos = parse_pos;
139 text_begin = pos;
140 }
141
142 return visitor.Text(text_begin, source.size() - text_begin);
143}
144
150template <Text Source>
151[[nodiscard]] consteval auto Analyze()
152{
153 constexpr auto scratch = []() consteval {
154 SourceAnalysisScratch<Source.Size()> visitor{};
155 visitor.error =
156 WalkSource(std::string_view(Source.Data(), Source.Size()), visitor);
157 return visitor;
158 }();
159
160 SourceAnalysis<scratch.field_count, scratch.argument_count> result{};
161 result.error = scratch.error;
162 for (size_t i = 0; i < scratch.field_count; ++i)

◆ ParsePrecision()

Error SourceSyntax::ParsePrecision ( std::string_view source,
size_t & pos,
Conversion & conversion )
nodiscardconsteval

解析一个可选的常量精度字段 / Parse one optional constant precision field

Parameters
source完整 printf 源字符串 / Full printf source string
pos当前解析位置,成功时推进到精度片段之后 / Current parse position; advanced past the precision fragment on success
conversion当前正在填充的转换项 / Conversion being filled
Returns
成功返回 Error::None;精度相关错误时返回对应错误 / Returns Error::None on success, or the first precision-related error

Definition at line 82 of file printf_frontend_source.hpp.

87{
88 if (HasEmbeddedNul(source))
89 {
90 return Error::EmbeddedNul;
91 }
92
93 size_t pos = 0;
94 size_t text_begin = 0;
95 IndexingState indexing{};
96
97 while (pos < source.size())
98 {
99 if (source[pos] != '%')
100 {
101 ++pos;
102 continue;
103 }
104
105 auto error = visitor.Text(text_begin, pos - text_begin);
106 if (error != Error::None)
107 {
108 return error;
109 }
110
111 if (pos + 1 < source.size() && source[pos + 1] == '%')
112 {

◆ ParseSpecifier()

Error SourceSyntax::ParseSpecifier ( std::string_view source,
size_t & pos,
Conversion & conversion )
nodiscardconsteval

解析并校验最终的转换说明符字符 / Parse and validate the final conversion specifier token

Parameters
source完整 printf 源字符串 / Full printf source string
pos当前解析位置,成功时推进到说明符之后 / Current parse position; advanced past the specifier on success
conversion当前正在填充的转换项 / Conversion being filled
Returns
成功返回 Error::None;说明符、长度或功能开关不合法时返回对应错误 / Returns Error::None on success, or the first specifier, length, or gate error

Definition at line 171 of file printf_frontend_source.hpp.

172 {
173 ResolvedArgumentVisitor<scratch.field_count, scratch.argument_count> visitor{
174 result};
175 result.error = WalkSource(std::string_view(Source.Data(), Source.Size()), visitor);
176 return result;
177 }
178}
179} // namespace SourceSyntax
将已解析转换解析成最终源顺序参数元信息摘要的 visitor / Visitor that resolves parsed conversions into the final source-order...

◆ ParseUnsigned()

template<typename UInt >
Error SourceSyntax::ParseUnsigned ( std::string_view source,
size_t & pos,
UInt limit,
UInt & value )
nodiscardconsteval

解析一个十进制整数字段片段,并检查是否溢出 / Parse one decimal integer fragment with overflow checking

Template Parameters
UInt目标无符号整数类型 / Target unsigned integer type
Parameters
source源字符串 / Source string
pos当前解析位置,成功时推进到片段之后 / Current parse position; advanced past the fragment on success
limit允许的最大值 / Inclusive upper bound accepted by this field
value输出解析结果 / Parsed result output
Returns
成功返回 Error::None;溢出或语法不合法时返回对应错误 / Returns Error::None on success, or the first overflow or syntax error

Definition at line 104 of file format_frontend_source.hpp.

107 {
108 if (pos + 1 < source.size() && source[pos + 1] == '}')
109 {
110 auto error = visitor.Text(text_begin, pos - text_begin);
111 if (error != Error::None)
112 {
113 return error;
114 }
115 error = visitor.Text(pos, 1);
116 if (error != Error::None)
117 {
118 return error;
119 }
120 pos += 2;
121 text_begin = pos;
122 continue;
123 }
124
125 return Error::UnmatchedBrace;
126 }
127

◆ ParseWidth()

Error SourceSyntax::ParseWidth ( std::string_view source,
size_t & pos,
Conversion & conversion )
nodiscardconsteval

解析一个可选的常量宽度字段 / Parse one optional constant width field

Parameters
source完整 printf 源字符串 / Full printf source string
pos当前解析位置,成功时推进到宽度片段之后 / Current parse position; advanced past the width fragment on success
conversion当前正在填充的转换项 / Conversion being filled
Returns
成功返回 Error::None;动态宽度或非法宽度时返回对应错误 / Returns Error::None on success, or the first dynamic-field or invalid-width error

Definition at line 58 of file printf_frontend_source.hpp.

60 {
61 auto field = FieldSelection::BuildFormatField(conversion);
62 auto info = FormatArgumentInfo{
63 .pack = field.pack,
64 .rule = field.rule,
65 };
66 auto& slot = analysis.args[conversion.arg_index];
67 if (slot.rule != FormatArgumentRule::None &&
68 (slot.rule != info.rule || slot.pack != info.pack))
69 {
70 return Error::ConflictingArgument;
71 }
72
73 slot = info;

◆ WalkSource()

Error SourceSyntax::WalkSource ( std::string_view source,
auto & visitor )
nodiscardconsteval

遍历一个 brace 源字符串,并发射字面文本片段与已解析字段 / Walk one brace source string and emit literal-text spans plus parsed fields

遍历一个 printf 源字符串,并发射字面文本片段与已解析转换项 / Walk one printf source string and emit literal-text spans plus parsed conversions

Parameters
source当前待解析的 brace 源字符串 / Brace source string to walk
visitor接收文本片段与已解析字段的 visitor / Visitor receiving text spans and parsed fields
Returns
首个源级解析错误;成功时返回 Error::None / Returns the first source-level parse error, or Error::None on success
Parameters
source当前待解析的 printf 源字符串 / Printf source string to walk
visitor接收文本片段与已解析转换项的 visitor / Visitor receiving text spans and parsed conversions
Returns
首个源级解析错误;成功时返回 Error::None / Returns the first source-level parse error, or Error::None on success

Definition at line 51 of file format_frontend_source.hpp.

52{
53 if (HasEmbeddedNul(source))
54 {
55 return Error::EmbeddedNul;
56 }
57
58 size_t pos = 0;
59 size_t text_begin = 0;
60 IndexingState indexing{};
61
62 while (pos < source.size())
63 {
64 if (source[pos] == '{')
65 {
66 if (pos + 1 < source.size() && source[pos + 1] == '{')
67 {
68 auto error = visitor.Text(text_begin, pos - text_begin);
69 if (error != Error::None)
70 {
71 return error;
72 }
73 error = visitor.Text(pos, 1);
74 if (error != Error::None)
75 {
76 return error;
77 }
78 pos += 2;
79 text_begin = pos;
80 continue;
81 }
82
83 auto error = visitor.Text(text_begin, pos - text_begin);
84 if (error != Error::None)
85 {
86 return error;
87 }
88
89 ParsedField field{};
90 error = ParseField(source, pos, indexing, field);
91 if (error != Error::None)
92 {
93 return error;
94 }
95
96 error = visitor.Field(field);
97 if (error != Error::None)
98 {
99 return error;
100 }
101
102 text_begin = pos;
103 continue;
104 }
105
106 if (source[pos] == '}')
107 {
108 if (pos + 1 < source.size() && source[pos + 1] == '}')
109 {
110 auto error = visitor.Text(text_begin, pos - text_begin);
111 if (error != Error::None)
112 {
113 return error;
114 }
115 error = visitor.Text(pos, 1);
116 if (error != Error::None)
117 {
118 return error;
119 }
120 pos += 2;
121 text_begin = pos;
122 continue;
123 }
124
125 return Error::UnmatchedBrace;
126 }
127
128 ++pos;
129 }
130
131 return visitor.Text(text_begin, source.size() - text_begin);
132}