载入中...
搜索中...
未找到
DnutBlockScanner.cpp
浏览该文件的文档.
2
3#include <string>
4#include <utility>
5#include <vector>
6
7namespace eve::dnut {
8namespace {
9
10eve::Result<std::vector<DnutBlock>> scanFailure(const std::string& path, const DnutToken& token, std::string message) {
13 {{"line", std::to_string(token.line)}, {"column", std::to_string(token.column)}}, "dnut.block-scanner"));
14}
15
16bool isPunct(const DnutToken& token, const char* text) {
17 return token.kind == DnutTokenKind::Punctuator && token.text == text;
18}
19
20} // namespace
21
22eve::Result<std::vector<DnutBlock>> scanDnutBlocks(const std::vector<DnutToken>& tokens, const std::string& path) {
23 std::vector<DnutBlock> blocks;
24 if (tokens.empty())
26 eve::DiagnosticCode::ParseError, "dnut token buffer is empty", path, {}, "dnut.block-scanner"));
27
28 std::size_t index = 0;
29 while (index < tokens.size() && tokens[index].kind != DnutTokenKind::EndOfFile) {
30 const DnutToken& keyword = tokens[index];
31 if (keyword.kind != DnutTokenKind::Identifier)
32 return scanFailure(path, keyword, "expected a top-level field or dialect block");
33
34 // The versioned document envelope is not a dialect block.
35 if (keyword.text == "schema") {
36 if (index + 1 >= tokens.size() || tokens[index + 1].kind != DnutTokenKind::String)
37 return scanFailure(path, keyword, "schema requires a quoted identifier");
38 index += 2;
39 continue;
40 }
41 if (keyword.text == "version") {
42 if (index + 1 >= tokens.size() || tokens[index + 1].kind != DnutTokenKind::Number)
43 return scanFailure(path, keyword, "version requires an integer");
44 index += 2;
45 continue;
46 }
47
48 DnutBlock block;
49 block.kind = keyword.text;
50 block.beginToken = index;
51 block.line = keyword.line;
52 block.column = keyword.column;
53 ++index;
54 if (index < tokens.size() &&
56 block.id = tokens[index].text;
57
58 while (index < tokens.size() && tokens[index].kind != DnutTokenKind::EndOfFile && !isPunct(tokens[index], "{"))
59 ++index;
60 if (index >= tokens.size() || tokens[index].kind == DnutTokenKind::EndOfFile)
61 return scanFailure(path, keyword, "top-level block '" + block.kind + "' requires '{'");
62
63 int depth = 0;
64 while (index < tokens.size() && tokens[index].kind != DnutTokenKind::EndOfFile) {
65 if (isPunct(tokens[index], "{"))
66 ++depth;
67 else if (isPunct(tokens[index], "}")) {
68 --depth;
69 if (depth == 0) {
70 ++index;
71 block.endToken = index;
72 blocks.push_back(std::move(block));
73 break;
74 }
75 }
76 ++index;
77 }
78 if (block.endToken == 0) return scanFailure(path, keyword, "unterminated top-level block '" + block.kind + "'");
79 }
80 return eve::Result<std::vector<DnutBlock>>::success(std::move(blocks));
81}
82
83} // namespace eve::dnut
Shared top-level block discovery for `.dnut` dialects.
std::string message
std::unordered_map< const Graphics *, std::shared_ptr< Lifetime > > tokens
std::string text
std::string path
Definition PlayHost.cpp:110
uint64_t token
uint32_t index
std::uint32_t depth
static Diagnostic error(DiagnosticCode code, std::string message, std::string path={}, DiagnosticDetails details={}, std::string source={})
Construct an error diagnostic with the standard error severity.
Definition Diagnostic.h:125
Move-only operation result carrying either a value or Status.
Definition Result.h:155
eve::Result< std::vector< DnutBlock > > scanDnutBlocks(const std::vector< DnutToken > &tokens, const std::string &path)
Discover balanced top-level dialect blocks in one lexed document.
@ String
Quoted string with escapes already resolved.
@ Identifier
Bare word: keyword, field name, identifier, or bare enum value.
@ Punctuator
One- or two-character punctuator such as {, =, ==, ->.
@ EndOfFile
Synthetic terminal token; always the last element.
@ Number
Unsigned numeric literal; sign handling belongs to the parser.
One top-level dialect block in a shared token buffer.
One lexed token with its exact source anchor.
Definition DnutLexer.h:31
int line
One-based source line.
Definition DnutLexer.h:35
DnutTokenKind kind
Definition DnutLexer.h:32
int column
One-based source column of the first character.
Definition DnutLexer.h:37
std::string text
Definition DnutLexer.h:33