libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
printf_frontend_source.hpp
1#pragma once
2
3#include "printf_frontend_lowering_base.hpp"
4#include "printf_frontend_lowering_field.hpp"
5
6namespace SourceSyntax
12template <size_t MaxFieldCount>
14{
15 std::array<size_t, MaxFieldCount> order{};
16 size_t field_count = 0;
17 size_t argument_count = 0;
18 Error error = Error::None;
19
20 [[nodiscard]] consteval Error Text(size_t, size_t) const { 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>
41{
42 std::array<size_t, FieldCount> order{};
43 std::array<FormatArgumentInfo, ArgCount> args{};
44 Error error = Error::None;
45};
46
52template <size_t FieldCount, size_t ArgCount>
56
57 [[nodiscard]] consteval Error Text(size_t, size_t) const { return Error::None; }
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;
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 {
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)
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)
163 {
164 result.order[i] = scratch.order[i];
165 }
166
167 if constexpr (scratch.error != Error::None)
168 {
169 return result;
170 }
171 else
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
Error
brace 风格 format 前端的编译期失败类别。 / Compile-time failure categories for the brace-style format frontend.
printf 降级阶段共享的描述表与策略辅助函数 / Shared descriptor-table and policy helpers for printf lowering
constexpr bool HasEmbeddedNul(std::string_view source)
判断源字符串在终止前是否包含嵌入式 NUL / Return whether the source contains an embedded NUL before the terminator
consteval auto Analyze()
对一个 brace 字面量执行仅源串分析,并返回按顺序整理的参数索引摘要 / Run source-only analysis for one brace literal and return the ...
consteval Error Parse(std::string_view source, size_t &pos, IndexingState &indexing, Conversion &conversion)
在前导 % 之后解析一个完整 printf 转换项 / Parse one complete printf conversion after the leading %
consteval Error WalkSource(std::string_view source, auto &visitor)
遍历一个 brace 源字符串,并发射字面文本片段与已解析字段 / Walk one brace source string and emit literal-text spans plus parse...
单个 printf 转换在降为共享格式前的解析结果 / One parsed printf conversion before lowering into the shared format
size_t arg_index
source argument index consumed by this field / 当前字段消耗的源参数索引
brace 字段自动索引与手动索引的源级状态 / Source-level indexing mode for automatic versus manual brace fields
将已解析转换解析成最终源顺序参数元信息摘要的 visitor / Visitor that resolves parsed conversions into the final source-order...
单条 brace 风格格式字面量的仅源串分析数据 / Source-only analysis data for one brace-style format literal
std::array< size_t, FieldCount > order
field-ordered source argument indexes / 按字段顺序排列的源参数索引
std::array< FormatArgumentInfo, ArgCount > args
source-ordered argument metadata / 按源参数顺序排列的参数元信息
Error error
first source-only parse error / 首个仅源串解析错误
仅源串分析阶段使用的保守临时累加器 / Conservative temporary accumulator used during source-only analysis
std::array< size_t, MaxFieldCount > order
conservative field-order scratch buffer / 按字段顺序记录参数索引的临时缓冲区
Error error
first parse error / 首个解析错误
size_t argument_count
highest referenced argument count / 最高引用到的参数个数
size_t field_count
parsed replacement-field count / 已解析的替换字段数量