qbe-reader

A parser for the QBE intermediate language in Rust

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

 1mod error;
 2mod parser;
 3pub mod types;
 4mod util;
 5
 6use nom::{
 7    branch::alt, combinator::map_res, multi::separated_list1, sequence::terminated, IResult,
 8};
 9
10use crate::error::Error;
11use std::convert;
12use std::fs::File;
13use std::io::Read;
14use std::path;
15
16#[derive(Debug)]
17pub enum Definition {
18    Type(types::TypeDef),
19    Data(types::DataDef),
20    Func(types::FuncDef),
21}
22
23fn parse_def(input: &str) -> IResult<&str, Definition> {
24    alt((
25        map_res(parser::typedef, |ty| -> Result<Definition, ()> {
26            Ok(Definition::Type(ty))
27        }),
28        map_res(parser::datadef, |data| -> Result<Definition, ()> {
29            Ok(Definition::Data(data))
30        }),
31        map_res(parser::funcdef, |func| -> Result<Definition, ()> {
32            Ok(Definition::Func(func))
33        }),
34    ))(input)
35}
36
37fn parse_defs(input: &str) -> IResult<&str, Vec<Definition>> {
38    terminated(
39        separated_list1(util::ws(util::newline0), parse_def),
40        util::newline0,
41    )(input)
42}
43
44////////////////////////////////////////////////////////////////////////
45
46pub fn parse_file<'a, P: convert::AsRef<path::Path>>(fp: P) -> Result<Vec<Definition>, Error> {
47    let mut file = File::open(fp)?;
48
49    // TODO: mmap(2) file instead of reading it into memory.
50    let mut buf = String::new();
51    file.read_to_string(&mut buf)?;
52
53    let (input, defs) = parse_defs(&buf)?;
54    if input != "" {
55        Err(Error::IncompleteParse)
56    } else {
57        Ok(defs)
58    }
59}