refactor: identation and typo fix

parcer was renamed to parser
fixed indentation in Lexer
This commit is contained in:
2026-04-22 11:04:14 +09:00
parent c152ce069a
commit 706b16afe0
4 changed files with 75 additions and 75 deletions
@@ -24,7 +24,7 @@ public func runRecipe(_ recipeName: String, args: [String] = []) -> runResult {
let tokenized = Lexer().tokenize(sonyafile)
guard !tokenized.isEmpty else { return .isEmpty }
guard let ast = Parcer().parce(tokenized) else { return .syntaxError }
guard let ast = Parser().parse(tokenized) else { return .syntaxError }
guard let requestedRecipe = ast.rules[recipeName] else { return .noSuchRecipe }
// check for dependencies
+67 -67
View File
@@ -1,81 +1,81 @@
import RegexBuilder
enum Token : Equatable {
case recipe(String)
case dependency(String)
case command(String)
case variable(name: String, value: String)
case comment(String)
case newline
case recipe(String)
case dependency(String)
case command(String)
case variable(name: String, value: String)
case comment(String)
case newline
}
struct Lexer {
private nonisolated(unsafe) static let recipeRegex = Regex {
Anchor.startOfLine
Capture(OneOrMore { CharacterClass(.word, .anyOf("-./")) })
ZeroOrMore(.whitespace)
":"
Optionally {
private nonisolated(unsafe) static let recipeRegex = Regex {
Anchor.startOfLine
Capture(OneOrMore { CharacterClass(.word, .anyOf("-./")) })
ZeroOrMore(.whitespace)
Capture(ZeroOrMore(.anyNonNewline)) // dependencies
":"
Optionally {
ZeroOrMore(.whitespace)
Capture(ZeroOrMore(.anyNonNewline)) // dependencies
}
}
}
private nonisolated(unsafe) static let commandRegex = Regex {
Anchor.startOfLine
OneOrMore(.horizontalWhitespace)
Capture(OneOrMore(.anyNonNewline))
}
private nonisolated(unsafe) static let variableRegex = Regex {
Anchor.startOfLine
Capture(OneOrMore(.word))
ZeroOrMore(.whitespace)
"="
ZeroOrMore(.whitespace)
Capture(ZeroOrMore(.anyNonNewline))
}
private nonisolated(unsafe) static let commentRegex = Regex {
Anchor.startOfLine
ZeroOrMore(.whitespace)
"#"
Capture(ZeroOrMore(.anyNonNewline))
}
func tokenize(_ input: String) -> [Token] {
input.split(omittingEmptySubsequences: false, whereSeparator: \.isNewline)
.flatMap { tokenizeLine(String($0)) }
}
private func tokenizeLine(_ line: String) -> [Token] {
if line.isEmpty {
return [.newline]
private nonisolated(unsafe) static let commandRegex = Regex {
Anchor.startOfLine
OneOrMore(.horizontalWhitespace)
Capture(OneOrMore(.anyNonNewline))
}
if let match = line.wholeMatch(of: Self.recipeRegex) {
let recipe = Token.recipe(String(match.1))
let deps: [Token] = match.2
.map(String.init)?
.split(separator: " ")
.map { .dependency(String($0)) } ?? []
return [recipe] + deps
private nonisolated(unsafe) static let variableRegex = Regex {
Anchor.startOfLine
Capture(OneOrMore(.word))
ZeroOrMore(.whitespace)
"="
ZeroOrMore(.whitespace)
Capture(ZeroOrMore(.anyNonNewline))
}
if let match = line.wholeMatch(of: Self.commentRegex) {
return [.comment(String(match.1))]
private nonisolated(unsafe) static let commentRegex = Regex {
Anchor.startOfLine
ZeroOrMore(.whitespace)
"#"
Capture(ZeroOrMore(.anyNonNewline))
}
if let match = line.wholeMatch(of: Self.variableRegex) {
return [.variable(name: String(match.1), value: String(match.2))]
func tokenize(_ input: String) -> [Token] {
input.split(omittingEmptySubsequences: false, whereSeparator: \.isNewline)
.flatMap { tokenizeLine(String($0)) }
}
if let match = line.wholeMatch(of: Self.commandRegex) {
return [.command(String(match.1))]
private func tokenizeLine(_ line: String) -> [Token] {
if line.isEmpty {
return [.newline]
}
if let match = line.wholeMatch(of: Self.recipeRegex) {
let recipe = Token.recipe(String(match.1))
let deps: [Token] = match.2
.map(String.init)?
.split(separator: " ")
.map { .dependency(String($0)) } ?? []
return [recipe] + deps
}
if let match = line.wholeMatch(of: Self.commentRegex) {
return [.comment(String(match.1))]
}
if let match = line.wholeMatch(of: Self.variableRegex) {
return [.variable(name: String(match.1), value: String(match.2))]
}
if let match = line.wholeMatch(of: Self.commandRegex) {
return [.command(String(match.1))]
}
return [] // unrecognized
}
return [] // unrecognized
}
}
@@ -8,8 +8,8 @@ struct Rule {
var commands: [String] = []
}
struct Parcer {
func parce(_ tokens: [Token]) -> sonyaAST? {
struct Parser {
func parse(_ tokens: [Token]) -> sonyaAST? {
var ast = sonyaAST()
var currentRule: (name: String, rule: Rule)? = nil
@@ -46,7 +46,7 @@ import Testing
@Test func parser_single_recipe_with_command() {
let tokens: [Token] = [.recipe("build"), .command("swift build")]
let ast = Parcer().parce(tokens)
let ast = Parser().parse(tokens)
#expect(ast != nil)
#expect(ast?.rules["build"]?.commands == ["swift build"])
}
@@ -56,14 +56,14 @@ import Testing
.recipe("test"), .dependency("build"),
.command("swift test")
]
let ast = Parcer().parce(tokens)
let ast = Parser().parse(tokens)
#expect(ast?.rules["test"]?.dependencies == ["build"])
#expect(ast?.rules["test"]?.commands == ["swift test"])
}
@Test func parser_variable_is_stored() {
let tokens: [Token] = [.variable(name: "CC", value: "clang")]
let ast = Parcer().parce(tokens)
let ast = Parser().parse(tokens)
#expect(ast?.vars["CC"] == "clang")
}
@@ -73,7 +73,7 @@ import Testing
.newline,
.recipe("test"), .command("swift test"),
]
let ast = Parcer().parce(tokens)
let ast = Parser().parse(tokens)
#expect(ast?.rules["build"]?.commands == ["swift build"])
#expect(ast?.rules["test"]?.commands == ["swift test"])
}
@@ -84,7 +84,7 @@ import Testing
.recipe("build"), .command("swift build"),
.variable(name: "X", value: "1"),
]
let ast = Parcer().parce(tokens)
let ast = Parser().parse(tokens)
#expect(ast?.rules["build"]?.commands == ["swift build"])
#expect(ast?.vars["X"] == "1")
}