zeolite-lang-0.24.0.0: example/parser/parse-text.0rx
define StringParser {
refines Parser<String>
@value String match
run (contextOld) {
if (contextOld.hasAnyError()) {
return contextOld.convertError()
}
String message <- "Failed to match \"" + match + "\" at " + contextOld.getPosition()
ParseContext<any> context <- contextOld
traverse (Counter.zeroIndexed(match.size()) -> Int index) {
$ReadOnly[index]$
if (context.atEof() || context.current() != match.readAt(index)) {
if (index > 0) {
// Partial match => set error context.
return context.setBrokenInput(message)
} else {
return context.setValue(ErrorOr:error(message))
}
}
context <- context.advance()
}
return context.setValue(ErrorOr:value(match))
}
create (match) {
return delegate -> #self
}
}
define SequenceOfParser {
refines Parser<String>
@value String matches
@value Int min
@value Int max
run (contextOld) {
if (contextOld.hasAnyError()) {
return contextOld.convertError()
}
String message <- "Failed to match [" + matches + "]{" +
min.formatted() + "," + max.formatted() + "} at " +
contextOld.getPosition()
ParseContext<any> context <- contextOld
[Append<Formatted> & Build<String>] builder <- String.builder()
optional Order<Int> counter <- defer
if (max == 0) {
counter <- Counter.unlimited()
} else {
counter <- Counter.zeroIndexed(max)
}
Int count <- 0
traverse (counter -> count) {
$Hidden[count, counter]$
if (context.atEof()) {
break
}
Bool found <- false
traverse (Counter.zeroIndexed(matches.size()) -> Int index) {
$ReadOnly[context, index]$
if (context.current() == matches.readAt(index)) {
\ builder.append(matches.readAt(index))
found <- true
break
}
}
if (!found) {
break
}
context <- context.advance()
}
if (count >= min) {
return context.setValue(ErrorOr:value(builder.build()))
} elif (count > 0) {
// Partial match => set error context.
return context.setBrokenInput(message)
} else {
return context.setValue(ErrorOr:error(message))
}
}
create (matches, min, max) {
return delegate -> #self
}
}
define CharParser {
refines Parser<Char>
@value Char match
run (contextOld) {
if (contextOld.hasAnyError()) {
return contextOld.convertError()
}
if (contextOld.atEof() || contextOld.current() != match) {
String message <- "Failed to match '" + match.formatted() + "' at " + contextOld.getPosition()
return contextOld.setValue(ErrorOr:error(message))
} else {
return contextOld.advance().setValue(ErrorOr:value(match))
}
}
create (match) {
return delegate -> #self
}
}
concrete ConstParser<#x> {
#x immutable
@type create (#x) -> (Parser<#x>)
}
define ConstParser {
refines Parser<#x>
@value #x value
run (contextOld) {
return contextOld.setValue(ErrorOr:value(value))
}
create (value) {
return delegate -> #self
}
}
concrete ErrorParser {
@type create (Formatted) -> (Parser<all>)
}
define ErrorParser {
refines Parser<all>
@value String message
run (contextOld) {
return contextOld.setValue(ErrorOr:error(message))
}
create (message) {
return ErrorParser{ message.formatted() }
}
}
concrete TryParser<#x> {
@type create (Parser<#x>) -> (Parser<#x>)
}
define TryParser {
refines Parser<#x>
@value Parser<#x> parser
run (contextOld) {
if (contextOld.hasAnyError()) {
return contextOld.convertError()
}
ParseContext<#x> context <- contextOld.run<#x>(parser)
if (context.hasAnyError()) {
return contextOld.setValue(context.getValue().convertError())
} else {
return context.toState()
}
}
create (parser) {
return delegate -> #self
}
}
concrete OrParser<#x> {
@type create (Parser<#x>, Parser<#x>) -> (Parser<#x>)
}
define OrParser {
refines Parser<#x>
@value Parser<#x> parser1
@value Parser<#x> parser2
run (contextOld) {
if (contextOld.hasAnyError()) {
return contextOld.convertError()
}
ParseContext<#x> context <- contextOld.run<#x>(parser1)
if (context.hasAnyError() && !context.hasBrokenInput()) {
return contextOld.run<#x>(parser2).toState()
} else {
return context.toState()
}
}
create (parser1, parser2) {
return delegate -> #self
}
}
concrete LeftParser<#x> {
@type create (Parser<#x>, Parser<any>) -> (Parser<#x>)
}
define LeftParser {
refines Parser<#x>
@value Parser<#x> parser1
@value Parser<any> parser2
run (contextOld) {
if (contextOld.hasAnyError()) {
return contextOld.convertError()
}
ParseContext<#x> context <- contextOld.run<#x>(parser1)
if (context.hasAnyError()) {
return context.toState()
} else {
ParseContext<any> context2 <- context.run(parser2)
if (context2.hasAnyError()) {
return context2.convertError()
} else {
return context2.setValue(context.getValue())
}
}
}
create (parser1, parser2) {
return delegate -> #self
}
}
concrete RightParser<#x> {
@type create (Parser<any>, Parser<#x>) -> (Parser<#x>)
}
define RightParser {
refines Parser<#x>
@value Parser<any> parser1
@value Parser<#x> parser2
run (contextOld) {
if (contextOld.hasAnyError()) {
return contextOld.convertError()
}
ParseContext<any> context <- contextOld.run(parser1)
if (context.hasAnyError()) {
return context.convertError()
} else {
return context.run<#x>(parser2).toState()
}
}
create (parser1, parser2) {
return delegate -> #self
}
}
define Parse {
error (message) {
return delegate -> `ErrorParser.create`
}
const (value) {
return delegate -> `ConstParser<#x>.create`
}
try (parser) {
return delegate -> `TryParser<#x>.create`
}
or (parser1, parser2) {
return delegate -> `OrParser<#x>.create`
}
left (parser1, parser2) {
return delegate -> `LeftParser<#x>.create`
}
right (parser1, parser2) {
return delegate -> `RightParser<#x>.create`
}
}