fn parse_unsigned_integer(parser: &mut trivet::Parser) -> trivet::errors::ParseResult<u64> {
let result = parser.take_while(|ch| ch.is_ascii_digit());
match result.parse::<u64>() {
Ok(number) => Ok(number),
Err(err) => Err(trivet::errors::error(parser.loc(), err)),
}
}
fn parse_identifier(parser: &mut trivet::Parser) -> String {
let mut result = parser.take_while(|ch| ch.is_alphabetic());
result += parser.take_while(|ch| ch.is_alphanumeric()).as_str();
result
}
#[derive(Debug)]
enum Thing {
Number(trivet::Loc, u64),
Id(trivet::Loc, String),
}
fn parse_sequence_ws(parser: &mut trivet::Parser) -> trivet::errors::ParseResult<Vec<Thing>> {
let mut things = Vec::new();
let _ = parser.consume_ws();
while !parser.is_at_eof() {
match parser.peek() {
ch if ch.is_ascii_digit() => {
things.push(Thing::Number(parser.loc(), parse_unsigned_integer(parser)?));
}
ch if ch.is_alphabetic() => {
things.push(Thing::Id(parser.loc(), parse_identifier(parser)));
}
ch => {
return Err(trivet::errors::unexpected_text_error(
parser.loc(),
"number or identifier",
&ch.to_string(),
));
}
}
let _ = parser.consume_ws();
}
Ok(things)
}
fn main() {
let mut parser = trivet::parse_from_stdin();
match parse_sequence_ws(&mut parser) {
Err(err) => {
println!("{}", err);
}
Ok(seq) => {
for thing in seq {
match thing {
Thing::Number(loc, value) => {
println!("{}: number = {}", loc, value)
}
Thing::Id(loc, ident) => {
println!("{}: identifier = {}", loc, ident)
}
}
}
}
}
}