zeolite-lang-0.24.0.0: example/parser/test-data.0rx
$TestsOnly$
define TestData {
@value String name
@value String description
@value Bool boolean
create (name, description, boolean) {
return TestData{ name, description, boolean }
}
name () {
return name
}
description () {
return description
}
boolean () {
return boolean
}
// From TestCompare<TestData>.
testCompare (actual, report) {
\ MultiChecker.new(report)
.tryCheck(
title: "name",
actual.name(),
CheckValue:equals(name))
.tryCheck(
title: "description",
actual.description(),
CheckValue:equals(description))
.tryCheck(
title: "boolean",
actual.boolean(),
CheckValue:equals(boolean))
}
}
define TestDataParser {
// Mark @category members as read-only, to avoid accidental assignment.
$ReadOnlyExcept[]$
// Mark @category members as hidden, since they should not be used directly.
$Hidden[whitespace,
sentenceChars,
sentence,
quote,
quotedSentence,
token,
acronym,
aardvark]$
refines Parser<TestData>
@category Parser<any> whitespace <- SequenceOfParser.create(" \n\t", min: 1, max: 0) `Parse.or` Parse.error("Expected whitespace")
@category String sentenceChars <- "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
"abcdefghijklmnopqrstuvwxyz" +
"., !?-"
@category Parser<String> sentence <- SequenceOfParser.create(sentenceChars, min: 0, max: 0)
@category Parser<any> quote <- CharParser.create('"')
@category Parser<String> quotedSentence <- quote `Parse.right` sentence `Parse.left` quote
@category Parser<String> token <- SequenceOfParser.create("ABCDEFGHIJKLMNOPQRSTUVWXYZ_", min: 1, max: 0)
@category Parser<String> sentenceOrToken <- quotedSentence `Parse.or` token `Parse.left` whitespace
@category Parser<Bool> acronym <- StringParser.create("acronym") `Parse.right` Parse.const(true)
@category Parser<Bool> aardvark <- StringParser.create("aardvark") `Parse.right` Parse.const(false)
@category Parser<Bool> acronymOrAardvark <- Parse.try(acronym) `Parse.or` aardvark `Parse.left` whitespace
@category Parser<any> fileStart <- StringParser.create("file_start") `Parse.left` whitespace
@category Parser<any> fileEnd <- StringParser.create("file_end") `Parse.left` whitespace
@category Parser<any> nameTag <- StringParser.create("name:") `Parse.left` whitespace
@category Parser<any> descriptionTag <- StringParser.create("description:") `Parse.left` whitespace
@category Parser<any> aWordTag <- StringParser.create("a_word:") `Parse.left` whitespace
run (contextOld) {
ParseContext<any> context <- contextOld
context <- context.run(fileStart)
context <- context.run(nameTag)
context, ErrorOr<String> name <- context.runAndGet(sentenceOrToken)
context <- context.run(descriptionTag)
context, ErrorOr<String> description <- context.runAndGet(sentenceOrToken)
context <- context.run(aWordTag)
context, ErrorOr<Bool> boolean <- context.runAndGet(acronymOrAardvark)
context <- context.run(fileEnd)
if (context.hasAnyError()) {
return context.convertError()
} else {
return context.setValue(
// Since TestData.create specifies labels, we _must_ use them here.
ErrorOr:value(TestData.create(
name: name.getValue(),
description: description.getValue(),
boolean: boolean.getValue())))
}
}
create () {
return delegate -> #self
}
}