working on c37.118 forma
This commit is contained in:
parent
7883b42d13
commit
f86a6bf9f4
6 changed files with 53 additions and 74 deletions
9
.mise.toml
Normal file
9
.mise.toml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
[tools]
|
||||||
|
rust = "stable"
|
||||||
|
jj = "latest"
|
||||||
|
|
||||||
|
[tasks]
|
||||||
|
run = "cargo run"
|
||||||
|
test = "cargo test"
|
||||||
|
watch-run = "cargo watch -x run --why"
|
||||||
|
watch-test = "cargo watch -x test --why"
|
|
@ -1,11 +1,15 @@
|
||||||
#= Bigendian
|
#= BigEndian
|
||||||
|
|
||||||
CFGFRAME {
|
CFGFRAME {
|
||||||
0-1 bytes: field "SYNC" {
|
0-1 bytes: field "SYNC" {
|
||||||
0 byte: const "magic_number" u8 0xAA
|
0 byte: const "sync" u8 0xAA
|
||||||
1 byte: const "ver_number" u8 0x31
|
1 byte: field "type_ver" {}
|
||||||
}
|
}
|
||||||
3-4 bytes: field "TIME BASE" u16
|
2-3 bytes: field "framesize" u16
|
||||||
5-6 bytes: field "NUM_PMU" u16
|
4-5 bytes: field "idcode" u16
|
||||||
|
6-7 bytes: field "soc" u16
|
||||||
|
8-9 bytes: field "fracsec" u16
|
||||||
|
10-11 bytes: field "time base" u16
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::ir::{Atom, OwnedAtom};
|
use crate::ir::OwnedAtom;
|
||||||
pub(crate) mod parser;
|
pub(crate) mod parser;
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
#[derive(PartialEq, Debug)]
|
||||||
|
@ -53,4 +53,4 @@ pub(crate) enum Type {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// position of field relative to parent
|
/// position of field relative to parent
|
||||||
type Range = (usize, usize);
|
pub type Range = (usize, usize);
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use crate::ir::Atom;
|
||||||
|
use nom::character::complete::space0;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
|
||||||
use nom::IResult;
|
use nom::IResult;
|
||||||
|
@ -14,8 +16,6 @@ use nom::character::complete::digit1;
|
||||||
use nom::character::complete::hex_digit1;
|
use nom::character::complete::hex_digit1;
|
||||||
use nom::character::complete::line_ending;
|
use nom::character::complete::line_ending;
|
||||||
use nom::character::complete::multispace0;
|
use nom::character::complete::multispace0;
|
||||||
use nom::character::complete::newline;
|
|
||||||
use nom::character::complete::space0;
|
|
||||||
use nom::character::streaming::multispace1;
|
use nom::character::streaming::multispace1;
|
||||||
use nom::combinator::map;
|
use nom::combinator::map;
|
||||||
use nom::combinator::map_res;
|
use nom::combinator::map_res;
|
||||||
|
@ -31,8 +31,6 @@ use nom::sequence::pair;
|
||||||
use nom::sequence::preceded;
|
use nom::sequence::preceded;
|
||||||
use nom::sequence::terminated;
|
use nom::sequence::terminated;
|
||||||
|
|
||||||
use crate::ir::Atom;
|
|
||||||
|
|
||||||
use super::FieldRegion;
|
use super::FieldRegion;
|
||||||
use super::Module;
|
use super::Module;
|
||||||
use super::Options;
|
use super::Options;
|
||||||
|
@ -117,7 +115,6 @@ fn identifier_test() {
|
||||||
|
|
||||||
/// A combinator that parses primitive types.
|
/// A combinator that parses primitive types.
|
||||||
pub fn parse_type(input: &str) -> IResult<&str, Type> {
|
pub fn parse_type(input: &str) -> IResult<&str, Type> {
|
||||||
println!("type: {:?}", input);
|
|
||||||
alt((
|
alt((
|
||||||
(map(tag("bool"), |_| Type::Bool)),
|
(map(tag("bool"), |_| Type::Bool)),
|
||||||
(map(tag("u8"), |_| Type::U8)),
|
(map(tag("u8"), |_| Type::U8)),
|
||||||
|
@ -196,7 +193,6 @@ fn range_test() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_field_entry(input: &str) -> IResult<&str, (Range, FieldRegion)> {
|
pub fn parse_field_entry(input: &str) -> IResult<&str, (Range, FieldRegion)> {
|
||||||
println!("field_entry{:?}", input);
|
|
||||||
map(
|
map(
|
||||||
(
|
(
|
||||||
parse_range,
|
parse_range,
|
||||||
|
@ -229,15 +225,14 @@ pub fn parse_field_entry(input: &str) -> IResult<&str, (Range, FieldRegion)> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_region(input: &str) -> IResult<&str, Region> {
|
pub fn parse_region(input: &str) -> IResult<&str, Region> {
|
||||||
println!("Region: {:?}", input);
|
|
||||||
alt((
|
alt((
|
||||||
map(
|
map(
|
||||||
(
|
(
|
||||||
multispace0,
|
multispace0,
|
||||||
char('{'),
|
char('{'),
|
||||||
multispace1,
|
multispace0,
|
||||||
separated_list0(multispace1, parse_field_entry),
|
separated_list0(multispace1, parse_field_entry),
|
||||||
multispace1,
|
multispace0,
|
||||||
char('}'),
|
char('}'),
|
||||||
),
|
),
|
||||||
|(_, _, _, field_list, _, _)| Region::Fields(field_list),
|
|(_, _, _, field_list, _, _)| Region::Fields(field_list),
|
||||||
|
@ -386,7 +381,6 @@ fn parse_named_region(input: &str) -> IResult<&str, (String, Region)> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_module(input: &str) -> IResult<&str, Module> {
|
pub fn parse_module(input: &str) -> IResult<&str, Module> {
|
||||||
println!("{}", input);
|
|
||||||
map(
|
map(
|
||||||
(
|
(
|
||||||
parse_options,
|
parse_options,
|
||||||
|
@ -402,62 +396,22 @@ pub fn parse_module(input: &str) -> IResult<&str, Module> {
|
||||||
fn module_test() {
|
fn module_test() {
|
||||||
let module = "#= BigEndian\n\n\nCFGFRAME { 0-1 bytes: field \"SYNC\" u16 }";
|
let module = "#= BigEndian\n\n\nCFGFRAME { 0-1 bytes: field \"SYNC\" u16 }";
|
||||||
let (_, module) = parse_module(module).unwrap();
|
let (_, module) = parse_module(module).unwrap();
|
||||||
assert_eq!(module.opts, Options(vec!["BigEndian".to_owned()]));
|
assert_eq!(
|
||||||
assert_eq!(module.objs[0].0, "CFGFRAME");
|
module,
|
||||||
}
|
Module {
|
||||||
|
objs: vec![(
|
||||||
#[test]
|
"CFGFRAME".to_owned(),
|
||||||
fn c37118_test() {
|
Region::Fields(vec![(
|
||||||
let brin = include_str!("../../formats/c37118.brin");
|
(0, 15),
|
||||||
let (_, module) = parse_module(brin).unwrap();
|
FieldRegion::Subfield {
|
||||||
assert_eq!(module.opts, Options(vec!["Bigendian".to_owned()]));
|
name: "SYNC".to_owned(),
|
||||||
assert_eq!(module.objs[0].0, "CFGFRAME");
|
content: Region::Atom { ty: Type::U16 }
|
||||||
|
}
|
||||||
if let Region::Fields(fields) = &module.objs[0].1 {
|
)])
|
||||||
assert_eq!(fields[0].0, (0, 15));
|
)],
|
||||||
if let FieldRegion::Subfield { name, content } = &fields[0].1 {
|
opts: Options(vec!["BigEndian".to_owned()])
|
||||||
assert_eq!(name, "SYNC");
|
|
||||||
if let Region::Fields(subfields) = content {
|
|
||||||
assert_eq!(subfields[0].0, (0, 7));
|
|
||||||
if let FieldRegion::Const { name, value } = &subfields[0].1 {
|
|
||||||
assert_eq!(name, "magic_number");
|
|
||||||
assert_eq!(*value, OwnedAtom::U8(0xAA));
|
|
||||||
}
|
|
||||||
|
|
||||||
assert_eq!(subfields[1].0, (8, 15));
|
|
||||||
if let FieldRegion::Const { name, value } = &subfields[1].1 {
|
|
||||||
assert_eq!(name, "ver_number");
|
|
||||||
assert_eq!(*value, OwnedAtom::U8(0x31));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
);
|
||||||
assert_eq!(fields[1].0, (24, 39));
|
|
||||||
if let FieldRegion::Subfield { name, content } = &fields[1].1 {
|
|
||||||
assert_eq!(*name, "TIME BASE");
|
|
||||||
if let Region::Atom { ty } = content {
|
|
||||||
assert_eq!(*ty, Type::U16);
|
|
||||||
} else {
|
|
||||||
panic!("Incorrect content for TIME BASE");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
panic!("Incorrect field region for TIME BASE");
|
|
||||||
}
|
|
||||||
|
|
||||||
assert_eq!(fields[2].0, (40, 55));
|
|
||||||
if let FieldRegion::Subfield { name, content } = &fields[2].1 {
|
|
||||||
assert_eq!(*name, "NUM_PMU");
|
|
||||||
if let Region::Atom { ty } = content {
|
|
||||||
assert_eq!(*ty, Type::U16);
|
|
||||||
} else {
|
|
||||||
panic!("Incorrect content for NUM_PMU");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
panic!("Incorrect field region for NUM_PMU");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
panic!("Wrong region type");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -476,7 +430,7 @@ fn test_field_entry() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_region_good() {
|
fn test_region_god() {
|
||||||
let region = "{
|
let region = "{
|
||||||
3-4 byte: field \"time base\" u16
|
3-4 byte: field \"time base\" u16
|
||||||
5-6 byte: field \"magic number\" {
|
5-6 byte: field \"magic number\" {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
//use nanoid::nanoid;
|
//use nanoid::nanoid;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
|
use crate::grammar::Range;
|
||||||
|
|
||||||
/* Any format will be parsed into an intermediate, json-like object.
|
/* Any format will be parsed into an intermediate, json-like object.
|
||||||
Where possible, zero-copying should be done (???!);
|
Where possible, zero-copying should be done (???!);
|
||||||
|
|
||||||
|
@ -77,3 +79,9 @@ impl<'a> Atom<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct ParsedField<'a> {
|
||||||
|
span: Range,
|
||||||
|
name: FieldTag,
|
||||||
|
value: Atom<'a>,
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
|
use grammar::parser::parse_module;
|
||||||
|
|
||||||
mod grammar;
|
mod grammar;
|
||||||
mod ir;
|
mod ir;
|
||||||
|
mod parser;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("Hello, world!");
|
let m = include_str!("../formats/c37118.brin");
|
||||||
|
println!("{:?}", parse_module(m));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue