From e34f27a00fba003b7d24a10567bec5054c8ca99d Mon Sep 17 00:00:00 2001 From: Lucas Date: Mon, 24 Jun 2024 12:58:18 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=A7=20(parser):=20Work=20on=20earley?= =?UTF-8?q?=20parser?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit semver: chore --- src/abstract_syntax_tree/builder.rs | 92 +++++++---------------------- src/abstract_syntax_tree/mod.rs | 10 +++- src/concrete_syntax_tree/mod.rs | 19 +++++- src/main.rs | 10 ++-- 4 files changed, 52 insertions(+), 79 deletions(-) diff --git a/src/abstract_syntax_tree/builder.rs b/src/abstract_syntax_tree/builder.rs index c817da8..043f727 100644 --- a/src/abstract_syntax_tree/builder.rs +++ b/src/abstract_syntax_tree/builder.rs @@ -1,7 +1,7 @@ use crate::{ abstract_syntax_tree::Statement, concrete_syntax_tree::{grammar::NonTerminal, ConcreteSyntax}, - diagnostic::{Diagnostic, Error}, + diagnostic::{Diagnostic, Error, Severity}, }; use super::AstractSyntax; @@ -9,74 +9,24 @@ use super::AstractSyntax; pub fn build_ast<'a>( syntax: &'a ConcreteSyntax<'a>, ) -> Result, Vec>> { - let mut diagnostics = Vec::new(); - let mut ast = AstractSyntax::Statement(Statement::Empty); - - match syntax { - ConcreteSyntax::NonTerminal(NonTerminal::Start, children) => { - match children - .iter() - .map(|child| build_ast(child)) - .collect::, _>>() - { - Ok(_) => {} - Err(err) => { - diagnostics.extend(err); - } - } - - ast = AstractSyntax::Statement(Statement::Empty); - } - _ => { - let range = syntax.range(); - - diagnostics.push( - Diagnostic::error("Structure error").with_error(Error::primary( - range.file_id, - range.position, - range.length, - format!("Expected start, got {:?}", syntax), - )), - ); - } - } - - if !diagnostics.is_empty() { - Err(diagnostics) - } else { - Ok(ast) - } -} - -pub fn build_top_level_statement<'a>( - parse_tree: &'a ConcreteSyntax<'a>, -) -> Result, Vec>> { - match parse_tree { - ConcreteSyntax::NonTerminal(NonTerminal::RootItems, children) => { - let root_items = children - .iter() - .map(|child| build_ast(child)) - .collect::, _>>()?; - - Ok(AstractSyntax::Statement(Statement::Empty)) - } - _ => { - let range = parse_tree.range(); - - return Err(vec![Diagnostic::error("Structure error").with_error( - Error::primary( - range.file_id, - range.position, - range.length, - "Expected root items", - ), - )]); - } - } -} - -#[cfg(test)] -mod test { - #[test] - fn test() {} + println!("Parsing {}", syntax); + + // match syntax { + // ConcreteSyntax::NonTerminal(NonTerminal::EnumDeclaration, children) => { + // let identifier = children[1].clone(); + // let items = children[3].clone(); + // } + // _ => Err(vec![Diagnostic { + // severity: Severity::Error, + // title: "Failed to build AST".to_string(), + // errors: vec![Error::primary( + // syntax.range().file_id, + // syntax.range().position, + // syntax.range().length, + // "Failed to build AST", + // )], + // }]), + // } + + todo!() } diff --git a/src/abstract_syntax_tree/mod.rs b/src/abstract_syntax_tree/mod.rs index 7116699..9e97e94 100644 --- a/src/abstract_syntax_tree/mod.rs +++ b/src/abstract_syntax_tree/mod.rs @@ -4,20 +4,24 @@ use crate::diagnostic::Range; pub mod builder; +#[derive(Debug)] pub enum AstractSyntax<'a> { Statement(Statement<'a>), } + +#[derive(Debug)] pub enum Statement<'a> { - Empty, EnumDeclaration(Spanned<'a, EnumDeclaration<'a>>), } +#[derive(Debug)] pub struct EnumDeclaration<'a> { pub identifier: Spanned<'a, &'a str>, pub items: Vec>, } +#[derive(Debug)] pub struct Spanned<'a, T> { - pub value: T, - pub range: Range<'a>, + pub value: &'a T, + pub range: &'a Range<'a>, } diff --git a/src/concrete_syntax_tree/mod.rs b/src/concrete_syntax_tree/mod.rs index 24cb1a2..2bdfef4 100644 --- a/src/concrete_syntax_tree/mod.rs +++ b/src/concrete_syntax_tree/mod.rs @@ -4,7 +4,7 @@ use crate::{ diagnostic::{Diagnostic, Error, Range}, scanner::token::Token, }; -use std::collections::HashSet; +use std::{collections::HashSet, fmt::Display}; pub mod grammar; @@ -42,6 +42,22 @@ pub enum ConcreteSyntax<'a> { NonTerminal(NonTerminal, Vec>), } +impl<'a> Display for ConcreteSyntax<'a> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ConcreteSyntax::Terminal(token) => write!(f, "{}", token.token_type), + ConcreteSyntax::NonTerminal(non_terminal, children) => { + write!(f, "{}", non_terminal)?; + if !children.is_empty() { + // And (n) children + write!(f, " ({})", children.len())?; + } + Ok(()) + } + } + } +} + impl<'a> ConcreteSyntax<'a> { pub fn range(&'a self) -> Range<'a> { match self { @@ -286,3 +302,4 @@ impl<'a> EarleyParser<'a> { } } } +q \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 4280c73..99e0b4e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,7 +14,7 @@ fn main() -> Result<()> { files.insert( "main", " - enum colors: green blue red; + enum colors: green blue red ", ); @@ -33,7 +33,7 @@ fn main() -> Result<()> { let parser = concrete_syntax_tree::EarleyParser::default(); - let parse_tree = match parser.parse(tokens) { + let concrete_syntax = match parser.parse(tokens) { Ok(parse_tree) => parse_tree, Err(diagnostics) => { diagnostics @@ -43,9 +43,9 @@ fn main() -> Result<()> { } }; - println!("{:#?}", parse_tree); + println!("Concrete syntax:\n{:#?}", concrete_syntax); - let ast = match build_ast(&parse_tree) { + let ast = match build_ast(&concrete_syntax) { Ok(ast) => ast, Err(diagnostics) => { diagnostics @@ -55,5 +55,7 @@ fn main() -> Result<()> { } }; + println!("Abstract syntax:\n{:#?}", ast); + Ok(()) }