qbe-reader

A parser for the QBE intermediate language in Rust

git clone https://git.8pit.net/qbe-reader.git

 1use nom::{
 2    bytes::complete::tag,
 3    character::complete::{char, one_of},
 4    combinator::{map_res, recognize},
 5    error::{FromExternalError, ParseError},
 6    multi::{many0, many1},
 7    sequence::delimited,
 8    IResult,
 9};
10
11fn newline(input: &str) -> IResult<&str, char> {
12    char('\n')(input)
13}
14pub fn newline0(input: &str) -> IResult<&str, ()> {
15    let (input, _) = many0(newline)(input)?;
16    Ok((input, ()))
17}
18pub fn newline1(input: &str) -> IResult<&str, ()> {
19    let (input, _) = many1(newline)(input)?;
20    Ok((input, ()))
21}
22
23pub fn bind<'a, F: 'a, T: Copy, O, E: ParseError<&'a str> + FromExternalError<&'a str, ()>>(
24    inner: F,
25    val: T,
26) -> impl FnMut(&'a str) -> IResult<&'a str, T, E>
27where
28    F: FnMut(&'a str) -> IResult<&'a str, O, E>,
29{
30    map_res(inner, move |_| -> Result<T, ()> { Ok(val) })
31}
32
33// Parse on of the given strings and return the given value.
34pub fn str<'a, T: Copy, E: ParseError<&'a str> + FromExternalError<&'a str, ()> + 'a>(
35    name: &'a str,
36    val: T,
37) -> impl FnMut(&'a str) -> IResult<&'a str, T, E> {
38    bind(tag(name), val)
39}
40
41pub fn digits(input: &str) -> IResult<&str, &str> {
42    recognize(many1(one_of("0123456789")))(input)
43}
44
45pub fn parse_i64(input: &str) -> IResult<&str, i64> {
46    map_res(digits, |input: &str| i64::from_str_radix(input, 10))(input)
47}
48
49// TODO: Use generics to refactor parse_u64 and parse_i64
50pub fn parse_u64(input: &str) -> IResult<&str, u64> {
51    map_res(digits, |input: &str| u64::from_str_radix(input, 10))(input)
52}
53
54pub fn ws<'a, F: 'a, O, E: ParseError<&'a str>>(
55    inner: F,
56) -> impl FnMut(&'a str) -> IResult<&'a str, O, E>
57where
58    F: Fn(&'a str) -> IResult<&'a str, O, E>,
59{
60    // See https://c9x.me/compile/doc/il-v1.1.html#Spacing
61    delimited(many0(one_of(" \t")), inner, many0(one_of(" \t")))
62}