ldscript_parser/
script.rs1use commands::{command, Command};
2use memory::region;
3use memory::Region;
4use nom::branch::alt;
5use nom::bytes::complete::tag;
6use nom::combinator::map;
7use nom::multi::many1;
8use nom::sequence::tuple;
9use nom::IResult;
10use sections::section_command;
11use sections::SectionCommand;
12use statements::{statement, Statement};
13use whitespace::opt_space;
14
15#[derive(Debug, PartialEq)]
16pub enum RootItem {
17 Statement(Statement),
18 Command(Command),
19 Memory { regions: Vec<Region> },
20 Sections { list: Vec<SectionCommand> },
21}
22
23fn statement_item(input: &str) -> IResult<&str, RootItem> {
24 map(statement, |stmt| RootItem::Statement(stmt))(input)
25}
26
27fn command_item(input: &str) -> IResult<&str, RootItem> {
28 map(command, |cmd| RootItem::Command(cmd))(input)
29}
30
31fn memory_item(input: &str) -> IResult<&str, RootItem> {
32 let (input, _) = tuple((tag("MEMORY"), wsc!(tag("{"))))(input)?;
33 let (input, regions) = many1(wsc!(region))(input)?;
34 let (input, _) = tag("}")(input)?;
35 Ok((input, RootItem::Memory { regions: regions }))
36}
37
38fn sections_item(input: &str) -> IResult<&str, RootItem> {
39 let (input, _) = tuple((tag("SECTIONS"), wsc!(tag("{"))))(input)?;
40 let (input, sections) = many1(wsc!(section_command))(input)?;
41 let (input, _) = tag("}")(input)?;
42 Ok((input, RootItem::Sections { list: sections }))
43}
44
45fn root_item(input: &str) -> IResult<&str, RootItem> {
46 alt((statement_item, memory_item, sections_item, command_item))(input)
47}
48
49pub fn parse(input: &str) -> IResult<&str, Vec<RootItem>> {
50 alt((many1(wsc!(root_item)), map(opt_space, |_| vec![])))(input)
51}
52
53#[cfg(test)]
54mod tests {
55 use script::*;
56 use std::fs::{self, File};
57 use std::io::Read;
58
59 #[test]
60 fn test_empty() {
61 assert_done_vec!(parse(""), 0);
62 assert_done_vec!(parse(" "), 0);
63 assert_done_vec!(parse(" /* hello */ "), 0);
64 }
65
66 #[test]
67 fn test_parse() {
68 for entry in fs::read_dir("tests").unwrap() {
69 let path = entry.unwrap().path();
70 println!("testing: {:?}", path);
71 let mut file = File::open(path).unwrap();
72 let mut contents = String::new();
73 file.read_to_string(&mut contents).unwrap();
74 assert_done!(parse(&contents));
75 }
76 }
77}