forked from mirror/vulkan-zig
75 lines
1.6 KiB
Zig
75 lines
1.6 KiB
Zig
const std = @import("std");
|
|
const Allocator = std.mem.Allocator;
|
|
const ArenaAllocator = std.heap.ArenaAllocator;
|
|
|
|
pub const TagType = enum {
|
|
tag,
|
|
proc_instr
|
|
};
|
|
|
|
pub const Node = struct {
|
|
pub name: []const u8,
|
|
pub type: TagType,
|
|
pub attributes: []Attribute,
|
|
pub children: []Element
|
|
};
|
|
|
|
pub const Attribute = struct {
|
|
pub key: []const u8,
|
|
pub value: []const u8
|
|
};
|
|
|
|
pub const Element = union(enum) {
|
|
pub text: []const u8,
|
|
pub node: *Node
|
|
};
|
|
|
|
pub const Document = struct {
|
|
arena: ArenaAllocator,
|
|
|
|
pub xml_decl: ?*Node,
|
|
pub root: *Node,
|
|
|
|
pub fn deinit(self: *Document) void {
|
|
self.arena.deinit();
|
|
}
|
|
};
|
|
|
|
const Parser = struct {
|
|
alloc: *Allocator,
|
|
source: []const u8,
|
|
offset: usize,
|
|
|
|
fn element(self: *Self) !Element {
|
|
|
|
}
|
|
|
|
fn text(self: *Self) ![]const u8 {
|
|
const start = self.offset;
|
|
const end = if (std.mem.indexOfPos(self.source, self.offset, "<")) |offset| offset else self.source.len;
|
|
self.offset = end;
|
|
return self.source[start .. end]; // TODO: Decode
|
|
}
|
|
|
|
fn node(self: *Self) !*Node {
|
|
std.debug.assert(try self.peekNoEof(0) == '<');
|
|
}
|
|
|
|
fn peekNoEof(self: *const Self, offset: usize) !u8 {
|
|
if (offset + self.offset >= self.source.len) {
|
|
return error.EndOfStream;
|
|
}
|
|
|
|
return self.source[offset + self.offset];
|
|
}
|
|
};
|
|
|
|
pub fn parse(alloc: *Allocator, source: []const u8) !Document {
|
|
var arena = ArenaAllocator.init(alloc);
|
|
var parser = Parser {
|
|
.alloc = alloc,
|
|
.source = source,
|
|
.offset = 0
|
|
};
|
|
}
|