diff options
| author | littleblack111 <littleblack11111@gmail.com> | 2025-09-27 20:35:59 +0800 |
|---|---|---|
| committer | littleblack111 <littleblack11111@gmail.com> | 2025-09-27 20:35:59 +0800 |
| commit | 477b98d8d271dafdbf4b02137a9068c70637c466 (patch) | |
| tree | 8b51d1a4c05b3c22a226d3093acc6fbad0bf659b | |
| parent | b120e413d21a9d4d1961bb814dff88531a7a4855 (diff) | |
feat: ast
| -rw-r--r-- | src/ast.rs | 53 | ||||
| -rw-r--r-- | src/main.rs | 7 | ||||
| -rw-r--r-- | src/parser.rs | 6 |
3 files changed, 55 insertions, 11 deletions
@@ -1,17 +1,18 @@ -use crate::parser::{self, Expr, ExprT, Scope}; +use crate::parser::{Expr, ExprT, Metadata, Scope}; +#[derive(Clone, Debug)] pub enum DepthExpr<'a> { Decision { cond: Box<DepthExpr<'a>>, t: Scope, - else_branch: Option<Box<DepthExpr<'a>>>, + else_branch: Option<Box<Vec<DepthExpr<'a>>>>, }, IO(&'a str), Process(&'a str), } -fn parse(vec: Vec<Expr>) -> Vec<DepthExpr> { - let exprs = Vec::new(); +pub fn parse<'a, 'b>(vec: &'b Vec<Expr<'a>>) -> Vec<DepthExpr<'a>> { + let mut exprs: Vec<DepthExpr<'a>> = Vec::new(); let mut it = vec .iter() @@ -19,8 +20,50 @@ fn parse(vec: Vec<Expr>) -> Vec<DepthExpr> { while let Some(e) = it.next() { if let ExprT::Decision((cond, scope)) = e.expr { - let cond = parser::parse(cond); + let cond = DepthExpr::Process(cond); + for e in it.clone() { + if e.meta == Some(Metadata::EndScope) { + break; + } + } + + exprs.push(DepthExpr::Decision { + cond: Box::new(cond), + t: scope, + else_branch: Some(Box::new(parse(&entire_scopes( + it.clone() + .cloned(), + )))), + }); + } + } + + exprs +} + +fn entire_scopes<'a>(it: impl Iterator<Item = Expr<'a>>) -> Vec<Expr<'a>> { + let mut exprs: Vec<Expr<'a>> = Vec::new(); + let mut scope_count: u32 = 1; // assume we already entered the scope + + for i in it { + if scope_count == 0 { + break; + } + if let Some(meta) = i.meta { + match meta { + Metadata::StartScope => { + scope_count = scope_count + .checked_add(1) + .expect("Scopes nested too deep") + } + Metadata::EndScope => { + scope_count = scope_count + .checked_sub(1) + .expect("Closed not opened scope") + } + } } + exprs.push(i); } exprs diff --git a/src/main.rs b/src/main.rs index 726ed1c..5c638a7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,8 @@ -use java2flowchart::parser::parse; +use java2flowchart::ast::parse; +use java2flowchart::parser; fn main() { - let test = "if (a) {f}"; + let test = "if (a) {if (a) {a} else if {asd else if {}}}"; - println!("{:#?}", parse(test)); + println!("{:#?}", parse(&parser::parse(test))); } diff --git a/src/parser.rs b/src/parser.rs index 1475fce..87d2470 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -12,13 +12,13 @@ pub enum Scope { Loop(Loop), } -#[derive(Debug)] +#[derive(Debug, PartialEq, Clone, Copy)] pub enum Metadata { StartScope, EndScope, } -#[derive(Debug)] +#[derive(Debug, Clone, Copy)] pub enum ExprT<'a> { StartOrStop(bool), Decision((&'a str, Scope)), @@ -26,7 +26,7 @@ pub enum ExprT<'a> { Process(&'a str), } -#[derive(Debug)] +#[derive(Debug, Clone, Copy)] pub struct Expr<'a> { pub expr: ExprT<'a>, pub meta: Option<Metadata>, |
