feat: Working on new implementation experiments.

This commit is contained in:
2025-01-31 09:42:56 -05:00
parent d815c5f7c3
commit e3541e9056

View File

@@ -33,98 +33,63 @@ enum YamlItem {
case boolean(Bool)
case date(year: Int, month: Int, day: Int)
case string(String)
case listItem(String)
private static let dateParser = Parse(input: Substring.self) {
private static let dateParser = Parse(input: Substring.UTF8View.self) {
Digits(4)
"-"
"-".utf8
Digits(2)
"-"
"-".utf8
Digits(2)
}.map { Self.date(year: $0.0, month: $0.1, day: $0.2) }
private static let booleanParser = Parse(input: Substring.self) {
private static let booleanParser = Parse(input: Substring.UTF8View.self) {
Bool.parser()
}.map { Self.boolean($0) }
private static let quotedString = Parse(input: Substring.self) {
"\""
PrefixUpTo("\"")
"\""
private static let quotedString = Parse(input: Substring.UTF8View.self) {
"\"".utf8
PrefixUpTo("\"".utf8)
"\"".utf8
}
private static let stringParser = Parse(input: Substring.self) {
private static let stringParser = Parse(input: Substring.UTF8View.self) {
OneOf {
quotedString
Rest()
}
}.map { Self.string(String($0)) }
}.map { Self.string(String(Substring($0))) }
private static let listItemParser = Parse(input: Substring.UTF8View.self) {
Skip { Whitespace() }
"- ".utf8
Rest()
}.map { Self.listItem(String(Substring($0))) }
static let parser = OneOf {
dateParser
booleanParser
listItemParser
stringParser
}
}
enum YamlLine {
case keyValue(String, YamlItem)
case list(String, [String])
static let parser = OneOf {
listParser
keyValueParser
}
static let keyParser = Parse(input: Substring.self) {
PrefixUpTo(":")
":"
}.map(String.init)
static let keyValueParser = Parse(input: Substring.self) {
PrefixUpTo(":").map(String.init)
": "
YamlItem.parser
}.map { YamlLine.keyValue($0.0, $0.1) }
static let listLineParser = Parse(input: Substring.self) {
Skip { PrefixThrough("- ") }
PrefixUpTo("\n").map(String.init)
"\n"
}
static let listParser = Parse(input: Substring.self) {
PrefixUpTo(":\n").map(String.init)
":\n"
Many {
Skip { PrefixThrough("- ") }
PrefixUpTo("\n").map(String.init)
"\n"
}
}
.map { YamlLine.list($0.0, $0.1) }
}
let yamlBlockParser = Parse(input: Substring.UTF8View.self) {
"---\n".utf8
Many {
PrefixUpTo("\n".utf8)
PrefixUpTo(":".utf8)
":".utf8
Optionally { YamlItem.parser }
// PrefixUpTo("\n".utf8)
// From(.substring) { YamlLine.parser }
} separator: {
"\n".utf8
}
"\n".utf8
} terminator: {
// "\n".utf8
"---".utf8
}
}
// let yamlLineParser = Parse(input: Substring.UTF8View.self) {
// PrefixUpTo(":".utf8).map(String.init)
// ":".utf8
// OneOf {
// PrefixUpTo("\n".utf8)
// Rest()
// }.map(String.init)
// }
let stringLine = #"author: "Michael Housh""#
// let parsedLine = try yamlLineParser.parse(stringLine[...].utf8)
// print(parsedLine)
@@ -140,19 +105,29 @@ try print(YamlItem.parser.parse(dateItem[...]))
try print(YamlItem.parser.parse(boolItem[...]))
let kvLine = "author: Michael Housh"
var listLine = """
test:
var listLine = #"""
- HVAC
- General
- Programming
"""[...]
"""#[...]
try print(YamlLine.parser.parse(kvLine[...]))
try print(YamlLine.parser.parse(&listLine))
print(listLine)
struct YamlList: Parser {
// try print(YamlItem.parser.parse(listItem[...]))
var body: some Parser<Substring.UTF8View, [String]> {
Many(into: [String]()) { array, string in
array.append(string)
} element: {
Whitespace()
"-".utf8
Whitespace()
PrefixUpTo("\n".utf8).map(.string)
"\n".utf8
}
}
}
try print(YamlList().parse(listLine))
var yamlLines = """
author: Michael Housh
@@ -163,28 +138,71 @@ test:
"""[...]
let lineParser = Many {
YamlLine.parser
} separator: {
"\n"
struct SimpleYamlValue: Parser {
enum Output: Equatable {
case array([String])
case bool(Bool)
case date(year: Int, month: Int, day: Int)
case string(String)
}
var body: some Parser<Substring.UTF8View, Output> {
OneOf {
// YamlList().map { Output.array($0) }
DateParser()
Bool.parser().map(.case(Output.bool))
PrefixUpTo("\n".utf8).map(.string).map(.case(Output.string))
Rest().map(.string).map(.case(Output.string))
}
}
struct DateParser: Parser {
var body: some Parser<Substring.UTF8View, Output> {
Parse {
Digits(4)
"-".utf8
Digits(2)
"-".utf8
Digits(2)
}.map(.case(Output.date))
}
}
}
try print(lineParser.parse(yamlLines))
// This works, but doesn't handle lists well.
struct SimpleYamlParser: Parser {
var body: some Parser<Substring.UTF8View, [String: SimpleYamlValue.Output]> {
Many(into: [String: SimpleYamlValue.Output]()) { (dict: inout [String: SimpleYamlValue.Output], pair: (String, SimpleYamlValue.Output)) in
let (key, value) = pair
dict[key] = value
} element: {
PrefixUpTo(":".utf8).map(.string)
":".utf8
Whitespace()
SimpleYamlValue()
} separator: {
"\n".utf8
} terminator: {
End()
}
}
}
// let lines = try yamlBlockParser.parse(yamlString[...].utf8)
//
// for line in lines {
// print("line: \(String(line)!)")
// if let parsed = try? YamlLine.keyValueParser.parse(Substring(line)) {
let simpleYamlString = #"""
author: Michael Housh
copy: true
draft: false
date: 2023-10-21
lastmod: 2023-10-21
image: banner.png
featuredImage: banner.png
"""#
let parsed = try SimpleYamlParser().parse(simpleYamlString[...].utf8)
// print(parsed)
// } else {
// if let key = try? YamlLine.keyParser.parse(Substring(line)) {
// print("found key: \(String(key))")
// } else {
// print("not key value.")
// }
// }
// }
// print(lines.map(String.init))
// print(lines)
for (key, value) in parsed {
print("\(key): \(value)")
}
// try print(SimpleYamlParser().parse(simpleYamlString[...].utf8))