///|
/// 接收Seq[Token]和XMLParserContext,返回((Value, Seq[Token])?, XMLParseError, XMLParserContext)
/// 这里我们考虑单个Parser最多产生一个Error,同时Parser可能在遇到错误后继续解析(例如dtd检查不通过时)。
/// XMLParser需要在遇到格式错误时立刻停止解析。
pub(all) struct XMLParser[Token, Value](
(Seq[Token], XMLParserContext) -> (
(Value, Seq[Token])?,
XMLParseError?,
XMLParserContext,
)
)
///|
type XMLParserResult[Token, Value] = (
(Value, Seq[Token])?,
XMLParseError?,
XMLParserContext,
)
///|
pub fn[Token, Value] XMLParser::new(
f : (Seq[Token], XMLParserContext) -> XMLParserResult[Token, Value],
) -> XMLParser[Token, Value] {
f
}
///|
pub fn[Token, Value] XMLParser::run(
self : XMLParser[Token, Value],
seq : Seq[Token],
ctx : XMLParserContext,
) -> XMLParserResult[Token, Value] {
match (self.0)(seq, ctx) {
(pair, Some(err), ctx) => {
ctx.raise_error(err)
(pair, Some(err), ctx)
}
tuple => tuple
}
// self.0(seq, ctx)
}
///|
pub fn[Token, A, B] XMLParser::and_then(
self : XMLParser[Token, A],
other : XMLParser[Token, B],
) -> XMLParser[Token, (A, B)] {
fn(tokens : Seq[Token], ctx : XMLParserContext) {
let (pair, ctx1) = match self.run(tokens, ctx) {
(pair, Some(err), ctx1) =>
if err.is_fatal() {
(None, ctx1)
} else {
(pair, ctx1)
}
(pair, _, ctx1) => (pair, ctx1)
}
match pair {
None => return (None, None, ctx1)
Some((v1, rest)) =>
match other.run(rest, ctx1) {
(pair, err, ctx2) =>
match pair {
None => (None, err, ctx2)
Some((v2, rest2)) => (Some(((v1, v2), rest2)), err, ctx2)
}
}
}
}
}
///|
pub fn[Token, A] XMLParser::or_else(
self : XMLParser[Token, A],
other : XMLParser[Token, A],
) -> XMLParser[Token, A] {
fn(tokens : Seq[Token], ctx : XMLParserContext) {
match self.run(tokens, ctx) {
(pair, err, ctx1) =>
match err {
Some(e) =>
if e.is_fatal() {
other.run(tokens, ctx1)
} else {
(pair, err, ctx1)
}
_ => (pair, err, ctx1)
}
}
}
}
///|
pub fn[Token, A, B] XMLParser::map(
self : XMLParser[Token, A],
f : (A) -> B,
) -> XMLParser[Token, B] {
fn(tokens : Seq[Token], ctx : XMLParserContext) {
match self.run(tokens, ctx) {
(None, err, ctx1) => (None, err, ctx1)
(Some((v, rest)), err, ctx1) => (Some((f(v), rest)), err, ctx1)
}
}
}
///|
pub fn[Token, A, B] XMLParser::repeat_with_sep(
self : XMLParser[Token, A],
sep : XMLParser[Token, B],
) -> XMLParser[Token, Array[A]] {
fn(tokens : Seq[Token], ctx : XMLParserContext) {
let sep_self = sep.and_then(self).omit_first()
match self.run(tokens, ctx) {
(None, err, ctx1) =>
match err {
Some(e) =>
if e.is_fatal() {
(None, err, ctx1)
} else {
(Some(([], tokens)), err, ctx1)
}
_ => (Some(([], tokens)), err, ctx1)
}
(Some((hd, tl)), err, ctx1) => {
let result = [hd]
let (input, ctx2) = for input = tl, ctx_loop = ctx1 {
match sep_self.run(input, ctx_loop) {
(Some((hd, tl)), err, ctx2) => {
result.push(hd)
continue tl, ctx2
}
(None, err, ctx2) => break (input, ctx2)
}
}
(Some((result, input)), err, ctx2)
}
}
}
}
///|
pub fn[Token, A] XMLParser::optional(
self : XMLParser[Token, A],
) -> XMLParser[Token, A?] {
self.map(fn(x) { Some(x) }).or_else(pconst(Option::None))
}
///|
pub fn[Token, A, B] XMLParser::omit_first(
self : XMLParser[Token, (A, B)],
) -> XMLParser[Token, B] {
self.map(fn(pair) { pair.1 })
}
///|
pub fn[Token, A, B] XMLParser::omit_second(
self : XMLParser[Token, (A, B)],
) -> XMLParser[Token, A] {
self.map(fn(pair) { pair.0 })
}
///|
pub fn[Token, A] XMLParser::from_ref(
self : Ref[XMLParser[Token, A]],
) -> XMLParser[Token, A] {
fn(tokens : Seq[Token], ctx : XMLParserContext) { self.val.run(tokens, ctx) }
}
///|
pub fn[Token, A] pconst(a : A) -> XMLParser[Token, A] {
fn(tokens : Seq[Token], ctx : XMLParserContext) {
(Some((a, tokens)), None, ctx)
}
}