feat: Working, unless it ends with a list, however using terminator isn't working at the moment.

This commit is contained in:
2025-01-31 20:34:00 -05:00
parent e3541e9056
commit 659bd8b797

View File

@@ -2,7 +2,6 @@ import Foundation
@preconcurrency import Parsing
let yamlString = """
---
author: Michael Housh
categories:
- HVAC
@@ -14,130 +13,20 @@ date: 2023-10-21
lastmod: 2023-10-21
image: banner.png
featuredImage: banner.png
series:
- General
tags:
- HVAC
- General
- Programming
---
title: "You Should Learn Markdown"
"""
_ = """
series:
- General
title: "You Should Learn Markdown"
slug: "you-should-learn-markdown"
"""
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.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.UTF8View.self) {
Bool.parser()
}.map { Self.boolean($0) }
private static let quotedString = Parse(input: Substring.UTF8View.self) {
"\"".utf8
PrefixUpTo("\"".utf8)
"\"".utf8
}
private static let stringParser = Parse(input: Substring.UTF8View.self) {
OneOf {
quotedString
Rest()
}
}.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
}
}
let yamlBlockParser = Parse(input: Substring.UTF8View.self) {
"---\n".utf8
Many {
PrefixUpTo(":".utf8)
":".utf8
Optionally { YamlItem.parser }
// PrefixUpTo("\n".utf8)
// From(.substring) { YamlLine.parser }
} separator: {
"\n".utf8
} terminator: {
// "\n".utf8
"---".utf8
}
}
let stringLine = #"author: "Michael Housh""#
// let parsedLine = try yamlLineParser.parse(stringLine[...].utf8)
// print(parsedLine)
let stringItem = "foo"
let quotedItem = "\"foo\""
let dateItem = "2025-01-29"
let boolItem = "true"
try print(YamlItem.parser.parse(stringItem[...]))
try print(YamlItem.parser.parse(quotedItem[...]))
try print(YamlItem.parser.parse(dateItem[...]))
try print(YamlItem.parser.parse(boolItem[...]))
let kvLine = "author: Michael Housh"
var listLine = #"""
- HVAC
- General
- Programming
"""#[...]
struct YamlList: Parser {
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
test:
- HVAC
- General
- Programming
"""[...]
struct SimpleYamlValue: Parser {
enum Output: Equatable {
case array([String])
@@ -169,17 +58,47 @@ struct SimpleYamlValue: Parser {
}
}
// 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
typealias Output = [String: SimpleYamlValue.Output]
var body: some Parser<Substring.UTF8View, Output> {
Many(into: Output()) { (dict: inout Output, pair: (String, SimpleYamlValue.Output)) in
let (key, value) = pair
dict[key] = value
} element: {
// Parses a key and array.
OneOf {
Parse {
PrefixUpTo(":".utf8).map(.string)
":\n".utf8
Many(into: [String]()) { array, string in
array.append(string)
} element: {
From(.substring) { Whitespace() }
"-".utf8
From(.substring) { Whitespace() }
PrefixUpTo("\n".utf8).map(.string)
} separator: {
"\n".utf8
}
// terminator: {
// OneOf {
// Peek { PrefixUpTo(":".utf8) }
// End()
// }
// }
}
.map { ($0.0, SimpleYamlValue.Output.array($0.1)) }
// Parse a key and a single value.
Parse {
PrefixUpTo(":".utf8).map(.string)
":".utf8
Whitespace()
SimpleYamlValue()
}
}
} separator: {
"\n".utf8
} terminator: {
@@ -196,13 +115,31 @@ date: 2023-10-21
lastmod: 2023-10-21
image: banner.png
featuredImage: banner.png
test:
- HVAC
- General
- Programming
foo: Bar
"""#
var keyedList = """
test:
- HVAC
- General
- Programming
foo: Bar
"""[...].utf8
// let parsedList = try keyedListParser.parse(&keyedList)
// print(parsedList)
let parsed = try SimpleYamlParser().parse(simpleYamlString[...].utf8)
// print(parsed)
// let parsed = try SimpleYamlParser().parse(yamlString[...].utf8)
for (key, value) in parsed {
print("\(key): \(value)")
}
// assert(parsed.keys.count == 10)
// try print(SimpleYamlParser().parse(simpleYamlString[...].utf8))