Just barely starting to diff the two parsed forms.

This commit is contained in:
Tom Alexander 2023-04-11 17:35:09 -04:00
parent 5305ae7627
commit 287cc8dea3
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
5 changed files with 54 additions and 2 deletions

25
src/compare/diff.rs Normal file
View File

@ -0,0 +1,25 @@
use super::sexp::Token;
use crate::parser::Document;
pub fn compare_document<'s>(
emacs: &'s Token<'s>,
rust: &'s Document<'s>,
) -> Result<(), Box<dyn std::error::Error>> {
compare_document_indented(0, emacs, rust)
}
fn compare_document_indented<'s>(
indentation: usize,
emacs: &'s Token<'s>,
rust: &'s Document<'s>,
) -> Result<(), Box<dyn std::error::Error>> {
let children = emacs.as_list()?;
let first_child = children.first().ok_or("Should have at least one child")?;
let first_child_text = first_child.as_atom()?;
if first_child_text != "org-data" {
return Err("Document should correspond to an org-data cell.".into());
}
// TODO: compare the children
Ok(())
}

View File

@ -1,5 +1,7 @@
mod diff;
mod error; mod error;
mod parse; mod parse;
mod sexp; mod sexp;
pub use diff::compare_document;
pub use parse::emacs_parse_org_document; pub use parse::emacs_parse_org_document;
pub use sexp::sexp; pub use sexp::sexp;

View File

@ -30,6 +30,22 @@ pub struct TextWithProperties<'s> {
properties: Vec<Token<'s>>, properties: Vec<Token<'s>>,
} }
impl<'s> Token<'s> {
pub fn as_list<'p>(&'p self) -> Result<&'p Vec<Token<'s>>, Box<dyn std::error::Error>> {
Ok(match self {
Token::List(children) => Ok(children),
_ => Err("wrong token type"),
}?)
}
pub fn as_atom<'p>(&'p self) -> Result<&'s str, Box<dyn std::error::Error>> {
Ok(match self {
Token::Atom(body) => Ok(*body),
_ => Err("wrong token type"),
}?)
}
}
#[tracing::instrument(ret, level = "debug")] #[tracing::instrument(ret, level = "debug")]
pub fn sexp<'s>(input: &'s str) -> Res<&'s str, Token<'s>> { pub fn sexp<'s>(input: &'s str) -> Res<&'s str, Token<'s>> {
let (remaining, _) = multispace0(input)?; let (remaining, _) = multispace0(input)?;

View File

@ -1,18 +1,26 @@
#![feature(round_char_boundary)] #![feature(round_char_boundary)]
#![feature(exit_status_error)] #![feature(exit_status_error)]
use crate::compare::compare_document;
use crate::init_tracing::init_telemetry; use crate::init_tracing::init_telemetry;
use crate::init_tracing::shutdown_telemetry; use crate::init_tracing::shutdown_telemetry;
use crate::parser::document;
use compare::emacs_parse_org_document; use compare::emacs_parse_org_document;
use compare::sexp; use compare::sexp;
mod compare; mod compare;
mod init_tracing; mod init_tracing;
mod parser;
fn main() -> Result<(), Box<dyn std::error::Error>> { fn main() -> Result<(), Box<dyn std::error::Error>> {
init_telemetry()?; init_telemetry()?;
let org_sexp = emacs_parse_org_document("./org_mode_samples/footnote_definition/simple.org")?; let org_path = "./org_mode_samples/footnote_definition/simple.org";
let org_contents = std::fs::read_to_string(org_path)?;
let org_sexp = emacs_parse_org_document(org_path)?;
println!("{}", org_sexp); println!("{}", org_sexp);
let parsed_sexp = sexp(org_sexp.as_str()).expect("Parse failure"); let (_remaining, parsed_sexp) = sexp(org_sexp.as_str()).expect("Sexp Parse failure");
println!("{:#?}", parsed_sexp); println!("{:#?}", parsed_sexp);
let (_remaining, rust_parsed) = document(org_contents.as_str()).expect("Org Parse failure");
println!("{:#?}", rust_parsed);
compare_document(&parsed_sexp, &rust_parsed)?;
shutdown_telemetry()?; shutdown_telemetry()?;
Ok(()) Ok(())
} }

View File

@ -15,4 +15,5 @@ mod plain_text;
mod source; mod source;
mod util; mod util;
pub use document::document; pub use document::document;
pub use document::Document;
type Context<'r, 's> = &'r parser_context::ContextTree<'r, 's>; type Context<'r, 's> = &'r parser_context::ContextTree<'r, 's>;